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 // adfd2965cc104f3de6cccaed5095721d042c1251 committed on 2022-01-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.14"
94 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3273
95 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20220118
96 #define WUFFS_VERSION_STRING "0.3.0-beta.14+3273.20220118"
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 // Quite OK Image.
691 #define WUFFS_BASE__FOURCC__QOI 0x514F4920
692 
693 // Random Access Compression.
694 #define WUFFS_BASE__FOURCC__RAC 0x52414320
695 
696 // Raw.
697 #define WUFFS_BASE__FOURCC__RAW 0x52415720
698 
699 // Resource Interchange File Format.
700 #define WUFFS_BASE__FOURCC__RIFF 0x52494646
701 
702 // Riegeli Records.
703 #define WUFFS_BASE__FOURCC__RIGL 0x5249474C
704 
705 // Snappy.
706 #define WUFFS_BASE__FOURCC__SNPY 0x534E5059
707 
708 // Standard Red Green Blue (Rendering Intent).
709 #define WUFFS_BASE__FOURCC__SRGB 0x53524742
710 
711 // Scalable Vector Graphics.
712 #define WUFFS_BASE__FOURCC__SVG 0x53564720
713 
714 // Tape Archive.
715 #define WUFFS_BASE__FOURCC__TAR 0x54415220
716 
717 // Text.
718 #define WUFFS_BASE__FOURCC__TEXT 0x54455854
719 
720 // Truevision Advanced Raster Graphics Adapter.
721 #define WUFFS_BASE__FOURCC__TGA 0x54474120
722 
723 // Tagged Image File Format.
724 #define WUFFS_BASE__FOURCC__TIFF 0x54494646
725 
726 // Tom's Obvious Minimal Language.
727 #define WUFFS_BASE__FOURCC__TOML 0x544F4D4C
728 
729 // Waveform.
730 #define WUFFS_BASE__FOURCC__WAVE 0x57415645
731 
732 // Wireless Bitmap.
733 #define WUFFS_BASE__FOURCC__WBMP 0x57424D50
734 
735 // Web Picture.
736 #define WUFFS_BASE__FOURCC__WEBP 0x57454250
737 
738 // Web Open Font Format.
739 #define WUFFS_BASE__FOURCC__WOFF 0x574F4646
740 
741 // Extensible Markup Language.
742 #define WUFFS_BASE__FOURCC__XML 0x584D4C20
743 
744 // Extensible Metadata Platform.
745 #define WUFFS_BASE__FOURCC__XMP 0x584D5020
746 
747 // Xz.
748 #define WUFFS_BASE__FOURCC__XZ 0x585A2020
749 
750 // Zip.
751 #define WUFFS_BASE__FOURCC__ZIP 0x5A495020
752 
753 // Zlib.
754 #define WUFFS_BASE__FOURCC__ZLIB 0x5A4C4942
755 
756 // Zstandard.
757 #define WUFFS_BASE__FOURCC__ZSTD 0x5A535444
758 
759 // --------
760 
761 // Quirks.
762 
763 #define WUFFS_BASE__QUIRK_IGNORE_CHECKSUM 1
764 
765 // --------
766 
767 // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a
768 // second. See https://github.com/OculusVR/Flicks
769 typedef int64_t wuffs_base__flicks;
770 
771 #define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000)
772 #define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600)
773 
774 // ---------------- Numeric Types
775 
776 // The helpers below are functions, instead of macros, because their arguments
777 // can be an expression that we shouldn't evaluate more than once.
778 //
779 // They are static, so that linking multiple wuffs .o files won't complain about
780 // duplicate function definitions.
781 //
782 // They are explicitly marked inline, even if modern compilers don't use the
783 // inline attribute to guide optimizations such as inlining, to avoid the
784 // -Wunused-function warning, and we like to compile with -Wall -Werror.
785 
786 static inline int8_t  //
wuffs_base__i8__min(int8_t x,int8_t y)787 wuffs_base__i8__min(int8_t x, int8_t y) {
788   return x < y ? x : y;
789 }
790 
791 static inline int8_t  //
wuffs_base__i8__max(int8_t x,int8_t y)792 wuffs_base__i8__max(int8_t x, int8_t y) {
793   return x > y ? x : y;
794 }
795 
796 static inline int16_t  //
wuffs_base__i16__min(int16_t x,int16_t y)797 wuffs_base__i16__min(int16_t x, int16_t y) {
798   return x < y ? x : y;
799 }
800 
801 static inline int16_t  //
wuffs_base__i16__max(int16_t x,int16_t y)802 wuffs_base__i16__max(int16_t x, int16_t y) {
803   return x > y ? x : y;
804 }
805 
806 static inline int32_t  //
wuffs_base__i32__min(int32_t x,int32_t y)807 wuffs_base__i32__min(int32_t x, int32_t y) {
808   return x < y ? x : y;
809 }
810 
811 static inline int32_t  //
wuffs_base__i32__max(int32_t x,int32_t y)812 wuffs_base__i32__max(int32_t x, int32_t y) {
813   return x > y ? x : y;
814 }
815 
816 static inline int64_t  //
wuffs_base__i64__min(int64_t x,int64_t y)817 wuffs_base__i64__min(int64_t x, int64_t y) {
818   return x < y ? x : y;
819 }
820 
821 static inline int64_t  //
wuffs_base__i64__max(int64_t x,int64_t y)822 wuffs_base__i64__max(int64_t x, int64_t y) {
823   return x > y ? x : y;
824 }
825 
826 static inline uint8_t  //
wuffs_base__u8__min(uint8_t x,uint8_t y)827 wuffs_base__u8__min(uint8_t x, uint8_t y) {
828   return x < y ? x : y;
829 }
830 
831 static inline uint8_t  //
wuffs_base__u8__max(uint8_t x,uint8_t y)832 wuffs_base__u8__max(uint8_t x, uint8_t y) {
833   return x > y ? x : y;
834 }
835 
836 static inline uint16_t  //
wuffs_base__u16__min(uint16_t x,uint16_t y)837 wuffs_base__u16__min(uint16_t x, uint16_t y) {
838   return x < y ? x : y;
839 }
840 
841 static inline uint16_t  //
wuffs_base__u16__max(uint16_t x,uint16_t y)842 wuffs_base__u16__max(uint16_t x, uint16_t y) {
843   return x > y ? x : y;
844 }
845 
846 static inline uint32_t  //
wuffs_base__u32__min(uint32_t x,uint32_t y)847 wuffs_base__u32__min(uint32_t x, uint32_t y) {
848   return x < y ? x : y;
849 }
850 
851 static inline uint32_t  //
wuffs_base__u32__max(uint32_t x,uint32_t y)852 wuffs_base__u32__max(uint32_t x, uint32_t y) {
853   return x > y ? x : y;
854 }
855 
856 static inline uint64_t  //
wuffs_base__u64__min(uint64_t x,uint64_t y)857 wuffs_base__u64__min(uint64_t x, uint64_t y) {
858   return x < y ? x : y;
859 }
860 
861 static inline uint64_t  //
wuffs_base__u64__max(uint64_t x,uint64_t y)862 wuffs_base__u64__max(uint64_t x, uint64_t y) {
863   return x > y ? x : y;
864 }
865 
866 // --------
867 
868 static inline uint8_t  //
wuffs_base__u8__rotate_left(uint8_t x,uint32_t n)869 wuffs_base__u8__rotate_left(uint8_t x, uint32_t n) {
870   n &= 7;
871   return ((uint8_t)(x << n)) | ((uint8_t)(x >> (8 - n)));
872 }
873 
874 static inline uint8_t  //
wuffs_base__u8__rotate_right(uint8_t x,uint32_t n)875 wuffs_base__u8__rotate_right(uint8_t x, uint32_t n) {
876   n &= 7;
877   return ((uint8_t)(x >> n)) | ((uint8_t)(x << (8 - n)));
878 }
879 
880 static inline uint16_t  //
wuffs_base__u16__rotate_left(uint16_t x,uint32_t n)881 wuffs_base__u16__rotate_left(uint16_t x, uint32_t n) {
882   n &= 15;
883   return ((uint16_t)(x << n)) | ((uint16_t)(x >> (16 - n)));
884 }
885 
886 static inline uint16_t  //
wuffs_base__u16__rotate_right(uint16_t x,uint32_t n)887 wuffs_base__u16__rotate_right(uint16_t x, uint32_t n) {
888   n &= 15;
889   return ((uint16_t)(x >> n)) | ((uint16_t)(x << (16 - n)));
890 }
891 
892 static inline uint32_t  //
wuffs_base__u32__rotate_left(uint32_t x,uint32_t n)893 wuffs_base__u32__rotate_left(uint32_t x, uint32_t n) {
894   n &= 31;
895   return ((uint32_t)(x << n)) | ((uint32_t)(x >> (32 - n)));
896 }
897 
898 static inline uint32_t  //
wuffs_base__u32__rotate_right(uint32_t x,uint32_t n)899 wuffs_base__u32__rotate_right(uint32_t x, uint32_t n) {
900   n &= 31;
901   return ((uint32_t)(x >> n)) | ((uint32_t)(x << (32 - n)));
902 }
903 
904 static inline uint64_t  //
wuffs_base__u64__rotate_left(uint64_t x,uint32_t n)905 wuffs_base__u64__rotate_left(uint64_t x, uint32_t n) {
906   n &= 63;
907   return ((uint64_t)(x << n)) | ((uint64_t)(x >> (64 - n)));
908 }
909 
910 static inline uint64_t  //
wuffs_base__u64__rotate_right(uint64_t x,uint32_t n)911 wuffs_base__u64__rotate_right(uint64_t x, uint32_t n) {
912   n &= 63;
913   return ((uint64_t)(x >> n)) | ((uint64_t)(x << (64 - n)));
914 }
915 
916 // --------
917 
918 // Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms
919 // are per https://locklessinc.com/articles/sat_arithmetic/
920 //
921 // It is important that the underlying types are unsigned integers, as signed
922 // integer arithmetic overflow is undefined behavior in C.
923 
924 static inline uint8_t  //
wuffs_base__u8__sat_add(uint8_t x,uint8_t y)925 wuffs_base__u8__sat_add(uint8_t x, uint8_t y) {
926   uint8_t res = (uint8_t)(x + y);
927   res |= (uint8_t)(-(res < x));
928   return res;
929 }
930 
931 static inline uint8_t  //
wuffs_base__u8__sat_sub(uint8_t x,uint8_t y)932 wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) {
933   uint8_t res = (uint8_t)(x - y);
934   res &= (uint8_t)(-(res <= x));
935   return res;
936 }
937 
938 static inline uint16_t  //
wuffs_base__u16__sat_add(uint16_t x,uint16_t y)939 wuffs_base__u16__sat_add(uint16_t x, uint16_t y) {
940   uint16_t res = (uint16_t)(x + y);
941   res |= (uint16_t)(-(res < x));
942   return res;
943 }
944 
945 static inline uint16_t  //
wuffs_base__u16__sat_sub(uint16_t x,uint16_t y)946 wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) {
947   uint16_t res = (uint16_t)(x - y);
948   res &= (uint16_t)(-(res <= x));
949   return res;
950 }
951 
952 static inline uint32_t  //
wuffs_base__u32__sat_add(uint32_t x,uint32_t y)953 wuffs_base__u32__sat_add(uint32_t x, uint32_t y) {
954   uint32_t res = (uint32_t)(x + y);
955   res |= (uint32_t)(-(res < x));
956   return res;
957 }
958 
959 static inline uint32_t  //
wuffs_base__u32__sat_sub(uint32_t x,uint32_t y)960 wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) {
961   uint32_t res = (uint32_t)(x - y);
962   res &= (uint32_t)(-(res <= x));
963   return res;
964 }
965 
966 static inline uint64_t  //
wuffs_base__u64__sat_add(uint64_t x,uint64_t y)967 wuffs_base__u64__sat_add(uint64_t x, uint64_t y) {
968   uint64_t res = (uint64_t)(x + y);
969   res |= (uint64_t)(-(res < x));
970   return res;
971 }
972 
973 static inline uint64_t  //
wuffs_base__u64__sat_sub(uint64_t x,uint64_t y)974 wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) {
975   uint64_t res = (uint64_t)(x - y);
976   res &= (uint64_t)(-(res <= x));
977   return res;
978 }
979 
980 // --------
981 
982 typedef struct wuffs_base__multiply_u64__output__struct {
983   uint64_t lo;
984   uint64_t hi;
985 } wuffs_base__multiply_u64__output;
986 
987 // wuffs_base__multiply_u64 returns x*y as a 128-bit value.
988 //
989 // The maximum inclusive output hi_lo is 0xFFFFFFFFFFFFFFFE_0000000000000001.
990 static inline wuffs_base__multiply_u64__output  //
wuffs_base__multiply_u64(uint64_t x,uint64_t y)991 wuffs_base__multiply_u64(uint64_t x, uint64_t y) {
992 #if defined(__SIZEOF_INT128__)
993   __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y);
994   wuffs_base__multiply_u64__output o;
995   o.lo = ((uint64_t)(z));
996   o.hi = ((uint64_t)(z >> 64));
997   return o;
998 #else
999   // TODO: consider using the _mul128 intrinsic if defined(_MSC_VER).
1000   uint64_t x0 = x & 0xFFFFFFFF;
1001   uint64_t x1 = x >> 32;
1002   uint64_t y0 = y & 0xFFFFFFFF;
1003   uint64_t y1 = y >> 32;
1004   uint64_t w0 = x0 * y0;
1005   uint64_t t = (x1 * y0) + (w0 >> 32);
1006   uint64_t w1 = t & 0xFFFFFFFF;
1007   uint64_t w2 = t >> 32;
1008   w1 += x0 * y1;
1009   wuffs_base__multiply_u64__output o;
1010   o.lo = x * y;
1011   o.hi = (x1 * y1) + w2 + (w1 >> 32);
1012   return o;
1013 #endif
1014 }
1015 
1016 // --------
1017 
1018 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
1019 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
1020 #if (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1021 
1022 static inline uint32_t  //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1023 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1024   return u ? ((uint32_t)(__builtin_clzl(u))) : 64u;
1025 }
1026 
1027 #else
1028 // TODO: consider using the _BitScanReverse intrinsic if defined(_MSC_VER).
1029 
1030 static inline uint32_t  //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1031 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1032   if (u == 0) {
1033     return 64;
1034   }
1035 
1036   uint32_t n = 0;
1037   if ((u >> 32) == 0) {
1038     n |= 32;
1039     u <<= 32;
1040   }
1041   if ((u >> 48) == 0) {
1042     n |= 16;
1043     u <<= 16;
1044   }
1045   if ((u >> 56) == 0) {
1046     n |= 8;
1047     u <<= 8;
1048   }
1049   if ((u >> 60) == 0) {
1050     n |= 4;
1051     u <<= 4;
1052   }
1053   if ((u >> 62) == 0) {
1054     n |= 2;
1055     u <<= 2;
1056   }
1057   if ((u >> 63) == 0) {
1058     n |= 1;
1059     u <<= 1;
1060   }
1061   return n;
1062 }
1063 
1064 #endif  // (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1065 
1066 // --------
1067 
1068 #define wuffs_base__peek_u8be__no_bounds_check \
1069   wuffs_base__peek_u8__no_bounds_check
1070 #define wuffs_base__peek_u8le__no_bounds_check \
1071   wuffs_base__peek_u8__no_bounds_check
1072 
1073 static inline uint8_t  //
wuffs_base__peek_u8__no_bounds_check(const uint8_t * p)1074 wuffs_base__peek_u8__no_bounds_check(const uint8_t* p) {
1075   return p[0];
1076 }
1077 
1078 static inline uint16_t  //
wuffs_base__peek_u16be__no_bounds_check(const uint8_t * p)1079 wuffs_base__peek_u16be__no_bounds_check(const uint8_t* p) {
1080   return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
1081 }
1082 
1083 static inline uint16_t  //
wuffs_base__peek_u16le__no_bounds_check(const uint8_t * p)1084 wuffs_base__peek_u16le__no_bounds_check(const uint8_t* p) {
1085   return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
1086 }
1087 
1088 static inline uint32_t  //
wuffs_base__peek_u24be__no_bounds_check(const uint8_t * p)1089 wuffs_base__peek_u24be__no_bounds_check(const uint8_t* p) {
1090   return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
1091          ((uint32_t)(p[2]) << 0);
1092 }
1093 
1094 static inline uint32_t  //
wuffs_base__peek_u24le__no_bounds_check(const uint8_t * p)1095 wuffs_base__peek_u24le__no_bounds_check(const uint8_t* p) {
1096   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1097          ((uint32_t)(p[2]) << 16);
1098 }
1099 
1100 static inline uint32_t  //
wuffs_base__peek_u32be__no_bounds_check(const uint8_t * p)1101 wuffs_base__peek_u32be__no_bounds_check(const uint8_t* p) {
1102   return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
1103          ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
1104 }
1105 
1106 static inline uint32_t  //
wuffs_base__peek_u32le__no_bounds_check(const uint8_t * p)1107 wuffs_base__peek_u32le__no_bounds_check(const uint8_t* p) {
1108   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1109          ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
1110 }
1111 
1112 static inline uint64_t  //
wuffs_base__peek_u40be__no_bounds_check(const uint8_t * p)1113 wuffs_base__peek_u40be__no_bounds_check(const uint8_t* p) {
1114   return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
1115          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
1116          ((uint64_t)(p[4]) << 0);
1117 }
1118 
1119 static inline uint64_t  //
wuffs_base__peek_u40le__no_bounds_check(const uint8_t * p)1120 wuffs_base__peek_u40le__no_bounds_check(const uint8_t* p) {
1121   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1122          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1123          ((uint64_t)(p[4]) << 32);
1124 }
1125 
1126 static inline uint64_t  //
wuffs_base__peek_u48be__no_bounds_check(const uint8_t * p)1127 wuffs_base__peek_u48be__no_bounds_check(const uint8_t* p) {
1128   return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
1129          ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
1130          ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
1131 }
1132 
1133 static inline uint64_t  //
wuffs_base__peek_u48le__no_bounds_check(const uint8_t * p)1134 wuffs_base__peek_u48le__no_bounds_check(const uint8_t* p) {
1135   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1136          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1137          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
1138 }
1139 
1140 static inline uint64_t  //
wuffs_base__peek_u56be__no_bounds_check(const uint8_t * p)1141 wuffs_base__peek_u56be__no_bounds_check(const uint8_t* p) {
1142   return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
1143          ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
1144          ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
1145          ((uint64_t)(p[6]) << 0);
1146 }
1147 
1148 static inline uint64_t  //
wuffs_base__peek_u56le__no_bounds_check(const uint8_t * p)1149 wuffs_base__peek_u56le__no_bounds_check(const uint8_t* p) {
1150   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1151          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1152          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1153          ((uint64_t)(p[6]) << 48);
1154 }
1155 
1156 static inline uint64_t  //
wuffs_base__peek_u64be__no_bounds_check(const uint8_t * p)1157 wuffs_base__peek_u64be__no_bounds_check(const uint8_t* p) {
1158   return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
1159          ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
1160          ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
1161          ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
1162 }
1163 
1164 static inline uint64_t  //
wuffs_base__peek_u64le__no_bounds_check(const uint8_t * p)1165 wuffs_base__peek_u64le__no_bounds_check(const uint8_t* p) {
1166   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1167          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1168          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1169          ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
1170 }
1171 
1172 // --------
1173 
1174 #define wuffs_base__poke_u8be__no_bounds_check \
1175   wuffs_base__poke_u8__no_bounds_check
1176 #define wuffs_base__poke_u8le__no_bounds_check \
1177   wuffs_base__poke_u8__no_bounds_check
1178 
1179 static inline void  //
wuffs_base__poke_u8__no_bounds_check(uint8_t * p,uint8_t x)1180 wuffs_base__poke_u8__no_bounds_check(uint8_t* p, uint8_t x) {
1181   p[0] = x;
1182 }
1183 
1184 static inline void  //
wuffs_base__poke_u16be__no_bounds_check(uint8_t * p,uint16_t x)1185 wuffs_base__poke_u16be__no_bounds_check(uint8_t* p, uint16_t x) {
1186   p[0] = (uint8_t)(x >> 8);
1187   p[1] = (uint8_t)(x >> 0);
1188 }
1189 
1190 static inline void  //
wuffs_base__poke_u16le__no_bounds_check(uint8_t * p,uint16_t x)1191 wuffs_base__poke_u16le__no_bounds_check(uint8_t* p, uint16_t x) {
1192 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1193   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1194   // defines "__GNUC__".
1195   memcpy(p, &x, 2);
1196 #else
1197   p[0] = (uint8_t)(x >> 0);
1198   p[1] = (uint8_t)(x >> 8);
1199 #endif
1200 }
1201 
1202 static inline void  //
wuffs_base__poke_u24be__no_bounds_check(uint8_t * p,uint32_t x)1203 wuffs_base__poke_u24be__no_bounds_check(uint8_t* p, uint32_t x) {
1204   p[0] = (uint8_t)(x >> 16);
1205   p[1] = (uint8_t)(x >> 8);
1206   p[2] = (uint8_t)(x >> 0);
1207 }
1208 
1209 static inline void  //
wuffs_base__poke_u24le__no_bounds_check(uint8_t * p,uint32_t x)1210 wuffs_base__poke_u24le__no_bounds_check(uint8_t* p, uint32_t x) {
1211   p[0] = (uint8_t)(x >> 0);
1212   p[1] = (uint8_t)(x >> 8);
1213   p[2] = (uint8_t)(x >> 16);
1214 }
1215 
1216 static inline void  //
wuffs_base__poke_u32be__no_bounds_check(uint8_t * p,uint32_t x)1217 wuffs_base__poke_u32be__no_bounds_check(uint8_t* p, uint32_t x) {
1218   p[0] = (uint8_t)(x >> 24);
1219   p[1] = (uint8_t)(x >> 16);
1220   p[2] = (uint8_t)(x >> 8);
1221   p[3] = (uint8_t)(x >> 0);
1222 }
1223 
1224 static inline void  //
wuffs_base__poke_u32le__no_bounds_check(uint8_t * p,uint32_t x)1225 wuffs_base__poke_u32le__no_bounds_check(uint8_t* p, uint32_t x) {
1226 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1227   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1228   // defines "__GNUC__".
1229   memcpy(p, &x, 4);
1230 #else
1231   p[0] = (uint8_t)(x >> 0);
1232   p[1] = (uint8_t)(x >> 8);
1233   p[2] = (uint8_t)(x >> 16);
1234   p[3] = (uint8_t)(x >> 24);
1235 #endif
1236 }
1237 
1238 static inline void  //
wuffs_base__poke_u40be__no_bounds_check(uint8_t * p,uint64_t x)1239 wuffs_base__poke_u40be__no_bounds_check(uint8_t* p, uint64_t x) {
1240   p[0] = (uint8_t)(x >> 32);
1241   p[1] = (uint8_t)(x >> 24);
1242   p[2] = (uint8_t)(x >> 16);
1243   p[3] = (uint8_t)(x >> 8);
1244   p[4] = (uint8_t)(x >> 0);
1245 }
1246 
1247 static inline void  //
wuffs_base__poke_u40le__no_bounds_check(uint8_t * p,uint64_t x)1248 wuffs_base__poke_u40le__no_bounds_check(uint8_t* p, uint64_t x) {
1249   p[0] = (uint8_t)(x >> 0);
1250   p[1] = (uint8_t)(x >> 8);
1251   p[2] = (uint8_t)(x >> 16);
1252   p[3] = (uint8_t)(x >> 24);
1253   p[4] = (uint8_t)(x >> 32);
1254 }
1255 
1256 static inline void  //
wuffs_base__poke_u48be__no_bounds_check(uint8_t * p,uint64_t x)1257 wuffs_base__poke_u48be__no_bounds_check(uint8_t* p, uint64_t x) {
1258   p[0] = (uint8_t)(x >> 40);
1259   p[1] = (uint8_t)(x >> 32);
1260   p[2] = (uint8_t)(x >> 24);
1261   p[3] = (uint8_t)(x >> 16);
1262   p[4] = (uint8_t)(x >> 8);
1263   p[5] = (uint8_t)(x >> 0);
1264 }
1265 
1266 static inline void  //
wuffs_base__poke_u48le__no_bounds_check(uint8_t * p,uint64_t x)1267 wuffs_base__poke_u48le__no_bounds_check(uint8_t* p, uint64_t x) {
1268   p[0] = (uint8_t)(x >> 0);
1269   p[1] = (uint8_t)(x >> 8);
1270   p[2] = (uint8_t)(x >> 16);
1271   p[3] = (uint8_t)(x >> 24);
1272   p[4] = (uint8_t)(x >> 32);
1273   p[5] = (uint8_t)(x >> 40);
1274 }
1275 
1276 static inline void  //
wuffs_base__poke_u56be__no_bounds_check(uint8_t * p,uint64_t x)1277 wuffs_base__poke_u56be__no_bounds_check(uint8_t* p, uint64_t x) {
1278   p[0] = (uint8_t)(x >> 48);
1279   p[1] = (uint8_t)(x >> 40);
1280   p[2] = (uint8_t)(x >> 32);
1281   p[3] = (uint8_t)(x >> 24);
1282   p[4] = (uint8_t)(x >> 16);
1283   p[5] = (uint8_t)(x >> 8);
1284   p[6] = (uint8_t)(x >> 0);
1285 }
1286 
1287 static inline void  //
wuffs_base__poke_u56le__no_bounds_check(uint8_t * p,uint64_t x)1288 wuffs_base__poke_u56le__no_bounds_check(uint8_t* p, uint64_t x) {
1289   p[0] = (uint8_t)(x >> 0);
1290   p[1] = (uint8_t)(x >> 8);
1291   p[2] = (uint8_t)(x >> 16);
1292   p[3] = (uint8_t)(x >> 24);
1293   p[4] = (uint8_t)(x >> 32);
1294   p[5] = (uint8_t)(x >> 40);
1295   p[6] = (uint8_t)(x >> 48);
1296 }
1297 
1298 static inline void  //
wuffs_base__poke_u64be__no_bounds_check(uint8_t * p,uint64_t x)1299 wuffs_base__poke_u64be__no_bounds_check(uint8_t* p, uint64_t x) {
1300   p[0] = (uint8_t)(x >> 56);
1301   p[1] = (uint8_t)(x >> 48);
1302   p[2] = (uint8_t)(x >> 40);
1303   p[3] = (uint8_t)(x >> 32);
1304   p[4] = (uint8_t)(x >> 24);
1305   p[5] = (uint8_t)(x >> 16);
1306   p[6] = (uint8_t)(x >> 8);
1307   p[7] = (uint8_t)(x >> 0);
1308 }
1309 
1310 static inline void  //
wuffs_base__poke_u64le__no_bounds_check(uint8_t * p,uint64_t x)1311 wuffs_base__poke_u64le__no_bounds_check(uint8_t* p, uint64_t x) {
1312 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1313   // This seems to perform better on gcc 10 (but not clang 9). Clang also
1314   // defines "__GNUC__".
1315   memcpy(p, &x, 8);
1316 #else
1317   p[0] = (uint8_t)(x >> 0);
1318   p[1] = (uint8_t)(x >> 8);
1319   p[2] = (uint8_t)(x >> 16);
1320   p[3] = (uint8_t)(x >> 24);
1321   p[4] = (uint8_t)(x >> 32);
1322   p[5] = (uint8_t)(x >> 40);
1323   p[6] = (uint8_t)(x >> 48);
1324   p[7] = (uint8_t)(x >> 56);
1325 #endif
1326 }
1327 
1328 // --------
1329 
1330 // Load and Store functions are deprecated. Use Peek and Poke instead.
1331 
1332 #define wuffs_base__load_u8__no_bounds_check \
1333   wuffs_base__peek_u8__no_bounds_check
1334 #define wuffs_base__load_u16be__no_bounds_check \
1335   wuffs_base__peek_u16be__no_bounds_check
1336 #define wuffs_base__load_u16le__no_bounds_check \
1337   wuffs_base__peek_u16le__no_bounds_check
1338 #define wuffs_base__load_u24be__no_bounds_check \
1339   wuffs_base__peek_u24be__no_bounds_check
1340 #define wuffs_base__load_u24le__no_bounds_check \
1341   wuffs_base__peek_u24le__no_bounds_check
1342 #define wuffs_base__load_u32be__no_bounds_check \
1343   wuffs_base__peek_u32be__no_bounds_check
1344 #define wuffs_base__load_u32le__no_bounds_check \
1345   wuffs_base__peek_u32le__no_bounds_check
1346 #define wuffs_base__load_u40be__no_bounds_check \
1347   wuffs_base__peek_u40be__no_bounds_check
1348 #define wuffs_base__load_u40le__no_bounds_check \
1349   wuffs_base__peek_u40le__no_bounds_check
1350 #define wuffs_base__load_u48be__no_bounds_check \
1351   wuffs_base__peek_u48be__no_bounds_check
1352 #define wuffs_base__load_u48le__no_bounds_check \
1353   wuffs_base__peek_u48le__no_bounds_check
1354 #define wuffs_base__load_u56be__no_bounds_check \
1355   wuffs_base__peek_u56be__no_bounds_check
1356 #define wuffs_base__load_u56le__no_bounds_check \
1357   wuffs_base__peek_u56le__no_bounds_check
1358 #define wuffs_base__load_u64be__no_bounds_check \
1359   wuffs_base__peek_u64be__no_bounds_check
1360 #define wuffs_base__load_u64le__no_bounds_check \
1361   wuffs_base__peek_u64le__no_bounds_check
1362 
1363 #define wuffs_base__store_u8__no_bounds_check \
1364   wuffs_base__poke_u8__no_bounds_check
1365 #define wuffs_base__store_u16be__no_bounds_check \
1366   wuffs_base__poke_u16be__no_bounds_check
1367 #define wuffs_base__store_u16le__no_bounds_check \
1368   wuffs_base__poke_u16le__no_bounds_check
1369 #define wuffs_base__store_u24be__no_bounds_check \
1370   wuffs_base__poke_u24be__no_bounds_check
1371 #define wuffs_base__store_u24le__no_bounds_check \
1372   wuffs_base__poke_u24le__no_bounds_check
1373 #define wuffs_base__store_u32be__no_bounds_check \
1374   wuffs_base__poke_u32be__no_bounds_check
1375 #define wuffs_base__store_u32le__no_bounds_check \
1376   wuffs_base__poke_u32le__no_bounds_check
1377 #define wuffs_base__store_u40be__no_bounds_check \
1378   wuffs_base__poke_u40be__no_bounds_check
1379 #define wuffs_base__store_u40le__no_bounds_check \
1380   wuffs_base__poke_u40le__no_bounds_check
1381 #define wuffs_base__store_u48be__no_bounds_check \
1382   wuffs_base__poke_u48be__no_bounds_check
1383 #define wuffs_base__store_u48le__no_bounds_check \
1384   wuffs_base__poke_u48le__no_bounds_check
1385 #define wuffs_base__store_u56be__no_bounds_check \
1386   wuffs_base__poke_u56be__no_bounds_check
1387 #define wuffs_base__store_u56le__no_bounds_check \
1388   wuffs_base__poke_u56le__no_bounds_check
1389 #define wuffs_base__store_u64be__no_bounds_check \
1390   wuffs_base__poke_u64be__no_bounds_check
1391 #define wuffs_base__store_u64le__no_bounds_check \
1392   wuffs_base__poke_u64le__no_bounds_check
1393 
1394 // ---------------- Slices and Tables
1395 
1396 // WUFFS_BASE__SLICE is a 1-dimensional buffer.
1397 //
1398 // len measures a number of elements, not necessarily a size in bytes.
1399 //
1400 // A value with all fields NULL or zero is a valid, empty slice.
1401 #define WUFFS_BASE__SLICE(T) \
1402   struct {                   \
1403     T* ptr;                  \
1404     size_t len;              \
1405   }
1406 
1407 // WUFFS_BASE__TABLE is a 2-dimensional buffer.
1408 //
1409 // width, height and stride measure a number of elements, not necessarily a
1410 // size in bytes.
1411 //
1412 // A value with all fields NULL or zero is a valid, empty table.
1413 #define WUFFS_BASE__TABLE(T) \
1414   struct {                   \
1415     T* ptr;                  \
1416     size_t width;            \
1417     size_t height;           \
1418     size_t stride;           \
1419   }
1420 
1421 typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;
1422 typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;
1423 typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;
1424 typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;
1425 
1426 typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8;
1427 typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;
1428 typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;
1429 typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;
1430 
1431 static inline wuffs_base__slice_u8  //
wuffs_base__make_slice_u8(uint8_t * ptr,size_t len)1432 wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {
1433   wuffs_base__slice_u8 ret;
1434   ret.ptr = ptr;
1435   ret.len = len;
1436   return ret;
1437 }
1438 
1439 static inline wuffs_base__slice_u16  //
wuffs_base__make_slice_u16(uint16_t * ptr,size_t len)1440 wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {
1441   wuffs_base__slice_u16 ret;
1442   ret.ptr = ptr;
1443   ret.len = len;
1444   return ret;
1445 }
1446 
1447 static inline wuffs_base__slice_u32  //
wuffs_base__make_slice_u32(uint32_t * ptr,size_t len)1448 wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {
1449   wuffs_base__slice_u32 ret;
1450   ret.ptr = ptr;
1451   ret.len = len;
1452   return ret;
1453 }
1454 
1455 static inline wuffs_base__slice_u64  //
wuffs_base__make_slice_u64(uint64_t * ptr,size_t len)1456 wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {
1457   wuffs_base__slice_u64 ret;
1458   ret.ptr = ptr;
1459   ret.len = len;
1460   return ret;
1461 }
1462 
1463 static inline wuffs_base__slice_u8  //
wuffs_base__empty_slice_u8()1464 wuffs_base__empty_slice_u8() {
1465   wuffs_base__slice_u8 ret;
1466   ret.ptr = NULL;
1467   ret.len = 0;
1468   return ret;
1469 }
1470 
1471 static inline wuffs_base__slice_u16  //
wuffs_base__empty_slice_u16()1472 wuffs_base__empty_slice_u16() {
1473   wuffs_base__slice_u16 ret;
1474   ret.ptr = NULL;
1475   ret.len = 0;
1476   return ret;
1477 }
1478 
1479 static inline wuffs_base__slice_u32  //
wuffs_base__empty_slice_u32()1480 wuffs_base__empty_slice_u32() {
1481   wuffs_base__slice_u32 ret;
1482   ret.ptr = NULL;
1483   ret.len = 0;
1484   return ret;
1485 }
1486 
1487 static inline wuffs_base__slice_u64  //
wuffs_base__empty_slice_u64()1488 wuffs_base__empty_slice_u64() {
1489   wuffs_base__slice_u64 ret;
1490   ret.ptr = NULL;
1491   ret.len = 0;
1492   return ret;
1493 }
1494 
1495 static inline wuffs_base__table_u8  //
wuffs_base__make_table_u8(uint8_t * ptr,size_t width,size_t height,size_t stride)1496 wuffs_base__make_table_u8(uint8_t* ptr,
1497                           size_t width,
1498                           size_t height,
1499                           size_t stride) {
1500   wuffs_base__table_u8 ret;
1501   ret.ptr = ptr;
1502   ret.width = width;
1503   ret.height = height;
1504   ret.stride = stride;
1505   return ret;
1506 }
1507 
1508 static inline wuffs_base__table_u16  //
wuffs_base__make_table_u16(uint16_t * ptr,size_t width,size_t height,size_t stride)1509 wuffs_base__make_table_u16(uint16_t* ptr,
1510                            size_t width,
1511                            size_t height,
1512                            size_t stride) {
1513   wuffs_base__table_u16 ret;
1514   ret.ptr = ptr;
1515   ret.width = width;
1516   ret.height = height;
1517   ret.stride = stride;
1518   return ret;
1519 }
1520 
1521 static inline wuffs_base__table_u32  //
wuffs_base__make_table_u32(uint32_t * ptr,size_t width,size_t height,size_t stride)1522 wuffs_base__make_table_u32(uint32_t* ptr,
1523                            size_t width,
1524                            size_t height,
1525                            size_t stride) {
1526   wuffs_base__table_u32 ret;
1527   ret.ptr = ptr;
1528   ret.width = width;
1529   ret.height = height;
1530   ret.stride = stride;
1531   return ret;
1532 }
1533 
1534 static inline wuffs_base__table_u64  //
wuffs_base__make_table_u64(uint64_t * ptr,size_t width,size_t height,size_t stride)1535 wuffs_base__make_table_u64(uint64_t* ptr,
1536                            size_t width,
1537                            size_t height,
1538                            size_t stride) {
1539   wuffs_base__table_u64 ret;
1540   ret.ptr = ptr;
1541   ret.width = width;
1542   ret.height = height;
1543   ret.stride = stride;
1544   return ret;
1545 }
1546 
1547 static inline wuffs_base__table_u8  //
wuffs_base__empty_table_u8()1548 wuffs_base__empty_table_u8() {
1549   wuffs_base__table_u8 ret;
1550   ret.ptr = NULL;
1551   ret.width = 0;
1552   ret.height = 0;
1553   ret.stride = 0;
1554   return ret;
1555 }
1556 
1557 static inline wuffs_base__table_u16  //
wuffs_base__empty_table_u16()1558 wuffs_base__empty_table_u16() {
1559   wuffs_base__table_u16 ret;
1560   ret.ptr = NULL;
1561   ret.width = 0;
1562   ret.height = 0;
1563   ret.stride = 0;
1564   return ret;
1565 }
1566 
1567 static inline wuffs_base__table_u32  //
wuffs_base__empty_table_u32()1568 wuffs_base__empty_table_u32() {
1569   wuffs_base__table_u32 ret;
1570   ret.ptr = NULL;
1571   ret.width = 0;
1572   ret.height = 0;
1573   ret.stride = 0;
1574   return ret;
1575 }
1576 
1577 static inline wuffs_base__table_u64  //
wuffs_base__empty_table_u64()1578 wuffs_base__empty_table_u64() {
1579   wuffs_base__table_u64 ret;
1580   ret.ptr = NULL;
1581   ret.width = 0;
1582   ret.height = 0;
1583   ret.stride = 0;
1584   return ret;
1585 }
1586 
1587 static inline bool  //
wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s,wuffs_base__slice_u8 t)1588 wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {
1589   return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||
1590          ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));
1591 }
1592 
1593 // wuffs_base__slice_u8__subslice_i returns s[i:].
1594 //
1595 // It returns an empty slice if i is out of bounds.
1596 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s,uint64_t i)1597 wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {
1598   if ((i <= SIZE_MAX) && (i <= s.len)) {
1599     return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));
1600   }
1601   return wuffs_base__make_slice_u8(NULL, 0);
1602 }
1603 
1604 // wuffs_base__slice_u8__subslice_j returns s[:j].
1605 //
1606 // It returns an empty slice if j is out of bounds.
1607 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s,uint64_t j)1608 wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {
1609   if ((j <= SIZE_MAX) && (j <= s.len)) {
1610     return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));
1611   }
1612   return wuffs_base__make_slice_u8(NULL, 0);
1613 }
1614 
1615 // wuffs_base__slice_u8__subslice_ij returns s[i:j].
1616 //
1617 // It returns an empty slice if i or j is out of bounds.
1618 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,uint64_t i,uint64_t j)1619 wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,
1620                                   uint64_t i,
1621                                   uint64_t j) {
1622   if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {
1623     return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));
1624   }
1625   return wuffs_base__make_slice_u8(NULL, 0);
1626 }
1627 
1628 // wuffs_base__table_u8__subtable_ij returns t[ix:jx, iy:jy].
1629 //
1630 // It returns an empty table if i or j is out of bounds.
1631 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)1632 wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,
1633                                   uint64_t ix,
1634                                   uint64_t iy,
1635                                   uint64_t jx,
1636                                   uint64_t jy) {
1637   if ((ix <= jx) && (jx <= SIZE_MAX) && (jx <= t.width) &&  //
1638       (iy <= jy) && (jy <= SIZE_MAX) && (jy <= t.height)) {
1639     return wuffs_base__make_table_u8(t.ptr + ix + (iy * t.stride),  //
1640                                      ((size_t)(jx - ix)),           //
1641                                      ((size_t)(jy - iy)),           //
1642                                      t.stride);                     //
1643   }
1644   return wuffs_base__make_table_u8(NULL, 0, 0, 0);
1645 }
1646 
1647 // wuffs_base__table__flattened_length returns the number of elements covered
1648 // by the 1-dimensional span that backs a 2-dimensional table. This counts the
1649 // elements inside the table and, when width != stride, the elements outside
1650 // the table but between its rows.
1651 //
1652 // For example, consider a width 10, height 4, stride 10 table. Mark its first
1653 // and last (inclusive) elements with 'a' and 'z'. This function returns 40.
1654 //
1655 //    a123456789
1656 //    0123456789
1657 //    0123456789
1658 //    012345678z
1659 //
1660 // Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
1661 //
1662 //    a123456789
1663 //    01iiiiiioo
1664 //    ooiiiiiioo
1665 //    ooiiiiii8z
1666 //
1667 // This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
1668 // inside elements plus 8 'o' outside elements. Note that 26 is less than a
1669 // naive (height * stride = 30) computation. Indeed, advancing 29 elements from
1670 // the first 'i' would venture past 'z', out of bounds of the original table.
1671 //
1672 // It does not check for overflow, but if the arguments come from a table that
1673 // exists in memory and each element occupies a positive number of bytes then
1674 // the result should be bounded by the amount of allocatable memory (which
1675 // shouldn't overflow SIZE_MAX).
1676 static inline size_t  //
wuffs_base__table__flattened_length(size_t width,size_t height,size_t stride)1677 wuffs_base__table__flattened_length(size_t width,
1678                                     size_t height,
1679                                     size_t stride) {
1680   if (height == 0) {
1681     return 0;
1682   }
1683   return ((height - 1) * stride) + width;
1684 }
1685 
1686 // ---------------- Magic Numbers
1687 
1688 // wuffs_base__magic_number_guess_fourcc guesses the file format of some data,
1689 // given its starting bytes (the prefix_data argument) and whether or not there
1690 // may be further bytes (the prefix_closed argument; true means that
1691 // prefix_data is the entire data).
1692 //
1693 // It returns a positive FourCC value on success.
1694 //
1695 // It returns zero if nothing matches its hard-coded list of 'magic numbers'.
1696 //
1697 // It returns a negative value if prefix_closed is false and a longer prefix is
1698 // required for a conclusive result. For example, a single 'B' byte (without
1699 // further data) is not enough to discriminate the BMP and BPG image file
1700 // formats. Similarly, a single '\xFF' byte might be the start of JPEG data or
1701 // it might be the start of some other binary data.
1702 //
1703 // It does not do a full validity check. Like any guess made from a short
1704 // prefix of the data, it may return false positives. Data that starts with 99
1705 // bytes of valid JPEG followed by corruption or truncation is an invalid JPEG
1706 // image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.
1707 //
1708 // Another source of false positives is that some 'magic numbers' are valid
1709 // ASCII data. A file starting with "GIF87a and GIF89a are the two versions of
1710 // GIF" will match GIF's 'magic number' even if it's plain text, not an image.
1711 //
1712 // For modular builds that divide the base module into sub-modules, using this
1713 // function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just
1714 // WUFFS_CONFIG__MODULE__BASE__CORE.
1715 WUFFS_BASE__MAYBE_STATIC int32_t  //
1716 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
1717                                       bool prefix_closed);
1718 
1719 // ---------------- Ranges and Rects
1720 
1721 // See https://github.com/google/wuffs/blob/main/doc/note/ranges-and-rects.md
1722 
1723 typedef struct wuffs_base__range_ii_u32__struct {
1724   uint32_t min_incl;
1725   uint32_t max_incl;
1726 
1727 #ifdef __cplusplus
1728   inline bool is_empty() const;
1729   inline bool equals(wuffs_base__range_ii_u32__struct s) const;
1730   inline wuffs_base__range_ii_u32__struct intersect(
1731       wuffs_base__range_ii_u32__struct s) const;
1732   inline wuffs_base__range_ii_u32__struct unite(
1733       wuffs_base__range_ii_u32__struct s) const;
1734   inline bool contains(uint32_t x) const;
1735   inline bool contains_range(wuffs_base__range_ii_u32__struct s) const;
1736 #endif  // __cplusplus
1737 
1738 } wuffs_base__range_ii_u32;
1739 
1740 static inline wuffs_base__range_ii_u32  //
wuffs_base__empty_range_ii_u32()1741 wuffs_base__empty_range_ii_u32() {
1742   wuffs_base__range_ii_u32 ret;
1743   ret.min_incl = 0;
1744   ret.max_incl = 0;
1745   return ret;
1746 }
1747 
1748 static inline wuffs_base__range_ii_u32  //
wuffs_base__make_range_ii_u32(uint32_t min_incl,uint32_t max_incl)1749 wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) {
1750   wuffs_base__range_ii_u32 ret;
1751   ret.min_incl = min_incl;
1752   ret.max_incl = max_incl;
1753   return ret;
1754 }
1755 
1756 static inline bool  //
wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32 * r)1757 wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) {
1758   return r->min_incl > r->max_incl;
1759 }
1760 
1761 static inline bool  //
wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1762 wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r,
1763                                  wuffs_base__range_ii_u32 s) {
1764   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
1765          (wuffs_base__range_ii_u32__is_empty(r) &&
1766           wuffs_base__range_ii_u32__is_empty(&s));
1767 }
1768 
1769 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)1770 wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r,
1771                                     wuffs_base__range_ii_u32 s) {
1772   wuffs_base__range_ii_u32 t;
1773   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1774   t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl);
1775   return t;
1776 }
1777 
1778 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)1779 wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r,
1780                                 wuffs_base__range_ii_u32 s) {
1781   if (wuffs_base__range_ii_u32__is_empty(r)) {
1782     return s;
1783   }
1784   if (wuffs_base__range_ii_u32__is_empty(&s)) {
1785     return *r;
1786   }
1787   wuffs_base__range_ii_u32 t;
1788   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1789   t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl);
1790   return t;
1791 }
1792 
1793 static inline bool  //
wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32 * r,uint32_t x)1794 wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r,
1795                                    uint32_t x) {
1796   return (r->min_incl <= x) && (x <= r->max_incl);
1797 }
1798 
1799 static inline bool  //
wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1800 wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r,
1801                                          wuffs_base__range_ii_u32 s) {
1802   return wuffs_base__range_ii_u32__equals(
1803       &s, wuffs_base__range_ii_u32__intersect(r, s));
1804 }
1805 
1806 #ifdef __cplusplus
1807 
1808 inline bool  //
is_empty()1809 wuffs_base__range_ii_u32::is_empty() const {
1810   return wuffs_base__range_ii_u32__is_empty(this);
1811 }
1812 
1813 inline bool  //
equals(wuffs_base__range_ii_u32 s)1814 wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const {
1815   return wuffs_base__range_ii_u32__equals(this, s);
1816 }
1817 
1818 inline wuffs_base__range_ii_u32  //
intersect(wuffs_base__range_ii_u32 s)1819 wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const {
1820   return wuffs_base__range_ii_u32__intersect(this, s);
1821 }
1822 
1823 inline wuffs_base__range_ii_u32  //
unite(wuffs_base__range_ii_u32 s)1824 wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const {
1825   return wuffs_base__range_ii_u32__unite(this, s);
1826 }
1827 
1828 inline bool  //
contains(uint32_t x)1829 wuffs_base__range_ii_u32::contains(uint32_t x) const {
1830   return wuffs_base__range_ii_u32__contains(this, x);
1831 }
1832 
1833 inline bool  //
contains_range(wuffs_base__range_ii_u32 s)1834 wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const {
1835   return wuffs_base__range_ii_u32__contains_range(this, s);
1836 }
1837 
1838 #endif  // __cplusplus
1839 
1840 // --------
1841 
1842 typedef struct wuffs_base__range_ie_u32__struct {
1843   uint32_t min_incl;
1844   uint32_t max_excl;
1845 
1846 #ifdef __cplusplus
1847   inline bool is_empty() const;
1848   inline bool equals(wuffs_base__range_ie_u32__struct s) const;
1849   inline wuffs_base__range_ie_u32__struct intersect(
1850       wuffs_base__range_ie_u32__struct s) const;
1851   inline wuffs_base__range_ie_u32__struct unite(
1852       wuffs_base__range_ie_u32__struct s) const;
1853   inline bool contains(uint32_t x) const;
1854   inline bool contains_range(wuffs_base__range_ie_u32__struct s) const;
1855   inline uint32_t length() const;
1856 #endif  // __cplusplus
1857 
1858 } wuffs_base__range_ie_u32;
1859 
1860 static inline wuffs_base__range_ie_u32  //
wuffs_base__empty_range_ie_u32()1861 wuffs_base__empty_range_ie_u32() {
1862   wuffs_base__range_ie_u32 ret;
1863   ret.min_incl = 0;
1864   ret.max_excl = 0;
1865   return ret;
1866 }
1867 
1868 static inline wuffs_base__range_ie_u32  //
wuffs_base__make_range_ie_u32(uint32_t min_incl,uint32_t max_excl)1869 wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) {
1870   wuffs_base__range_ie_u32 ret;
1871   ret.min_incl = min_incl;
1872   ret.max_excl = max_excl;
1873   return ret;
1874 }
1875 
1876 static inline bool  //
wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32 * r)1877 wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) {
1878   return r->min_incl >= r->max_excl;
1879 }
1880 
1881 static inline bool  //
wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1882 wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r,
1883                                  wuffs_base__range_ie_u32 s) {
1884   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
1885          (wuffs_base__range_ie_u32__is_empty(r) &&
1886           wuffs_base__range_ie_u32__is_empty(&s));
1887 }
1888 
1889 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)1890 wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r,
1891                                     wuffs_base__range_ie_u32 s) {
1892   wuffs_base__range_ie_u32 t;
1893   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1894   t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl);
1895   return t;
1896 }
1897 
1898 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)1899 wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r,
1900                                 wuffs_base__range_ie_u32 s) {
1901   if (wuffs_base__range_ie_u32__is_empty(r)) {
1902     return s;
1903   }
1904   if (wuffs_base__range_ie_u32__is_empty(&s)) {
1905     return *r;
1906   }
1907   wuffs_base__range_ie_u32 t;
1908   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1909   t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl);
1910   return t;
1911 }
1912 
1913 static inline bool  //
wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32 * r,uint32_t x)1914 wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r,
1915                                    uint32_t x) {
1916   return (r->min_incl <= x) && (x < r->max_excl);
1917 }
1918 
1919 static inline bool  //
wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1920 wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r,
1921                                          wuffs_base__range_ie_u32 s) {
1922   return wuffs_base__range_ie_u32__equals(
1923       &s, wuffs_base__range_ie_u32__intersect(r, s));
1924 }
1925 
1926 static inline uint32_t  //
wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32 * r)1927 wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) {
1928   return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl);
1929 }
1930 
1931 #ifdef __cplusplus
1932 
1933 inline bool  //
is_empty()1934 wuffs_base__range_ie_u32::is_empty() const {
1935   return wuffs_base__range_ie_u32__is_empty(this);
1936 }
1937 
1938 inline bool  //
equals(wuffs_base__range_ie_u32 s)1939 wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const {
1940   return wuffs_base__range_ie_u32__equals(this, s);
1941 }
1942 
1943 inline wuffs_base__range_ie_u32  //
intersect(wuffs_base__range_ie_u32 s)1944 wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const {
1945   return wuffs_base__range_ie_u32__intersect(this, s);
1946 }
1947 
1948 inline wuffs_base__range_ie_u32  //
unite(wuffs_base__range_ie_u32 s)1949 wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const {
1950   return wuffs_base__range_ie_u32__unite(this, s);
1951 }
1952 
1953 inline bool  //
contains(uint32_t x)1954 wuffs_base__range_ie_u32::contains(uint32_t x) const {
1955   return wuffs_base__range_ie_u32__contains(this, x);
1956 }
1957 
1958 inline bool  //
contains_range(wuffs_base__range_ie_u32 s)1959 wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const {
1960   return wuffs_base__range_ie_u32__contains_range(this, s);
1961 }
1962 
1963 inline uint32_t  //
length()1964 wuffs_base__range_ie_u32::length() const {
1965   return wuffs_base__range_ie_u32__length(this);
1966 }
1967 
1968 #endif  // __cplusplus
1969 
1970 // --------
1971 
1972 typedef struct wuffs_base__range_ii_u64__struct {
1973   uint64_t min_incl;
1974   uint64_t max_incl;
1975 
1976 #ifdef __cplusplus
1977   inline bool is_empty() const;
1978   inline bool equals(wuffs_base__range_ii_u64__struct s) const;
1979   inline wuffs_base__range_ii_u64__struct intersect(
1980       wuffs_base__range_ii_u64__struct s) const;
1981   inline wuffs_base__range_ii_u64__struct unite(
1982       wuffs_base__range_ii_u64__struct s) const;
1983   inline bool contains(uint64_t x) const;
1984   inline bool contains_range(wuffs_base__range_ii_u64__struct s) const;
1985 #endif  // __cplusplus
1986 
1987 } wuffs_base__range_ii_u64;
1988 
1989 static inline wuffs_base__range_ii_u64  //
wuffs_base__empty_range_ii_u64()1990 wuffs_base__empty_range_ii_u64() {
1991   wuffs_base__range_ii_u64 ret;
1992   ret.min_incl = 0;
1993   ret.max_incl = 0;
1994   return ret;
1995 }
1996 
1997 static inline wuffs_base__range_ii_u64  //
wuffs_base__make_range_ii_u64(uint64_t min_incl,uint64_t max_incl)1998 wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) {
1999   wuffs_base__range_ii_u64 ret;
2000   ret.min_incl = min_incl;
2001   ret.max_incl = max_incl;
2002   return ret;
2003 }
2004 
2005 static inline bool  //
wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64 * r)2006 wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) {
2007   return r->min_incl > r->max_incl;
2008 }
2009 
2010 static inline bool  //
wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2011 wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r,
2012                                  wuffs_base__range_ii_u64 s) {
2013   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
2014          (wuffs_base__range_ii_u64__is_empty(r) &&
2015           wuffs_base__range_ii_u64__is_empty(&s));
2016 }
2017 
2018 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)2019 wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r,
2020                                     wuffs_base__range_ii_u64 s) {
2021   wuffs_base__range_ii_u64 t;
2022   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2023   t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl);
2024   return t;
2025 }
2026 
2027 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)2028 wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r,
2029                                 wuffs_base__range_ii_u64 s) {
2030   if (wuffs_base__range_ii_u64__is_empty(r)) {
2031     return s;
2032   }
2033   if (wuffs_base__range_ii_u64__is_empty(&s)) {
2034     return *r;
2035   }
2036   wuffs_base__range_ii_u64 t;
2037   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2038   t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl);
2039   return t;
2040 }
2041 
2042 static inline bool  //
wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64 * r,uint64_t x)2043 wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r,
2044                                    uint64_t x) {
2045   return (r->min_incl <= x) && (x <= r->max_incl);
2046 }
2047 
2048 static inline bool  //
wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2049 wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r,
2050                                          wuffs_base__range_ii_u64 s) {
2051   return wuffs_base__range_ii_u64__equals(
2052       &s, wuffs_base__range_ii_u64__intersect(r, s));
2053 }
2054 
2055 #ifdef __cplusplus
2056 
2057 inline bool  //
is_empty()2058 wuffs_base__range_ii_u64::is_empty() const {
2059   return wuffs_base__range_ii_u64__is_empty(this);
2060 }
2061 
2062 inline bool  //
equals(wuffs_base__range_ii_u64 s)2063 wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const {
2064   return wuffs_base__range_ii_u64__equals(this, s);
2065 }
2066 
2067 inline wuffs_base__range_ii_u64  //
intersect(wuffs_base__range_ii_u64 s)2068 wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const {
2069   return wuffs_base__range_ii_u64__intersect(this, s);
2070 }
2071 
2072 inline wuffs_base__range_ii_u64  //
unite(wuffs_base__range_ii_u64 s)2073 wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const {
2074   return wuffs_base__range_ii_u64__unite(this, s);
2075 }
2076 
2077 inline bool  //
contains(uint64_t x)2078 wuffs_base__range_ii_u64::contains(uint64_t x) const {
2079   return wuffs_base__range_ii_u64__contains(this, x);
2080 }
2081 
2082 inline bool  //
contains_range(wuffs_base__range_ii_u64 s)2083 wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const {
2084   return wuffs_base__range_ii_u64__contains_range(this, s);
2085 }
2086 
2087 #endif  // __cplusplus
2088 
2089 // --------
2090 
2091 typedef struct wuffs_base__range_ie_u64__struct {
2092   uint64_t min_incl;
2093   uint64_t max_excl;
2094 
2095 #ifdef __cplusplus
2096   inline bool is_empty() const;
2097   inline bool equals(wuffs_base__range_ie_u64__struct s) const;
2098   inline wuffs_base__range_ie_u64__struct intersect(
2099       wuffs_base__range_ie_u64__struct s) const;
2100   inline wuffs_base__range_ie_u64__struct unite(
2101       wuffs_base__range_ie_u64__struct s) const;
2102   inline bool contains(uint64_t x) const;
2103   inline bool contains_range(wuffs_base__range_ie_u64__struct s) const;
2104   inline uint64_t length() const;
2105 #endif  // __cplusplus
2106 
2107 } wuffs_base__range_ie_u64;
2108 
2109 static inline wuffs_base__range_ie_u64  //
wuffs_base__empty_range_ie_u64()2110 wuffs_base__empty_range_ie_u64() {
2111   wuffs_base__range_ie_u64 ret;
2112   ret.min_incl = 0;
2113   ret.max_excl = 0;
2114   return ret;
2115 }
2116 
2117 static inline wuffs_base__range_ie_u64  //
wuffs_base__make_range_ie_u64(uint64_t min_incl,uint64_t max_excl)2118 wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) {
2119   wuffs_base__range_ie_u64 ret;
2120   ret.min_incl = min_incl;
2121   ret.max_excl = max_excl;
2122   return ret;
2123 }
2124 
2125 static inline bool  //
wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64 * r)2126 wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) {
2127   return r->min_incl >= r->max_excl;
2128 }
2129 
2130 static inline bool  //
wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2131 wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r,
2132                                  wuffs_base__range_ie_u64 s) {
2133   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
2134          (wuffs_base__range_ie_u64__is_empty(r) &&
2135           wuffs_base__range_ie_u64__is_empty(&s));
2136 }
2137 
2138 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)2139 wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r,
2140                                     wuffs_base__range_ie_u64 s) {
2141   wuffs_base__range_ie_u64 t;
2142   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2143   t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl);
2144   return t;
2145 }
2146 
2147 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)2148 wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r,
2149                                 wuffs_base__range_ie_u64 s) {
2150   if (wuffs_base__range_ie_u64__is_empty(r)) {
2151     return s;
2152   }
2153   if (wuffs_base__range_ie_u64__is_empty(&s)) {
2154     return *r;
2155   }
2156   wuffs_base__range_ie_u64 t;
2157   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2158   t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl);
2159   return t;
2160 }
2161 
2162 static inline bool  //
wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64 * r,uint64_t x)2163 wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r,
2164                                    uint64_t x) {
2165   return (r->min_incl <= x) && (x < r->max_excl);
2166 }
2167 
2168 static inline bool  //
wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2169 wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r,
2170                                          wuffs_base__range_ie_u64 s) {
2171   return wuffs_base__range_ie_u64__equals(
2172       &s, wuffs_base__range_ie_u64__intersect(r, s));
2173 }
2174 
2175 static inline uint64_t  //
wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64 * r)2176 wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) {
2177   return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl);
2178 }
2179 
2180 #ifdef __cplusplus
2181 
2182 inline bool  //
is_empty()2183 wuffs_base__range_ie_u64::is_empty() const {
2184   return wuffs_base__range_ie_u64__is_empty(this);
2185 }
2186 
2187 inline bool  //
equals(wuffs_base__range_ie_u64 s)2188 wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const {
2189   return wuffs_base__range_ie_u64__equals(this, s);
2190 }
2191 
2192 inline wuffs_base__range_ie_u64  //
intersect(wuffs_base__range_ie_u64 s)2193 wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const {
2194   return wuffs_base__range_ie_u64__intersect(this, s);
2195 }
2196 
2197 inline wuffs_base__range_ie_u64  //
unite(wuffs_base__range_ie_u64 s)2198 wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const {
2199   return wuffs_base__range_ie_u64__unite(this, s);
2200 }
2201 
2202 inline bool  //
contains(uint64_t x)2203 wuffs_base__range_ie_u64::contains(uint64_t x) const {
2204   return wuffs_base__range_ie_u64__contains(this, x);
2205 }
2206 
2207 inline bool  //
contains_range(wuffs_base__range_ie_u64 s)2208 wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const {
2209   return wuffs_base__range_ie_u64__contains_range(this, s);
2210 }
2211 
2212 inline uint64_t  //
length()2213 wuffs_base__range_ie_u64::length() const {
2214   return wuffs_base__range_ie_u64__length(this);
2215 }
2216 
2217 #endif  // __cplusplus
2218 
2219 // --------
2220 
2221 typedef struct wuffs_base__rect_ii_u32__struct {
2222   uint32_t min_incl_x;
2223   uint32_t min_incl_y;
2224   uint32_t max_incl_x;
2225   uint32_t max_incl_y;
2226 
2227 #ifdef __cplusplus
2228   inline bool is_empty() const;
2229   inline bool equals(wuffs_base__rect_ii_u32__struct s) const;
2230   inline wuffs_base__rect_ii_u32__struct intersect(
2231       wuffs_base__rect_ii_u32__struct s) const;
2232   inline wuffs_base__rect_ii_u32__struct unite(
2233       wuffs_base__rect_ii_u32__struct s) const;
2234   inline bool contains(uint32_t x, uint32_t y) const;
2235   inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const;
2236 #endif  // __cplusplus
2237 
2238 } wuffs_base__rect_ii_u32;
2239 
2240 static inline wuffs_base__rect_ii_u32  //
wuffs_base__empty_rect_ii_u32()2241 wuffs_base__empty_rect_ii_u32() {
2242   wuffs_base__rect_ii_u32 ret;
2243   ret.min_incl_x = 0;
2244   ret.min_incl_y = 0;
2245   ret.max_incl_x = 0;
2246   ret.max_incl_y = 0;
2247   return ret;
2248 }
2249 
2250 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)2251 wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,
2252                              uint32_t min_incl_y,
2253                              uint32_t max_incl_x,
2254                              uint32_t max_incl_y) {
2255   wuffs_base__rect_ii_u32 ret;
2256   ret.min_incl_x = min_incl_x;
2257   ret.min_incl_y = min_incl_y;
2258   ret.max_incl_x = max_incl_x;
2259   ret.max_incl_y = max_incl_y;
2260   return ret;
2261 }
2262 
2263 static inline bool  //
wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32 * r)2264 wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) {
2265   return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y);
2266 }
2267 
2268 static inline bool  //
wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2269 wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r,
2270                                 wuffs_base__rect_ii_u32 s) {
2271   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2272           r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) ||
2273          (wuffs_base__rect_ii_u32__is_empty(r) &&
2274           wuffs_base__rect_ii_u32__is_empty(&s));
2275 }
2276 
2277 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)2278 wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r,
2279                                    wuffs_base__rect_ii_u32 s) {
2280   wuffs_base__rect_ii_u32 t;
2281   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2282   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2283   t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x);
2284   t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y);
2285   return t;
2286 }
2287 
2288 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)2289 wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r,
2290                                wuffs_base__rect_ii_u32 s) {
2291   if (wuffs_base__rect_ii_u32__is_empty(r)) {
2292     return s;
2293   }
2294   if (wuffs_base__rect_ii_u32__is_empty(&s)) {
2295     return *r;
2296   }
2297   wuffs_base__rect_ii_u32 t;
2298   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2299   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2300   t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x);
2301   t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y);
2302   return t;
2303 }
2304 
2305 static inline bool  //
wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32 * r,uint32_t x,uint32_t y)2306 wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r,
2307                                   uint32_t x,
2308                                   uint32_t y) {
2309   return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) &&
2310          (y <= r->max_incl_y);
2311 }
2312 
2313 static inline bool  //
wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2314 wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r,
2315                                        wuffs_base__rect_ii_u32 s) {
2316   return wuffs_base__rect_ii_u32__equals(
2317       &s, wuffs_base__rect_ii_u32__intersect(r, s));
2318 }
2319 
2320 #ifdef __cplusplus
2321 
2322 inline bool  //
is_empty()2323 wuffs_base__rect_ii_u32::is_empty() const {
2324   return wuffs_base__rect_ii_u32__is_empty(this);
2325 }
2326 
2327 inline bool  //
equals(wuffs_base__rect_ii_u32 s)2328 wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const {
2329   return wuffs_base__rect_ii_u32__equals(this, s);
2330 }
2331 
2332 inline wuffs_base__rect_ii_u32  //
intersect(wuffs_base__rect_ii_u32 s)2333 wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const {
2334   return wuffs_base__rect_ii_u32__intersect(this, s);
2335 }
2336 
2337 inline wuffs_base__rect_ii_u32  //
unite(wuffs_base__rect_ii_u32 s)2338 wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const {
2339   return wuffs_base__rect_ii_u32__unite(this, s);
2340 }
2341 
2342 inline bool  //
contains(uint32_t x,uint32_t y)2343 wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const {
2344   return wuffs_base__rect_ii_u32__contains(this, x, y);
2345 }
2346 
2347 inline bool  //
contains_rect(wuffs_base__rect_ii_u32 s)2348 wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const {
2349   return wuffs_base__rect_ii_u32__contains_rect(this, s);
2350 }
2351 
2352 #endif  // __cplusplus
2353 
2354 // --------
2355 
2356 typedef struct wuffs_base__rect_ie_u32__struct {
2357   uint32_t min_incl_x;
2358   uint32_t min_incl_y;
2359   uint32_t max_excl_x;
2360   uint32_t max_excl_y;
2361 
2362 #ifdef __cplusplus
2363   inline bool is_empty() const;
2364   inline bool equals(wuffs_base__rect_ie_u32__struct s) const;
2365   inline wuffs_base__rect_ie_u32__struct intersect(
2366       wuffs_base__rect_ie_u32__struct s) const;
2367   inline wuffs_base__rect_ie_u32__struct unite(
2368       wuffs_base__rect_ie_u32__struct s) const;
2369   inline bool contains(uint32_t x, uint32_t y) const;
2370   inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const;
2371   inline uint32_t width() const;
2372   inline uint32_t height() const;
2373 #endif  // __cplusplus
2374 
2375 } wuffs_base__rect_ie_u32;
2376 
2377 static inline wuffs_base__rect_ie_u32  //
wuffs_base__empty_rect_ie_u32()2378 wuffs_base__empty_rect_ie_u32() {
2379   wuffs_base__rect_ie_u32 ret;
2380   ret.min_incl_x = 0;
2381   ret.min_incl_y = 0;
2382   ret.max_excl_x = 0;
2383   ret.max_excl_y = 0;
2384   return ret;
2385 }
2386 
2387 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)2388 wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,
2389                              uint32_t min_incl_y,
2390                              uint32_t max_excl_x,
2391                              uint32_t max_excl_y) {
2392   wuffs_base__rect_ie_u32 ret;
2393   ret.min_incl_x = min_incl_x;
2394   ret.min_incl_y = min_incl_y;
2395   ret.max_excl_x = max_excl_x;
2396   ret.max_excl_y = max_excl_y;
2397   return ret;
2398 }
2399 
2400 static inline bool  //
wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32 * r)2401 wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) {
2402   return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y);
2403 }
2404 
2405 static inline bool  //
wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2406 wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r,
2407                                 wuffs_base__rect_ie_u32 s) {
2408   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2409           r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) ||
2410          (wuffs_base__rect_ie_u32__is_empty(r) &&
2411           wuffs_base__rect_ie_u32__is_empty(&s));
2412 }
2413 
2414 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)2415 wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r,
2416                                    wuffs_base__rect_ie_u32 s) {
2417   wuffs_base__rect_ie_u32 t;
2418   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2419   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2420   t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x);
2421   t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y);
2422   return t;
2423 }
2424 
2425 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)2426 wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r,
2427                                wuffs_base__rect_ie_u32 s) {
2428   if (wuffs_base__rect_ie_u32__is_empty(r)) {
2429     return s;
2430   }
2431   if (wuffs_base__rect_ie_u32__is_empty(&s)) {
2432     return *r;
2433   }
2434   wuffs_base__rect_ie_u32 t;
2435   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2436   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2437   t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x);
2438   t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y);
2439   return t;
2440 }
2441 
2442 static inline bool  //
wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32 * r,uint32_t x,uint32_t y)2443 wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r,
2444                                   uint32_t x,
2445                                   uint32_t y) {
2446   return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) &&
2447          (y < r->max_excl_y);
2448 }
2449 
2450 static inline bool  //
wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2451 wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r,
2452                                        wuffs_base__rect_ie_u32 s) {
2453   return wuffs_base__rect_ie_u32__equals(
2454       &s, wuffs_base__rect_ie_u32__intersect(r, s));
2455 }
2456 
2457 static inline uint32_t  //
wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32 * r)2458 wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) {
2459   return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x);
2460 }
2461 
2462 static inline uint32_t  //
wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32 * r)2463 wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) {
2464   return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y);
2465 }
2466 
2467 #ifdef __cplusplus
2468 
2469 inline bool  //
is_empty()2470 wuffs_base__rect_ie_u32::is_empty() const {
2471   return wuffs_base__rect_ie_u32__is_empty(this);
2472 }
2473 
2474 inline bool  //
equals(wuffs_base__rect_ie_u32 s)2475 wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const {
2476   return wuffs_base__rect_ie_u32__equals(this, s);
2477 }
2478 
2479 inline wuffs_base__rect_ie_u32  //
intersect(wuffs_base__rect_ie_u32 s)2480 wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const {
2481   return wuffs_base__rect_ie_u32__intersect(this, s);
2482 }
2483 
2484 inline wuffs_base__rect_ie_u32  //
unite(wuffs_base__rect_ie_u32 s)2485 wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const {
2486   return wuffs_base__rect_ie_u32__unite(this, s);
2487 }
2488 
2489 inline bool  //
contains(uint32_t x,uint32_t y)2490 wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const {
2491   return wuffs_base__rect_ie_u32__contains(this, x, y);
2492 }
2493 
2494 inline bool  //
contains_rect(wuffs_base__rect_ie_u32 s)2495 wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const {
2496   return wuffs_base__rect_ie_u32__contains_rect(this, s);
2497 }
2498 
2499 inline uint32_t  //
width()2500 wuffs_base__rect_ie_u32::width() const {
2501   return wuffs_base__rect_ie_u32__width(this);
2502 }
2503 
2504 inline uint32_t  //
height()2505 wuffs_base__rect_ie_u32::height() const {
2506   return wuffs_base__rect_ie_u32__height(this);
2507 }
2508 
2509 #endif  // __cplusplus
2510 
2511 // ---------------- More Information
2512 
2513 // wuffs_base__more_information holds additional fields, typically when a Wuffs
2514 // method returns a [note status](/doc/note/statuses.md).
2515 //
2516 // The flavor field follows the base38 namespace
2517 // convention](/doc/note/base38-and-fourcc.md). The other fields' semantics
2518 // depends on the flavor.
2519 typedef struct wuffs_base__more_information__struct {
2520   uint32_t flavor;
2521   uint32_t w;
2522   uint64_t x;
2523   uint64_t y;
2524   uint64_t z;
2525 
2526 #ifdef __cplusplus
2527   inline void set(uint32_t flavor_arg,
2528                   uint32_t w_arg,
2529                   uint64_t x_arg,
2530                   uint64_t y_arg,
2531                   uint64_t z_arg);
2532   inline uint32_t io_redirect__fourcc() const;
2533   inline wuffs_base__range_ie_u64 io_redirect__range() const;
2534   inline uint64_t io_seek__position() const;
2535   inline uint32_t metadata__fourcc() const;
2536   // Deprecated: use metadata_raw_passthrough__range.
2537   inline wuffs_base__range_ie_u64 metadata__range() const;
2538   inline wuffs_base__range_ie_u64 metadata_raw_passthrough__range() const;
2539   inline int32_t metadata_parsed__chrm(uint32_t component) const;
2540   inline uint32_t metadata_parsed__gama() const;
2541   inline uint32_t metadata_parsed__srgb() const;
2542 #endif  // __cplusplus
2543 
2544 } wuffs_base__more_information;
2545 
2546 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT 1
2547 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK 2
2548 // Deprecated: use
2549 // WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH.
2550 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA 3
2551 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH 3
2552 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM 4
2553 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED 5
2554 
2555 static inline wuffs_base__more_information  //
wuffs_base__empty_more_information()2556 wuffs_base__empty_more_information() {
2557   wuffs_base__more_information ret;
2558   ret.flavor = 0;
2559   ret.w = 0;
2560   ret.x = 0;
2561   ret.y = 0;
2562   ret.z = 0;
2563   return ret;
2564 }
2565 
2566 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)2567 wuffs_base__more_information__set(wuffs_base__more_information* m,
2568                                   uint32_t flavor,
2569                                   uint32_t w,
2570                                   uint64_t x,
2571                                   uint64_t y,
2572                                   uint64_t z) {
2573   if (!m) {
2574     return;
2575   }
2576   m->flavor = flavor;
2577   m->w = w;
2578   m->x = x;
2579   m->y = y;
2580   m->z = z;
2581 }
2582 
2583 static inline uint32_t  //
wuffs_base__more_information__io_redirect__fourcc(const wuffs_base__more_information * m)2584 wuffs_base__more_information__io_redirect__fourcc(
2585     const wuffs_base__more_information* m) {
2586   return m->w;
2587 }
2588 
2589 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__io_redirect__range(const wuffs_base__more_information * m)2590 wuffs_base__more_information__io_redirect__range(
2591     const wuffs_base__more_information* m) {
2592   wuffs_base__range_ie_u64 ret;
2593   ret.min_incl = m->y;
2594   ret.max_excl = m->z;
2595   return ret;
2596 }
2597 
2598 static inline uint64_t  //
wuffs_base__more_information__io_seek__position(const wuffs_base__more_information * m)2599 wuffs_base__more_information__io_seek__position(
2600     const wuffs_base__more_information* m) {
2601   return m->x;
2602 }
2603 
2604 static inline uint32_t  //
wuffs_base__more_information__metadata__fourcc(const wuffs_base__more_information * m)2605 wuffs_base__more_information__metadata__fourcc(
2606     const wuffs_base__more_information* m) {
2607   return m->w;
2608 }
2609 
2610 // Deprecated: use
2611 // wuffs_base__more_information__metadata_raw_passthrough__range.
2612 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__metadata__range(const wuffs_base__more_information * m)2613 wuffs_base__more_information__metadata__range(
2614     const wuffs_base__more_information* m) {
2615   wuffs_base__range_ie_u64 ret;
2616   ret.min_incl = m->y;
2617   ret.max_excl = m->z;
2618   return ret;
2619 }
2620 
2621 static inline wuffs_base__range_ie_u64  //
wuffs_base__more_information__metadata_raw_passthrough__range(const wuffs_base__more_information * m)2622 wuffs_base__more_information__metadata_raw_passthrough__range(
2623     const wuffs_base__more_information* m) {
2624   wuffs_base__range_ie_u64 ret;
2625   ret.min_incl = m->y;
2626   ret.max_excl = m->z;
2627   return ret;
2628 }
2629 
2630 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_X 0
2631 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_Y 1
2632 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_X 2
2633 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_Y 3
2634 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_X 4
2635 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_Y 5
2636 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_X 6
2637 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_Y 7
2638 
2639 // wuffs_base__more_information__metadata_parsed__chrm returns chromaticity
2640 // values (scaled by 100000) like the PNG "cHRM" chunk. For example, the sRGB
2641 // color space corresponds to:
2642 //  - ETC__CHRM__WHITE_X 31270
2643 //  - ETC__CHRM__WHITE_Y 32900
2644 //  - ETC__CHRM__RED_X   64000
2645 //  - ETC__CHRM__RED_Y   33000
2646 //  - ETC__CHRM__GREEN_X 30000
2647 //  - ETC__CHRM__GREEN_Y 60000
2648 //  - ETC__CHRM__BLUE_X  15000
2649 //  - ETC__CHRM__BLUE_Y   6000
2650 //
2651 // See
2652 // https://ciechanow.ski/color-spaces/#chromaticity-and-white-point-coordinates
2653 static inline int32_t  //
wuffs_base__more_information__metadata_parsed__chrm(const wuffs_base__more_information * m,uint32_t component)2654 wuffs_base__more_information__metadata_parsed__chrm(
2655     const wuffs_base__more_information* m,
2656     uint32_t component) {
2657   // After the flavor and the w field (holding a FourCC), a
2658   // wuffs_base__more_information holds 24 bytes of data in three uint64_t
2659   // typed fields (x, y and z). We pack the eight chromaticity values (wx, wy,
2660   // rx, ..., by), basically int24_t values, into 24 bytes like this:
2661   //  -    LSB                 MSB
2662   //  - x: wx wx wx wy wy wy rx rx
2663   //  - y: rx ry ry ry gx gx gx gy
2664   //  - z: gy gy bx bx bx by by by
2665   uint32_t u = 0;
2666   switch (component & 7) {
2667     case 0:
2668       u = ((uint32_t)(m->x >> 0));
2669       break;
2670     case 1:
2671       u = ((uint32_t)(m->x >> 24));
2672       break;
2673     case 2:
2674       u = ((uint32_t)((m->x >> 48) | (m->y << 16)));
2675       break;
2676     case 3:
2677       u = ((uint32_t)(m->y >> 8));
2678       break;
2679     case 4:
2680       u = ((uint32_t)(m->y >> 32));
2681       break;
2682     case 5:
2683       u = ((uint32_t)((m->y >> 56) | (m->z << 8)));
2684       break;
2685     case 6:
2686       u = ((uint32_t)(m->z >> 16));
2687       break;
2688     case 7:
2689       u = ((uint32_t)(m->z >> 40));
2690       break;
2691   }
2692   // The left-right shifts sign-extend from 24-bit to 32-bit integers.
2693   return ((int32_t)(u << 8)) >> 8;
2694 }
2695 
2696 // wuffs_base__more_information__metadata_parsed__gama returns inverse gamma
2697 // correction values (scaled by 100000) like the PNG "gAMA" chunk. For example,
2698 // for gamma = 2.2, this returns 45455 (approximating 100000 / 2.2).
2699 static inline uint32_t  //
wuffs_base__more_information__metadata_parsed__gama(const wuffs_base__more_information * m)2700 wuffs_base__more_information__metadata_parsed__gama(
2701     const wuffs_base__more_information* m) {
2702   return ((uint32_t)(m->x));
2703 }
2704 
2705 #define WUFFS_BASE__SRGB_RENDERING_INTENT__PERCEPTUAL 0
2706 #define WUFFS_BASE__SRGB_RENDERING_INTENT__RELATIVE_COLORIMETRIC 1
2707 #define WUFFS_BASE__SRGB_RENDERING_INTENT__SATURATION 2
2708 #define WUFFS_BASE__SRGB_RENDERING_INTENT__ABSOLUTE_COLORIMETRIC 3
2709 
2710 // wuffs_base__more_information__metadata_parsed__srgb returns the sRGB
2711 // rendering intent like the PNG "sRGB" chunk.
2712 static inline uint32_t  //
wuffs_base__more_information__metadata_parsed__srgb(const wuffs_base__more_information * m)2713 wuffs_base__more_information__metadata_parsed__srgb(
2714     const wuffs_base__more_information* m) {
2715   return m->x & 3;
2716 }
2717 
2718 #ifdef __cplusplus
2719 
2720 inline void  //
set(uint32_t flavor_arg,uint32_t w_arg,uint64_t x_arg,uint64_t y_arg,uint64_t z_arg)2721 wuffs_base__more_information::set(uint32_t flavor_arg,
2722                                   uint32_t w_arg,
2723                                   uint64_t x_arg,
2724                                   uint64_t y_arg,
2725                                   uint64_t z_arg) {
2726   wuffs_base__more_information__set(this, flavor_arg, w_arg, x_arg, y_arg,
2727                                     z_arg);
2728 }
2729 
2730 inline uint32_t  //
io_redirect__fourcc()2731 wuffs_base__more_information::io_redirect__fourcc() const {
2732   return wuffs_base__more_information__io_redirect__fourcc(this);
2733 }
2734 
2735 inline wuffs_base__range_ie_u64  //
io_redirect__range()2736 wuffs_base__more_information::io_redirect__range() const {
2737   return wuffs_base__more_information__io_redirect__range(this);
2738 }
2739 
2740 inline uint64_t  //
io_seek__position()2741 wuffs_base__more_information::io_seek__position() const {
2742   return wuffs_base__more_information__io_seek__position(this);
2743 }
2744 
2745 inline uint32_t  //
metadata__fourcc()2746 wuffs_base__more_information::metadata__fourcc() const {
2747   return wuffs_base__more_information__metadata__fourcc(this);
2748 }
2749 
2750 inline wuffs_base__range_ie_u64  //
metadata__range()2751 wuffs_base__more_information::metadata__range() const {
2752   return wuffs_base__more_information__metadata__range(this);
2753 }
2754 
2755 inline wuffs_base__range_ie_u64  //
metadata_raw_passthrough__range()2756 wuffs_base__more_information::metadata_raw_passthrough__range() const {
2757   return wuffs_base__more_information__metadata_raw_passthrough__range(this);
2758 }
2759 
2760 inline int32_t  //
metadata_parsed__chrm(uint32_t component)2761 wuffs_base__more_information::metadata_parsed__chrm(uint32_t component) const {
2762   return wuffs_base__more_information__metadata_parsed__chrm(this, component);
2763 }
2764 
2765 inline uint32_t  //
metadata_parsed__gama()2766 wuffs_base__more_information::metadata_parsed__gama() const {
2767   return wuffs_base__more_information__metadata_parsed__gama(this);
2768 }
2769 
2770 inline uint32_t  //
metadata_parsed__srgb()2771 wuffs_base__more_information::metadata_parsed__srgb() const {
2772   return wuffs_base__more_information__metadata_parsed__srgb(this);
2773 }
2774 
2775 #endif  // __cplusplus
2776 
2777 // ---------------- I/O
2778 //
2779 // See (/doc/note/io-input-output.md).
2780 
2781 // wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's
2782 // data.
2783 typedef struct wuffs_base__io_buffer_meta__struct {
2784   size_t wi;     // Write index. Invariant: wi <= len.
2785   size_t ri;     // Read  index. Invariant: ri <= wi.
2786   uint64_t pos;  // Buffer position (relative to the start of stream).
2787   bool closed;   // No further writes are expected.
2788 } wuffs_base__io_buffer_meta;
2789 
2790 // wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus
2791 // additional metadata.
2792 //
2793 // A value with all fields zero is a valid, empty buffer.
2794 typedef struct wuffs_base__io_buffer__struct {
2795   wuffs_base__slice_u8 data;
2796   wuffs_base__io_buffer_meta meta;
2797 
2798 #ifdef __cplusplus
2799   inline bool is_valid() const;
2800   inline void compact();
2801   inline size_t reader_length() const;
2802   inline uint8_t* reader_pointer() const;
2803   inline uint64_t reader_position() const;
2804   inline wuffs_base__slice_u8 reader_slice() const;
2805   inline size_t writer_length() const;
2806   inline uint8_t* writer_pointer() const;
2807   inline uint64_t writer_position() const;
2808   inline wuffs_base__slice_u8 writer_slice() const;
2809 
2810   // Deprecated: use reader_position.
2811   inline uint64_t reader_io_position() const;
2812   // Deprecated: use writer_position.
2813   inline uint64_t writer_io_position() const;
2814 #endif  // __cplusplus
2815 
2816 } wuffs_base__io_buffer;
2817 
2818 static inline wuffs_base__io_buffer  //
wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,wuffs_base__io_buffer_meta meta)2819 wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,
2820                            wuffs_base__io_buffer_meta meta) {
2821   wuffs_base__io_buffer ret;
2822   ret.data = data;
2823   ret.meta = meta;
2824   return ret;
2825 }
2826 
2827 static inline wuffs_base__io_buffer_meta  //
wuffs_base__make_io_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)2828 wuffs_base__make_io_buffer_meta(size_t wi,
2829                                 size_t ri,
2830                                 uint64_t pos,
2831                                 bool closed) {
2832   wuffs_base__io_buffer_meta ret;
2833   ret.wi = wi;
2834   ret.ri = ri;
2835   ret.pos = pos;
2836   ret.closed = closed;
2837   return ret;
2838 }
2839 
2840 static inline wuffs_base__io_buffer  //
wuffs_base__ptr_u8__reader(uint8_t * ptr,size_t len,bool closed)2841 wuffs_base__ptr_u8__reader(uint8_t* ptr, size_t len, bool closed) {
2842   wuffs_base__io_buffer ret;
2843   ret.data.ptr = ptr;
2844   ret.data.len = len;
2845   ret.meta.wi = len;
2846   ret.meta.ri = 0;
2847   ret.meta.pos = 0;
2848   ret.meta.closed = closed;
2849   return ret;
2850 }
2851 
2852 static inline wuffs_base__io_buffer  //
wuffs_base__ptr_u8__writer(uint8_t * ptr,size_t len)2853 wuffs_base__ptr_u8__writer(uint8_t* ptr, size_t len) {
2854   wuffs_base__io_buffer ret;
2855   ret.data.ptr = ptr;
2856   ret.data.len = len;
2857   ret.meta.wi = 0;
2858   ret.meta.ri = 0;
2859   ret.meta.pos = 0;
2860   ret.meta.closed = false;
2861   return ret;
2862 }
2863 
2864 static inline wuffs_base__io_buffer  //
wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s,bool closed)2865 wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s, bool closed) {
2866   wuffs_base__io_buffer ret;
2867   ret.data.ptr = s.ptr;
2868   ret.data.len = s.len;
2869   ret.meta.wi = s.len;
2870   ret.meta.ri = 0;
2871   ret.meta.pos = 0;
2872   ret.meta.closed = closed;
2873   return ret;
2874 }
2875 
2876 static inline wuffs_base__io_buffer  //
wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s)2877 wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s) {
2878   wuffs_base__io_buffer ret;
2879   ret.data.ptr = s.ptr;
2880   ret.data.len = s.len;
2881   ret.meta.wi = 0;
2882   ret.meta.ri = 0;
2883   ret.meta.pos = 0;
2884   ret.meta.closed = false;
2885   return ret;
2886 }
2887 
2888 static inline wuffs_base__io_buffer  //
wuffs_base__empty_io_buffer()2889 wuffs_base__empty_io_buffer() {
2890   wuffs_base__io_buffer ret;
2891   ret.data.ptr = NULL;
2892   ret.data.len = 0;
2893   ret.meta.wi = 0;
2894   ret.meta.ri = 0;
2895   ret.meta.pos = 0;
2896   ret.meta.closed = false;
2897   return ret;
2898 }
2899 
2900 static inline wuffs_base__io_buffer_meta  //
wuffs_base__empty_io_buffer_meta()2901 wuffs_base__empty_io_buffer_meta() {
2902   wuffs_base__io_buffer_meta ret;
2903   ret.wi = 0;
2904   ret.ri = 0;
2905   ret.pos = 0;
2906   ret.closed = false;
2907   return ret;
2908 }
2909 
2910 static inline bool  //
wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer * buf)2911 wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer* buf) {
2912   if (buf) {
2913     if (buf->data.ptr) {
2914       return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
2915     } else {
2916       return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
2917     }
2918   }
2919   return false;
2920 }
2921 
2922 // wuffs_base__io_buffer__compact moves any written but unread bytes to the
2923 // start of the buffer.
2924 static inline void  //
wuffs_base__io_buffer__compact(wuffs_base__io_buffer * buf)2925 wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) {
2926   if (!buf || (buf->meta.ri == 0)) {
2927     return;
2928   }
2929   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
2930   size_t n = buf->meta.wi - buf->meta.ri;
2931   if (n != 0) {
2932     memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, n);
2933   }
2934   buf->meta.wi = n;
2935   buf->meta.ri = 0;
2936 }
2937 
2938 // Deprecated. Use wuffs_base__io_buffer__reader_position.
2939 static inline uint64_t  //
wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer * buf)2940 wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer* buf) {
2941   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
2942 }
2943 
2944 static inline size_t  //
wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer * buf)2945 wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer* buf) {
2946   return buf ? buf->meta.wi - buf->meta.ri : 0;
2947 }
2948 
2949 static inline uint8_t*  //
wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer * buf)2950 wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer* buf) {
2951   return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
2952 }
2953 
2954 static inline uint64_t  //
wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer * buf)2955 wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer* buf) {
2956   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
2957 }
2958 
2959 static inline wuffs_base__slice_u8  //
wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer * buf)2960 wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer* buf) {
2961   return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri,
2962                                          buf->meta.wi - buf->meta.ri)
2963              : wuffs_base__empty_slice_u8();
2964 }
2965 
2966 // Deprecated. Use wuffs_base__io_buffer__writer_position.
2967 static inline uint64_t  //
wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer * buf)2968 wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer* buf) {
2969   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
2970 }
2971 
2972 static inline size_t  //
wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer * buf)2973 wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer* buf) {
2974   return buf ? buf->data.len - buf->meta.wi : 0;
2975 }
2976 
2977 static inline uint8_t*  //
wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer * buf)2978 wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer* buf) {
2979   return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
2980 }
2981 
2982 static inline uint64_t  //
wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer * buf)2983 wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer* buf) {
2984   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
2985 }
2986 
2987 static inline wuffs_base__slice_u8  //
wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer * buf)2988 wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer* buf) {
2989   return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi,
2990                                          buf->data.len - buf->meta.wi)
2991              : wuffs_base__empty_slice_u8();
2992 }
2993 
2994 #ifdef __cplusplus
2995 
2996 inline bool  //
is_valid()2997 wuffs_base__io_buffer::is_valid() const {
2998   return wuffs_base__io_buffer__is_valid(this);
2999 }
3000 
3001 inline void  //
compact()3002 wuffs_base__io_buffer::compact() {
3003   wuffs_base__io_buffer__compact(this);
3004 }
3005 
3006 inline uint64_t  //
reader_io_position()3007 wuffs_base__io_buffer::reader_io_position() const {
3008   return wuffs_base__io_buffer__reader_io_position(this);
3009 }
3010 
3011 inline size_t  //
reader_length()3012 wuffs_base__io_buffer::reader_length() const {
3013   return wuffs_base__io_buffer__reader_length(this);
3014 }
3015 
3016 inline uint8_t*  //
reader_pointer()3017 wuffs_base__io_buffer::reader_pointer() const {
3018   return wuffs_base__io_buffer__reader_pointer(this);
3019 }
3020 
3021 inline uint64_t  //
reader_position()3022 wuffs_base__io_buffer::reader_position() const {
3023   return wuffs_base__io_buffer__reader_position(this);
3024 }
3025 
3026 inline wuffs_base__slice_u8  //
reader_slice()3027 wuffs_base__io_buffer::reader_slice() const {
3028   return wuffs_base__io_buffer__reader_slice(this);
3029 }
3030 
3031 inline uint64_t  //
writer_io_position()3032 wuffs_base__io_buffer::writer_io_position() const {
3033   return wuffs_base__io_buffer__writer_io_position(this);
3034 }
3035 
3036 inline size_t  //
writer_length()3037 wuffs_base__io_buffer::writer_length() const {
3038   return wuffs_base__io_buffer__writer_length(this);
3039 }
3040 
3041 inline uint8_t*  //
writer_pointer()3042 wuffs_base__io_buffer::writer_pointer() const {
3043   return wuffs_base__io_buffer__writer_pointer(this);
3044 }
3045 
3046 inline uint64_t  //
writer_position()3047 wuffs_base__io_buffer::writer_position() const {
3048   return wuffs_base__io_buffer__writer_position(this);
3049 }
3050 
3051 inline wuffs_base__slice_u8  //
writer_slice()3052 wuffs_base__io_buffer::writer_slice() const {
3053   return wuffs_base__io_buffer__writer_slice(this);
3054 }
3055 
3056 #endif  // __cplusplus
3057 
3058 // ---------------- Tokens
3059 
3060 // wuffs_base__token is an element of a byte stream's tokenization.
3061 //
3062 // See https://github.com/google/wuffs/blob/main/doc/note/tokens.md
3063 typedef struct wuffs_base__token__struct {
3064   uint64_t repr;
3065 
3066 #ifdef __cplusplus
3067   inline int64_t value() const;
3068   inline int64_t value_extension() const;
3069   inline int64_t value_major() const;
3070   inline int64_t value_base_category() const;
3071   inline uint64_t value_minor() const;
3072   inline uint64_t value_base_detail() const;
3073   inline int64_t value_base_detail__sign_extended() const;
3074   inline bool continued() const;
3075   inline uint64_t length() const;
3076 #endif  // __cplusplus
3077 
3078 } wuffs_base__token;
3079 
3080 static inline wuffs_base__token  //
wuffs_base__make_token(uint64_t repr)3081 wuffs_base__make_token(uint64_t repr) {
3082   wuffs_base__token ret;
3083   ret.repr = repr;
3084   return ret;
3085 }
3086 
3087 // --------
3088 
3089 #define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF
3090 
3091 #define WUFFS_BASE__TOKEN__VALUE__SHIFT 17
3092 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17
3093 #define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42
3094 #define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17
3095 #define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38
3096 #define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17
3097 #define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16
3098 #define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0
3099 
3100 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46
3101 
3102 // --------
3103 
3104 #define WUFFS_BASE__TOKEN__VBC__FILLER 0
3105 #define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1
3106 #define WUFFS_BASE__TOKEN__VBC__STRING 2
3107 #define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3
3108 #define WUFFS_BASE__TOKEN__VBC__LITERAL 4
3109 #define WUFFS_BASE__TOKEN__VBC__NUMBER 5
3110 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6
3111 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED 7
3112 
3113 // --------
3114 
3115 #define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001
3116 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002
3117 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004
3118 
3119 // COMMENT_ANY is a bit-wise or of COMMENT_BLOCK AND COMMENT_LINE.
3120 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006
3121 
3122 // --------
3123 
3124 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001
3125 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002
3126 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010
3127 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020
3128 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040
3129 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000
3130 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000
3131 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000
3132 
3133 // --------
3134 
3135 // DEFINITELY_FOO means that the destination bytes (and also the source bytes,
3136 // for 1_DST_1_SRC_COPY) are in the FOO format. Definitely means that the lack
3137 // of the bit means "maybe FOO". It does not necessarily mean "not FOO".
3138 //
3139 // CHAIN_ETC means that decoding the entire token chain forms a UTF-8 or ASCII
3140 // string, not just this current token. CHAIN_ETC_UTF_8 therefore distinguishes
3141 // Unicode (UTF-8) strings from byte strings. MUST means that the the token
3142 // producer (e.g. parser) must verify this. SHOULD means that the token
3143 // consumer (e.g. renderer) should verify this.
3144 //
3145 // When a CHAIN_ETC_UTF_8 bit is set, the parser must ensure that non-ASCII
3146 // code points (with multi-byte UTF-8 encodings) do not straddle token
3147 // boundaries. Checking UTF-8 validity can inspect each token separately.
3148 //
3149 // The lack of any particular bit is conservative: it is valid for all-ASCII
3150 // strings, in a single- or multi-token chain, to have none of these bits set.
3151 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001
3152 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002
3153 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_UTF_8 0x00004
3154 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010
3155 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020
3156 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_ASCII 0x00040
3157 
3158 // CONVERT_D_DST_S_SRC means that multiples of S source bytes (possibly padded)
3159 // produces multiples of D destination bytes. For example,
3160 // CONVERT_1_DST_4_SRC_BACKSLASH_X means a source like "\\x23\\x67\\xAB", where
3161 // 12 src bytes encode 3 dst bytes.
3162 //
3163 // Post-processing may further transform those D destination bytes (e.g. treat
3164 // "\\xFF" as the Unicode code point U+00FF instead of the byte 0xFF), but that
3165 // is out of scope of this VBD's semantics.
3166 //
3167 // When src is the empty string, multiple conversion algorithms are applicable
3168 // (so these bits are not necessarily mutually exclusive), all producing the
3169 // same empty dst string.
3170 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100
3171 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200
3172 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00400
3173 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00800
3174 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x01000
3175 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x02000
3176 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000
3177 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_HEX 0x08000
3178 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_STD 0x10000
3179 
3180 // --------
3181 
3182 #define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001
3183 #define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002
3184 #define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004
3185 #define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008
3186 
3187 // --------
3188 
3189 // For a source string of "123" or "0x9A", it is valid for a tokenizer to
3190 // return any combination of:
3191 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT.
3192 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED.
3193 //  - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED.
3194 //
3195 // For a source string of "+123" or "-0x9A", only the first two are valid.
3196 //
3197 // For a source string of "123.", only the first one is valid.
3198 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001
3199 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002
3200 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004
3201 
3202 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010
3203 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF 0x00020
3204 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN 0x00040
3205 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN 0x00080
3206 
3207 // The number 300 might be represented as "\x01\x2C", "\x2C\x01\x00\x00" or
3208 // "300", which are big-endian, little-endian or text. For binary formats, the
3209 // token length (after adjusting for FORMAT_IGNORE_ETC) discriminates
3210 // e.g. u16 little-endian vs u32 little-endian.
3211 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100
3212 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200
3213 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400
3214 
3215 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000
3216 
3217 // --------
3218 
3219 // wuffs_base__token__value returns the token's high 46 bits, sign-extended. A
3220 // negative value means an extended token, non-negative means a simple token.
3221 static inline int64_t  //
wuffs_base__token__value(const wuffs_base__token * t)3222 wuffs_base__token__value(const wuffs_base__token* t) {
3223   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE__SHIFT;
3224 }
3225 
3226 // wuffs_base__token__value_extension returns a negative value if the token was
3227 // not an extended token.
3228 static inline int64_t  //
wuffs_base__token__value_extension(const wuffs_base__token * t)3229 wuffs_base__token__value_extension(const wuffs_base__token* t) {
3230   return (~(int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT;
3231 }
3232 
3233 // wuffs_base__token__value_major returns a negative value if the token was not
3234 // a simple token.
3235 static inline int64_t  //
wuffs_base__token__value_major(const wuffs_base__token * t)3236 wuffs_base__token__value_major(const wuffs_base__token* t) {
3237   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT;
3238 }
3239 
3240 // wuffs_base__token__value_base_category returns a negative value if the token
3241 // was not a simple token.
3242 static inline int64_t  //
wuffs_base__token__value_base_category(const wuffs_base__token * t)3243 wuffs_base__token__value_base_category(const wuffs_base__token* t) {
3244   return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT;
3245 }
3246 
3247 static inline uint64_t  //
wuffs_base__token__value_minor(const wuffs_base__token * t)3248 wuffs_base__token__value_minor(const wuffs_base__token* t) {
3249   return (t->repr >> WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) & 0x1FFFFFF;
3250 }
3251 
3252 static inline uint64_t  //
wuffs_base__token__value_base_detail(const wuffs_base__token * t)3253 wuffs_base__token__value_base_detail(const wuffs_base__token* t) {
3254   return (t->repr >> WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) & 0x1FFFFF;
3255 }
3256 
3257 static inline int64_t  //
wuffs_base__token__value_base_detail__sign_extended(const wuffs_base__token * t)3258 wuffs_base__token__value_base_detail__sign_extended(
3259     const wuffs_base__token* t) {
3260   // The VBD is 21 bits in the middle of t->repr. Left shift the high (64 - 21
3261   // - ETC__SHIFT) bits off, then right shift (sign-extending) back down.
3262   uint64_t u = t->repr << (43 - WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT);
3263   return ((int64_t)u) >> 43;
3264 }
3265 
3266 static inline bool  //
wuffs_base__token__continued(const wuffs_base__token * t)3267 wuffs_base__token__continued(const wuffs_base__token* t) {
3268   return t->repr & 0x10000;
3269 }
3270 
3271 static inline uint64_t  //
wuffs_base__token__length(const wuffs_base__token * t)3272 wuffs_base__token__length(const wuffs_base__token* t) {
3273   return (t->repr >> WUFFS_BASE__TOKEN__LENGTH__SHIFT) & 0xFFFF;
3274 }
3275 
3276 #ifdef __cplusplus
3277 
3278 inline int64_t  //
value()3279 wuffs_base__token::value() const {
3280   return wuffs_base__token__value(this);
3281 }
3282 
3283 inline int64_t  //
value_extension()3284 wuffs_base__token::value_extension() const {
3285   return wuffs_base__token__value_extension(this);
3286 }
3287 
3288 inline int64_t  //
value_major()3289 wuffs_base__token::value_major() const {
3290   return wuffs_base__token__value_major(this);
3291 }
3292 
3293 inline int64_t  //
value_base_category()3294 wuffs_base__token::value_base_category() const {
3295   return wuffs_base__token__value_base_category(this);
3296 }
3297 
3298 inline uint64_t  //
value_minor()3299 wuffs_base__token::value_minor() const {
3300   return wuffs_base__token__value_minor(this);
3301 }
3302 
3303 inline uint64_t  //
value_base_detail()3304 wuffs_base__token::value_base_detail() const {
3305   return wuffs_base__token__value_base_detail(this);
3306 }
3307 
3308 inline int64_t  //
value_base_detail__sign_extended()3309 wuffs_base__token::value_base_detail__sign_extended() const {
3310   return wuffs_base__token__value_base_detail__sign_extended(this);
3311 }
3312 
3313 inline bool  //
continued()3314 wuffs_base__token::continued() const {
3315   return wuffs_base__token__continued(this);
3316 }
3317 
3318 inline uint64_t  //
length()3319 wuffs_base__token::length() const {
3320   return wuffs_base__token__length(this);
3321 }
3322 
3323 #endif  // __cplusplus
3324 
3325 // --------
3326 
3327 typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token;
3328 
3329 static inline wuffs_base__slice_token  //
wuffs_base__make_slice_token(wuffs_base__token * ptr,size_t len)3330 wuffs_base__make_slice_token(wuffs_base__token* ptr, size_t len) {
3331   wuffs_base__slice_token ret;
3332   ret.ptr = ptr;
3333   ret.len = len;
3334   return ret;
3335 }
3336 
3337 static inline wuffs_base__slice_token  //
wuffs_base__empty_slice_token()3338 wuffs_base__empty_slice_token() {
3339   wuffs_base__slice_token ret;
3340   ret.ptr = NULL;
3341   ret.len = 0;
3342   return ret;
3343 }
3344 
3345 // --------
3346 
3347 // wuffs_base__token_buffer_meta is the metadata for a
3348 // wuffs_base__token_buffer's data.
3349 typedef struct wuffs_base__token_buffer_meta__struct {
3350   size_t wi;     // Write index. Invariant: wi <= len.
3351   size_t ri;     // Read  index. Invariant: ri <= wi.
3352   uint64_t pos;  // Position of the buffer start relative to the stream start.
3353   bool closed;   // No further writes are expected.
3354 } wuffs_base__token_buffer_meta;
3355 
3356 // wuffs_base__token_buffer is a 1-dimensional buffer (a pointer and length)
3357 // plus additional metadata.
3358 //
3359 // A value with all fields zero is a valid, empty buffer.
3360 typedef struct wuffs_base__token_buffer__struct {
3361   wuffs_base__slice_token data;
3362   wuffs_base__token_buffer_meta meta;
3363 
3364 #ifdef __cplusplus
3365   inline bool is_valid() const;
3366   inline void compact();
3367   inline uint64_t reader_length() const;
3368   inline wuffs_base__token* reader_pointer() const;
3369   inline wuffs_base__slice_token reader_slice() const;
3370   inline uint64_t reader_token_position() const;
3371   inline uint64_t writer_length() const;
3372   inline uint64_t writer_token_position() const;
3373   inline wuffs_base__token* writer_pointer() const;
3374   inline wuffs_base__slice_token writer_slice() const;
3375 #endif  // __cplusplus
3376 
3377 } wuffs_base__token_buffer;
3378 
3379 static inline wuffs_base__token_buffer  //
wuffs_base__make_token_buffer(wuffs_base__slice_token data,wuffs_base__token_buffer_meta meta)3380 wuffs_base__make_token_buffer(wuffs_base__slice_token data,
3381                               wuffs_base__token_buffer_meta meta) {
3382   wuffs_base__token_buffer ret;
3383   ret.data = data;
3384   ret.meta = meta;
3385   return ret;
3386 }
3387 
3388 static inline wuffs_base__token_buffer_meta  //
wuffs_base__make_token_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)3389 wuffs_base__make_token_buffer_meta(size_t wi,
3390                                    size_t ri,
3391                                    uint64_t pos,
3392                                    bool closed) {
3393   wuffs_base__token_buffer_meta ret;
3394   ret.wi = wi;
3395   ret.ri = ri;
3396   ret.pos = pos;
3397   ret.closed = closed;
3398   return ret;
3399 }
3400 
3401 static inline wuffs_base__token_buffer  //
wuffs_base__slice_token__reader(wuffs_base__slice_token s,bool closed)3402 wuffs_base__slice_token__reader(wuffs_base__slice_token s, bool closed) {
3403   wuffs_base__token_buffer ret;
3404   ret.data.ptr = s.ptr;
3405   ret.data.len = s.len;
3406   ret.meta.wi = s.len;
3407   ret.meta.ri = 0;
3408   ret.meta.pos = 0;
3409   ret.meta.closed = closed;
3410   return ret;
3411 }
3412 
3413 static inline wuffs_base__token_buffer  //
wuffs_base__slice_token__writer(wuffs_base__slice_token s)3414 wuffs_base__slice_token__writer(wuffs_base__slice_token s) {
3415   wuffs_base__token_buffer ret;
3416   ret.data.ptr = s.ptr;
3417   ret.data.len = s.len;
3418   ret.meta.wi = 0;
3419   ret.meta.ri = 0;
3420   ret.meta.pos = 0;
3421   ret.meta.closed = false;
3422   return ret;
3423 }
3424 
3425 static inline wuffs_base__token_buffer  //
wuffs_base__empty_token_buffer()3426 wuffs_base__empty_token_buffer() {
3427   wuffs_base__token_buffer ret;
3428   ret.data.ptr = NULL;
3429   ret.data.len = 0;
3430   ret.meta.wi = 0;
3431   ret.meta.ri = 0;
3432   ret.meta.pos = 0;
3433   ret.meta.closed = false;
3434   return ret;
3435 }
3436 
3437 static inline wuffs_base__token_buffer_meta  //
wuffs_base__empty_token_buffer_meta()3438 wuffs_base__empty_token_buffer_meta() {
3439   wuffs_base__token_buffer_meta ret;
3440   ret.wi = 0;
3441   ret.ri = 0;
3442   ret.pos = 0;
3443   ret.closed = false;
3444   return ret;
3445 }
3446 
3447 static inline bool  //
wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer * buf)3448 wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer* buf) {
3449   if (buf) {
3450     if (buf->data.ptr) {
3451       return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
3452     } else {
3453       return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
3454     }
3455   }
3456   return false;
3457 }
3458 
3459 // wuffs_base__token_buffer__compact moves any written but unread tokens to the
3460 // start of the buffer.
3461 static inline void  //
wuffs_base__token_buffer__compact(wuffs_base__token_buffer * buf)3462 wuffs_base__token_buffer__compact(wuffs_base__token_buffer* buf) {
3463   if (!buf || (buf->meta.ri == 0)) {
3464     return;
3465   }
3466   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
3467   size_t n = buf->meta.wi - buf->meta.ri;
3468   if (n != 0) {
3469     memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri,
3470             n * sizeof(wuffs_base__token));
3471   }
3472   buf->meta.wi = n;
3473   buf->meta.ri = 0;
3474 }
3475 
3476 static inline uint64_t  //
wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer * buf)3477 wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer* buf) {
3478   return buf ? buf->meta.wi - buf->meta.ri : 0;
3479 }
3480 
3481 static inline wuffs_base__token*  //
wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer * buf)3482 wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer* buf) {
3483   return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
3484 }
3485 
3486 static inline wuffs_base__slice_token  //
wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer * buf)3487 wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer* buf) {
3488   return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.ri,
3489                                             buf->meta.wi - buf->meta.ri)
3490              : wuffs_base__empty_slice_token();
3491 }
3492 
3493 static inline uint64_t  //
wuffs_base__token_buffer__reader_token_position(const wuffs_base__token_buffer * buf)3494 wuffs_base__token_buffer__reader_token_position(
3495     const wuffs_base__token_buffer* buf) {
3496   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
3497 }
3498 
3499 static inline uint64_t  //
wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer * buf)3500 wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer* buf) {
3501   return buf ? buf->data.len - buf->meta.wi : 0;
3502 }
3503 
3504 static inline wuffs_base__token*  //
wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer * buf)3505 wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer* buf) {
3506   return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
3507 }
3508 
3509 static inline wuffs_base__slice_token  //
wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer * buf)3510 wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer* buf) {
3511   return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.wi,
3512                                             buf->data.len - buf->meta.wi)
3513              : wuffs_base__empty_slice_token();
3514 }
3515 
3516 static inline uint64_t  //
wuffs_base__token_buffer__writer_token_position(const wuffs_base__token_buffer * buf)3517 wuffs_base__token_buffer__writer_token_position(
3518     const wuffs_base__token_buffer* buf) {
3519   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
3520 }
3521 
3522 #ifdef __cplusplus
3523 
3524 inline bool  //
is_valid()3525 wuffs_base__token_buffer::is_valid() const {
3526   return wuffs_base__token_buffer__is_valid(this);
3527 }
3528 
3529 inline void  //
compact()3530 wuffs_base__token_buffer::compact() {
3531   wuffs_base__token_buffer__compact(this);
3532 }
3533 
3534 inline uint64_t  //
reader_length()3535 wuffs_base__token_buffer::reader_length() const {
3536   return wuffs_base__token_buffer__reader_length(this);
3537 }
3538 
3539 inline wuffs_base__token*  //
reader_pointer()3540 wuffs_base__token_buffer::reader_pointer() const {
3541   return wuffs_base__token_buffer__reader_pointer(this);
3542 }
3543 
3544 inline wuffs_base__slice_token  //
reader_slice()3545 wuffs_base__token_buffer::reader_slice() const {
3546   return wuffs_base__token_buffer__reader_slice(this);
3547 }
3548 
3549 inline uint64_t  //
reader_token_position()3550 wuffs_base__token_buffer::reader_token_position() const {
3551   return wuffs_base__token_buffer__reader_token_position(this);
3552 }
3553 
3554 inline uint64_t  //
writer_length()3555 wuffs_base__token_buffer::writer_length() const {
3556   return wuffs_base__token_buffer__writer_length(this);
3557 }
3558 
3559 inline wuffs_base__token*  //
writer_pointer()3560 wuffs_base__token_buffer::writer_pointer() const {
3561   return wuffs_base__token_buffer__writer_pointer(this);
3562 }
3563 
3564 inline wuffs_base__slice_token  //
writer_slice()3565 wuffs_base__token_buffer::writer_slice() const {
3566   return wuffs_base__token_buffer__writer_slice(this);
3567 }
3568 
3569 inline uint64_t  //
writer_token_position()3570 wuffs_base__token_buffer::writer_token_position() const {
3571   return wuffs_base__token_buffer__writer_token_position(this);
3572 }
3573 
3574 #endif  // __cplusplus
3575 
3576 // ---------------- Memory Allocation
3577 
3578 // The memory allocation related functions in this section aren't used by Wuffs
3579 // per se, but they may be helpful to the code that uses Wuffs.
3580 
3581 // wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except
3582 // that it takes a uint64_t number of elements instead of a size_t size in
3583 // bytes, and it returns a slice (a pointer and a length) instead of just a
3584 // pointer.
3585 //
3586 // You can pass the C stdlib's malloc as the malloc_func.
3587 //
3588 // It returns an empty slice (containing a NULL ptr field) if (num_uxx *
3589 // sizeof(uintxx_t)) would overflow SIZE_MAX.
3590 
3591 static inline wuffs_base__slice_u8  //
wuffs_base__malloc_slice_u8(void * (* malloc_func)(size_t),uint64_t num_u8)3592 wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) {
3593   if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) {
3594     void* p = (*malloc_func)((size_t)(num_u8 * sizeof(uint8_t)));
3595     if (p) {
3596       return wuffs_base__make_slice_u8((uint8_t*)(p), (size_t)num_u8);
3597     }
3598   }
3599   return wuffs_base__make_slice_u8(NULL, 0);
3600 }
3601 
3602 static inline wuffs_base__slice_u16  //
wuffs_base__malloc_slice_u16(void * (* malloc_func)(size_t),uint64_t num_u16)3603 wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) {
3604   if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) {
3605     void* p = (*malloc_func)((size_t)(num_u16 * sizeof(uint16_t)));
3606     if (p) {
3607       return wuffs_base__make_slice_u16((uint16_t*)(p), (size_t)num_u16);
3608     }
3609   }
3610   return wuffs_base__make_slice_u16(NULL, 0);
3611 }
3612 
3613 static inline wuffs_base__slice_u32  //
wuffs_base__malloc_slice_u32(void * (* malloc_func)(size_t),uint64_t num_u32)3614 wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) {
3615   if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) {
3616     void* p = (*malloc_func)((size_t)(num_u32 * sizeof(uint32_t)));
3617     if (p) {
3618       return wuffs_base__make_slice_u32((uint32_t*)(p), (size_t)num_u32);
3619     }
3620   }
3621   return wuffs_base__make_slice_u32(NULL, 0);
3622 }
3623 
3624 static inline wuffs_base__slice_u64  //
wuffs_base__malloc_slice_u64(void * (* malloc_func)(size_t),uint64_t num_u64)3625 wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) {
3626   if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) {
3627     void* p = (*malloc_func)((size_t)(num_u64 * sizeof(uint64_t)));
3628     if (p) {
3629       return wuffs_base__make_slice_u64((uint64_t*)(p), (size_t)num_u64);
3630     }
3631   }
3632   return wuffs_base__make_slice_u64(NULL, 0);
3633 }
3634 
3635 // ---------------- Images
3636 
3637 // wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
3638 // Alpha, Red, Green, Blue color, as a uint32_t value. Its value is always
3639 // 0xAARRGGBB (Alpha most significant, Blue least), regardless of endianness.
3640 typedef uint32_t wuffs_base__color_u32_argb_premul;
3641 
3642 // wuffs_base__color_u32_argb_premul__is_valid returns whether c's Red, Green
3643 // and Blue channels are all less than or equal to its Alpha channel. c uses
3644 // premultiplied alpha, so 50% opaque 100% saturated red is 0x7F7F_0000 and a
3645 // value like 0x7F80_0000 is invalid.
3646 static inline bool  //
wuffs_base__color_u32_argb_premul__is_valid(wuffs_base__color_u32_argb_premul c)3647 wuffs_base__color_u32_argb_premul__is_valid(
3648     wuffs_base__color_u32_argb_premul c) {
3649   uint32_t a = 0xFF & (c >> 24);
3650   uint32_t r = 0xFF & (c >> 16);
3651   uint32_t g = 0xFF & (c >> 8);
3652   uint32_t b = 0xFF & (c >> 0);
3653   return (a >= r) && (a >= g) && (a >= b);
3654 }
3655 
3656 static inline uint16_t  //
wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(wuffs_base__color_u32_argb_premul c)3657 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
3658     wuffs_base__color_u32_argb_premul c) {
3659   uint32_t r5 = 0xF800 & (c >> 8);
3660   uint32_t g6 = 0x07E0 & (c >> 5);
3661   uint32_t b5 = 0x001F & (c >> 3);
3662   return (uint16_t)(r5 | g6 | b5);
3663 }
3664 
3665 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565)3666 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565) {
3667   uint32_t b5 = 0x1F & (rgb_565 >> 0);
3668   uint32_t b = (b5 << 3) | (b5 >> 2);
3669   uint32_t g6 = 0x3F & (rgb_565 >> 5);
3670   uint32_t g = (g6 << 2) | (g6 >> 4);
3671   uint32_t r5 = 0x1F & (rgb_565 >> 11);
3672   uint32_t r = (r5 << 3) | (r5 >> 2);
3673   return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
3674 }
3675 
3676 static inline uint8_t  //
wuffs_base__color_u32_argb_premul__as__color_u8_gray(wuffs_base__color_u32_argb_premul c)3677 wuffs_base__color_u32_argb_premul__as__color_u8_gray(
3678     wuffs_base__color_u32_argb_premul c) {
3679   // Work in 16-bit color.
3680   uint32_t cr = 0x101 * (0xFF & (c >> 16));
3681   uint32_t cg = 0x101 * (0xFF & (c >> 8));
3682   uint32_t cb = 0x101 * (0xFF & (c >> 0));
3683 
3684   // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3685   // as those given by the JFIF specification.
3686   //
3687   // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16). We
3688   // shift by 24, not just by 16, because the return value is 8-bit color, not
3689   // 16-bit color.
3690   uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3691   return (uint8_t)(weighted_average >> 24);
3692 }
3693 
3694 static inline uint16_t  //
wuffs_base__color_u32_argb_premul__as__color_u16_gray(wuffs_base__color_u32_argb_premul c)3695 wuffs_base__color_u32_argb_premul__as__color_u16_gray(
3696     wuffs_base__color_u32_argb_premul c) {
3697   // Work in 16-bit color.
3698   uint32_t cr = 0x101 * (0xFF & (c >> 16));
3699   uint32_t cg = 0x101 * (0xFF & (c >> 8));
3700   uint32_t cb = 0x101 * (0xFF & (c >> 0));
3701 
3702   // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3703   // as those given by the JFIF specification.
3704   //
3705   // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16).
3706   uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3707   return (uint16_t)(weighted_average >> 16);
3708 }
3709 
3710 // wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul converts
3711 // from non-premultiplied alpha to premultiplied alpha.
3712 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(uint32_t argb_nonpremul)3713 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
3714     uint32_t argb_nonpremul) {
3715   // Multiplying by 0x101 (twice, once for alpha and once for color) converts
3716   // from 8-bit to 16-bit color. Shifting right by 8 undoes that.
3717   //
3718   // Working in the higher bit depth can produce slightly different (and
3719   // arguably slightly more accurate) results. For example, given 8-bit blue
3720   // and alpha of 0x80 and 0x81:
3721   //
3722   //  - ((0x80   * 0x81  ) / 0xFF  )      = 0x40        = 0x40
3723   //  - ((0x8080 * 0x8181) / 0xFFFF) >> 8 = 0x4101 >> 8 = 0x41
3724   uint32_t a = 0xFF & (argb_nonpremul >> 24);
3725   uint32_t a16 = a * (0x101 * 0x101);
3726 
3727   uint32_t r = 0xFF & (argb_nonpremul >> 16);
3728   r = ((r * a16) / 0xFFFF) >> 8;
3729   uint32_t g = 0xFF & (argb_nonpremul >> 8);
3730   g = ((g * a16) / 0xFFFF) >> 8;
3731   uint32_t b = 0xFF & (argb_nonpremul >> 0);
3732   b = ((b * a16) / 0xFFFF) >> 8;
3733 
3734   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3735 }
3736 
3737 // wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul converts
3738 // from premultiplied alpha to non-premultiplied alpha.
3739 static inline uint32_t  //
wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3740 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
3741     wuffs_base__color_u32_argb_premul c) {
3742   uint32_t a = 0xFF & (c >> 24);
3743   if (a == 0xFF) {
3744     return c;
3745   } else if (a == 0) {
3746     return 0;
3747   }
3748   uint32_t a16 = a * 0x101;
3749 
3750   uint32_t r = 0xFF & (c >> 16);
3751   r = ((r * (0x101 * 0xFFFF)) / a16) >> 8;
3752   uint32_t g = 0xFF & (c >> 8);
3753   g = ((g * (0x101 * 0xFFFF)) / a16) >> 8;
3754   uint32_t b = 0xFF & (c >> 0);
3755   b = ((b * (0x101 * 0xFFFF)) / a16) >> 8;
3756 
3757   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3758 }
3759 
3760 // wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul converts
3761 // from 4x16LE non-premultiplied alpha to 4x8 premultiplied alpha.
3762 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(uint64_t argb_nonpremul)3763 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
3764     uint64_t argb_nonpremul) {
3765   uint32_t a16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 48)));
3766 
3767   uint32_t r16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 32)));
3768   r16 = (r16 * a16) / 0xFFFF;
3769   uint32_t g16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 16)));
3770   g16 = (g16 * a16) / 0xFFFF;
3771   uint32_t b16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 0)));
3772   b16 = (b16 * a16) / 0xFFFF;
3773 
3774   return ((a16 >> 8) << 24) | ((r16 >> 8) << 16) | ((g16 >> 8) << 8) |
3775          ((b16 >> 8) << 0);
3776 }
3777 
3778 // wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul converts
3779 // from 4x8 premultiplied alpha to 4x16LE non-premultiplied alpha.
3780 static inline uint64_t  //
wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3781 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
3782     wuffs_base__color_u32_argb_premul c) {
3783   uint32_t a = 0xFF & (c >> 24);
3784   if (a == 0xFF) {
3785     uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3786     uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3787     uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3788     return 0xFFFF000000000000u | (r16 << 32) | (g16 << 16) | (b16 << 0);
3789   } else if (a == 0) {
3790     return 0;
3791   }
3792   uint64_t a16 = a * 0x101;
3793 
3794   uint64_t r = 0xFF & (c >> 16);
3795   uint64_t r16 = (r * (0x101 * 0xFFFF)) / a16;
3796   uint64_t g = 0xFF & (c >> 8);
3797   uint64_t g16 = (g * (0x101 * 0xFFFF)) / a16;
3798   uint64_t b = 0xFF & (c >> 0);
3799   uint64_t b16 = (b * (0x101 * 0xFFFF)) / a16;
3800 
3801   return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3802 }
3803 
3804 static inline uint64_t  //
wuffs_base__color_u32__as__color_u64(uint32_t c)3805 wuffs_base__color_u32__as__color_u64(uint32_t c) {
3806   uint64_t a16 = 0x101 * (0xFF & (c >> 24));
3807   uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3808   uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3809   uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3810   return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3811 }
3812 
3813 static inline uint32_t  //
wuffs_base__color_u64__as__color_u32(uint64_t c)3814 wuffs_base__color_u64__as__color_u32(uint64_t c) {
3815   uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
3816   uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
3817   uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
3818   uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
3819   return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3820 }
3821 
3822 // --------
3823 
3824 typedef uint8_t wuffs_base__pixel_blend;
3825 
3826 // wuffs_base__pixel_blend encodes how to blend source and destination pixels,
3827 // accounting for transparency. It encompasses the Porter-Duff compositing
3828 // operators as well as the other blending modes defined by PDF.
3829 //
3830 // TODO: implement the other modes.
3831 #define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
3832 #define WUFFS_BASE__PIXEL_BLEND__SRC_OVER ((wuffs_base__pixel_blend)1)
3833 
3834 // --------
3835 
3836 // wuffs_base__pixel_alpha_transparency is a pixel format's alpha channel
3837 // model. It is a property of the pixel format in general, not of a specific
3838 // pixel. An RGBA pixel format (with alpha) can still have fully opaque pixels.
3839 typedef uint32_t wuffs_base__pixel_alpha_transparency;
3840 
3841 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE 0
3842 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA 1
3843 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__PREMULTIPLIED_ALPHA 2
3844 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__BINARY_ALPHA 3
3845 
3846 // Deprecated: use WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA
3847 // instead.
3848 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NON_PREMULTIPLIED_ALPHA 1
3849 
3850 // --------
3851 
3852 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
3853 
3854 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
3855 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
3856 
3857 // A palette is 256 entries × 4 bytes per entry (e.g. BGRA).
3858 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH 1024
3859 
3860 // wuffs_base__pixel_format encodes the format of the bytes that constitute an
3861 // image frame's pixel data.
3862 //
3863 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-formats.md
3864 //
3865 // Do not manipulate its bits directly; they are private implementation
3866 // details. Use methods such as wuffs_base__pixel_format__num_planes instead.
3867 typedef struct wuffs_base__pixel_format__struct {
3868   uint32_t repr;
3869 
3870 #ifdef __cplusplus
3871   inline bool is_valid() const;
3872   inline uint32_t bits_per_pixel() const;
3873   inline bool is_direct() const;
3874   inline bool is_indexed() const;
3875   inline bool is_interleaved() const;
3876   inline bool is_planar() const;
3877   inline uint32_t num_planes() const;
3878   inline wuffs_base__pixel_alpha_transparency transparency() const;
3879 #endif  // __cplusplus
3880 
3881 } wuffs_base__pixel_format;
3882 
3883 static inline wuffs_base__pixel_format  //
wuffs_base__make_pixel_format(uint32_t repr)3884 wuffs_base__make_pixel_format(uint32_t repr) {
3885   wuffs_base__pixel_format f;
3886   f.repr = repr;
3887   return f;
3888 }
3889 
3890 // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid
3891 // wuffs_base__pixel_format values are present.
3892 
3893 #define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000
3894 
3895 #define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008
3896 
3897 #define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008
3898 #define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B
3899 #define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B
3900 #define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000008
3901 #define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000008
3902 
3903 #define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888
3904 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888
3905 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888
3906 
3907 #define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888
3908 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888
3909 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888
3910 
3911 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008
3912 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008
3913 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008
3914 
3915 #define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565
3916 #define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888
3917 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888
3918 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB
3919 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888
3920 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB
3921 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888
3922 #define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888
3923 
3924 #define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888
3925 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888
3926 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB
3927 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888
3928 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB
3929 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888
3930 #define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888
3931 
3932 #define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888
3933 #define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888
3934 
3935 extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];
3936 
3937 static inline bool  //
wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format * f)3938 wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {
3939   return f->repr != 0;
3940 }
3941 
3942 // wuffs_base__pixel_format__bits_per_pixel returns the number of bits per
3943 // pixel for interleaved pixel formats, and returns 0 for planar pixel formats.
3944 static inline uint32_t  //
wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format * f)3945 wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) {
3946   if (((f->repr >> 16) & 0x03) != 0) {
3947     return 0;
3948   }
3949   return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] +
3950          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] +
3951          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 8)] +
3952          wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 12)];
3953 }
3954 
3955 static inline bool  //
wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format * f)3956 wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format* f) {
3957   return ((f->repr >> 18) & 0x01) == 0;
3958 }
3959 
3960 static inline bool  //
wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format * f)3961 wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format* f) {
3962   return ((f->repr >> 18) & 0x01) != 0;
3963 }
3964 
3965 static inline bool  //
wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format * f)3966 wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format* f) {
3967   return ((f->repr >> 16) & 0x03) == 0;
3968 }
3969 
3970 static inline bool  //
wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format * f)3971 wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format* f) {
3972   return ((f->repr >> 16) & 0x03) != 0;
3973 }
3974 
3975 static inline uint32_t  //
wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format * f)3976 wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format* f) {
3977   return ((f->repr >> 16) & 0x03) + 1;
3978 }
3979 
3980 static inline wuffs_base__pixel_alpha_transparency  //
wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format * f)3981 wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format* f) {
3982   return (wuffs_base__pixel_alpha_transparency)((f->repr >> 24) & 0x03);
3983 }
3984 
3985 #ifdef __cplusplus
3986 
3987 inline bool  //
is_valid()3988 wuffs_base__pixel_format::is_valid() const {
3989   return wuffs_base__pixel_format__is_valid(this);
3990 }
3991 
3992 inline uint32_t  //
bits_per_pixel()3993 wuffs_base__pixel_format::bits_per_pixel() const {
3994   return wuffs_base__pixel_format__bits_per_pixel(this);
3995 }
3996 
3997 inline bool  //
is_direct()3998 wuffs_base__pixel_format::is_direct() const {
3999   return wuffs_base__pixel_format__is_direct(this);
4000 }
4001 
4002 inline bool  //
is_indexed()4003 wuffs_base__pixel_format::is_indexed() const {
4004   return wuffs_base__pixel_format__is_indexed(this);
4005 }
4006 
4007 inline bool  //
is_interleaved()4008 wuffs_base__pixel_format::is_interleaved() const {
4009   return wuffs_base__pixel_format__is_interleaved(this);
4010 }
4011 
4012 inline bool  //
is_planar()4013 wuffs_base__pixel_format::is_planar() const {
4014   return wuffs_base__pixel_format__is_planar(this);
4015 }
4016 
4017 inline uint32_t  //
num_planes()4018 wuffs_base__pixel_format::num_planes() const {
4019   return wuffs_base__pixel_format__num_planes(this);
4020 }
4021 
4022 inline wuffs_base__pixel_alpha_transparency  //
transparency()4023 wuffs_base__pixel_format::transparency() const {
4024   return wuffs_base__pixel_format__transparency(this);
4025 }
4026 
4027 #endif  // __cplusplus
4028 
4029 // --------
4030 
4031 // wuffs_base__pixel_subsampling encodes whether sample values cover one pixel
4032 // or cover multiple pixels.
4033 //
4034 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-subsampling.md
4035 //
4036 // Do not manipulate its bits directly; they are private implementation
4037 // details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead.
4038 typedef struct wuffs_base__pixel_subsampling__struct {
4039   uint32_t repr;
4040 
4041 #ifdef __cplusplus
4042   inline uint32_t bias_x(uint32_t plane) const;
4043   inline uint32_t denominator_x(uint32_t plane) const;
4044   inline uint32_t bias_y(uint32_t plane) const;
4045   inline uint32_t denominator_y(uint32_t plane) const;
4046 #endif  // __cplusplus
4047 
4048 } wuffs_base__pixel_subsampling;
4049 
4050 static inline wuffs_base__pixel_subsampling  //
wuffs_base__make_pixel_subsampling(uint32_t repr)4051 wuffs_base__make_pixel_subsampling(uint32_t repr) {
4052   wuffs_base__pixel_subsampling s;
4053   s.repr = repr;
4054   return s;
4055 }
4056 
4057 #define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE 0x00000000
4058 
4059 #define WUFFS_BASE__PIXEL_SUBSAMPLING__444 0x000000
4060 #define WUFFS_BASE__PIXEL_SUBSAMPLING__440 0x010100
4061 #define WUFFS_BASE__PIXEL_SUBSAMPLING__422 0x101000
4062 #define WUFFS_BASE__PIXEL_SUBSAMPLING__420 0x111100
4063 #define WUFFS_BASE__PIXEL_SUBSAMPLING__411 0x303000
4064 #define WUFFS_BASE__PIXEL_SUBSAMPLING__410 0x313100
4065 
4066 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4067 wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling* s,
4068                                       uint32_t plane) {
4069   uint32_t shift = ((plane & 0x03) * 8) + 6;
4070   return (s->repr >> shift) & 0x03;
4071 }
4072 
4073 static inline uint32_t  //
wuffs_base__pixel_subsampling__denominator_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4074 wuffs_base__pixel_subsampling__denominator_x(
4075     const wuffs_base__pixel_subsampling* s,
4076     uint32_t plane) {
4077   uint32_t shift = ((plane & 0x03) * 8) + 4;
4078   return ((s->repr >> shift) & 0x03) + 1;
4079 }
4080 
4081 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4082 wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling* s,
4083                                       uint32_t plane) {
4084   uint32_t shift = ((plane & 0x03) * 8) + 2;
4085   return (s->repr >> shift) & 0x03;
4086 }
4087 
4088 static inline uint32_t  //
wuffs_base__pixel_subsampling__denominator_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4089 wuffs_base__pixel_subsampling__denominator_y(
4090     const wuffs_base__pixel_subsampling* s,
4091     uint32_t plane) {
4092   uint32_t shift = ((plane & 0x03) * 8) + 0;
4093   return ((s->repr >> shift) & 0x03) + 1;
4094 }
4095 
4096 #ifdef __cplusplus
4097 
4098 inline uint32_t  //
bias_x(uint32_t plane)4099 wuffs_base__pixel_subsampling::bias_x(uint32_t plane) const {
4100   return wuffs_base__pixel_subsampling__bias_x(this, plane);
4101 }
4102 
4103 inline uint32_t  //
denominator_x(uint32_t plane)4104 wuffs_base__pixel_subsampling::denominator_x(uint32_t plane) const {
4105   return wuffs_base__pixel_subsampling__denominator_x(this, plane);
4106 }
4107 
4108 inline uint32_t  //
bias_y(uint32_t plane)4109 wuffs_base__pixel_subsampling::bias_y(uint32_t plane) const {
4110   return wuffs_base__pixel_subsampling__bias_y(this, plane);
4111 }
4112 
4113 inline uint32_t  //
denominator_y(uint32_t plane)4114 wuffs_base__pixel_subsampling::denominator_y(uint32_t plane) const {
4115   return wuffs_base__pixel_subsampling__denominator_y(this, plane);
4116 }
4117 
4118 #endif  // __cplusplus
4119 
4120 // --------
4121 
4122 typedef struct wuffs_base__pixel_config__struct {
4123   // Do not access the private_impl's fields directly. There is no API/ABI
4124   // compatibility or safety guarantee if you do so.
4125   struct {
4126     wuffs_base__pixel_format pixfmt;
4127     wuffs_base__pixel_subsampling pixsub;
4128     uint32_t width;
4129     uint32_t height;
4130   } private_impl;
4131 
4132 #ifdef __cplusplus
4133   inline void set(uint32_t pixfmt_repr,
4134                   uint32_t pixsub_repr,
4135                   uint32_t width,
4136                   uint32_t height);
4137   inline void invalidate();
4138   inline bool is_valid() const;
4139   inline wuffs_base__pixel_format pixel_format() const;
4140   inline wuffs_base__pixel_subsampling pixel_subsampling() const;
4141   inline wuffs_base__rect_ie_u32 bounds() const;
4142   inline uint32_t width() const;
4143   inline uint32_t height() const;
4144   inline uint64_t pixbuf_len() const;
4145 #endif  // __cplusplus
4146 
4147 } wuffs_base__pixel_config;
4148 
4149 static inline wuffs_base__pixel_config  //
wuffs_base__null_pixel_config()4150 wuffs_base__null_pixel_config() {
4151   wuffs_base__pixel_config ret;
4152   ret.private_impl.pixfmt.repr = 0;
4153   ret.private_impl.pixsub.repr = 0;
4154   ret.private_impl.width = 0;
4155   ret.private_impl.height = 0;
4156   return ret;
4157 }
4158 
4159 // TODO: Should this function return bool? An error type?
4160 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)4161 wuffs_base__pixel_config__set(wuffs_base__pixel_config* c,
4162                               uint32_t pixfmt_repr,
4163                               uint32_t pixsub_repr,
4164                               uint32_t width,
4165                               uint32_t height) {
4166   if (!c) {
4167     return;
4168   }
4169   if (pixfmt_repr) {
4170     uint64_t wh = ((uint64_t)width) * ((uint64_t)height);
4171     // TODO: handle things other than 1 byte per pixel.
4172     if (wh <= ((uint64_t)SIZE_MAX)) {
4173       c->private_impl.pixfmt.repr = pixfmt_repr;
4174       c->private_impl.pixsub.repr = pixsub_repr;
4175       c->private_impl.width = width;
4176       c->private_impl.height = height;
4177       return;
4178     }
4179   }
4180 
4181   c->private_impl.pixfmt.repr = 0;
4182   c->private_impl.pixsub.repr = 0;
4183   c->private_impl.width = 0;
4184   c->private_impl.height = 0;
4185 }
4186 
4187 static inline void  //
wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config * c)4188 wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) {
4189   if (c) {
4190     c->private_impl.pixfmt.repr = 0;
4191     c->private_impl.pixsub.repr = 0;
4192     c->private_impl.width = 0;
4193     c->private_impl.height = 0;
4194   }
4195 }
4196 
4197 static inline bool  //
wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config * c)4198 wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) {
4199   return c && c->private_impl.pixfmt.repr;
4200 }
4201 
4202 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config * c)4203 wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
4204   return c ? c->private_impl.pixfmt : wuffs_base__make_pixel_format(0);
4205 }
4206 
4207 static inline wuffs_base__pixel_subsampling  //
wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config * c)4208 wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) {
4209   return c ? c->private_impl.pixsub : wuffs_base__make_pixel_subsampling(0);
4210 }
4211 
4212 static inline wuffs_base__rect_ie_u32  //
wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config * c)4213 wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) {
4214   if (c) {
4215     wuffs_base__rect_ie_u32 ret;
4216     ret.min_incl_x = 0;
4217     ret.min_incl_y = 0;
4218     ret.max_excl_x = c->private_impl.width;
4219     ret.max_excl_y = c->private_impl.height;
4220     return ret;
4221   }
4222 
4223   wuffs_base__rect_ie_u32 ret;
4224   ret.min_incl_x = 0;
4225   ret.min_incl_y = 0;
4226   ret.max_excl_x = 0;
4227   ret.max_excl_y = 0;
4228   return ret;
4229 }
4230 
4231 static inline uint32_t  //
wuffs_base__pixel_config__width(const wuffs_base__pixel_config * c)4232 wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) {
4233   return c ? c->private_impl.width : 0;
4234 }
4235 
4236 static inline uint32_t  //
wuffs_base__pixel_config__height(const wuffs_base__pixel_config * c)4237 wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) {
4238   return c ? c->private_impl.height : 0;
4239 }
4240 
4241 // TODO: this is the right API for planar (not interleaved) pixbufs? Should it
4242 // allow decoding into a color model different from the format's intrinsic one?
4243 // For example, decoding a JPEG image straight to RGBA instead of to YCbCr?
4244 static inline uint64_t  //
wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config * c)4245 wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) {
4246   if (!c) {
4247     return 0;
4248   }
4249   if (wuffs_base__pixel_format__is_planar(&c->private_impl.pixfmt)) {
4250     // TODO: support planar pixel formats, concious of pixel subsampling.
4251     return 0;
4252   }
4253   uint32_t bits_per_pixel =
4254       wuffs_base__pixel_format__bits_per_pixel(&c->private_impl.pixfmt);
4255   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4256     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4257     return 0;
4258   }
4259   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4260 
4261   uint64_t n =
4262       ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height);
4263   if (n > (UINT64_MAX / bytes_per_pixel)) {
4264     return 0;
4265   }
4266   n *= bytes_per_pixel;
4267 
4268   if (wuffs_base__pixel_format__is_indexed(&c->private_impl.pixfmt)) {
4269     if (n >
4270         (UINT64_MAX - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4271       return 0;
4272     }
4273     n += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4274   }
4275 
4276   return n;
4277 }
4278 
4279 #ifdef __cplusplus
4280 
4281 inline void  //
set(uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height)4282 wuffs_base__pixel_config::set(uint32_t pixfmt_repr,
4283                               uint32_t pixsub_repr,
4284                               uint32_t width,
4285                               uint32_t height) {
4286   wuffs_base__pixel_config__set(this, pixfmt_repr, pixsub_repr, width, height);
4287 }
4288 
4289 inline void  //
invalidate()4290 wuffs_base__pixel_config::invalidate() {
4291   wuffs_base__pixel_config__invalidate(this);
4292 }
4293 
4294 inline bool  //
is_valid()4295 wuffs_base__pixel_config::is_valid() const {
4296   return wuffs_base__pixel_config__is_valid(this);
4297 }
4298 
4299 inline wuffs_base__pixel_format  //
pixel_format()4300 wuffs_base__pixel_config::pixel_format() const {
4301   return wuffs_base__pixel_config__pixel_format(this);
4302 }
4303 
4304 inline wuffs_base__pixel_subsampling  //
pixel_subsampling()4305 wuffs_base__pixel_config::pixel_subsampling() const {
4306   return wuffs_base__pixel_config__pixel_subsampling(this);
4307 }
4308 
4309 inline wuffs_base__rect_ie_u32  //
bounds()4310 wuffs_base__pixel_config::bounds() const {
4311   return wuffs_base__pixel_config__bounds(this);
4312 }
4313 
4314 inline uint32_t  //
width()4315 wuffs_base__pixel_config::width() const {
4316   return wuffs_base__pixel_config__width(this);
4317 }
4318 
4319 inline uint32_t  //
height()4320 wuffs_base__pixel_config::height() const {
4321   return wuffs_base__pixel_config__height(this);
4322 }
4323 
4324 inline uint64_t  //
pixbuf_len()4325 wuffs_base__pixel_config::pixbuf_len() const {
4326   return wuffs_base__pixel_config__pixbuf_len(this);
4327 }
4328 
4329 #endif  // __cplusplus
4330 
4331 // --------
4332 
4333 typedef struct wuffs_base__image_config__struct {
4334   wuffs_base__pixel_config pixcfg;
4335 
4336   // Do not access the private_impl's fields directly. There is no API/ABI
4337   // compatibility or safety guarantee if you do so.
4338   struct {
4339     uint64_t first_frame_io_position;
4340     bool first_frame_is_opaque;
4341   } private_impl;
4342 
4343 #ifdef __cplusplus
4344   inline void set(uint32_t pixfmt_repr,
4345                   uint32_t pixsub_repr,
4346                   uint32_t width,
4347                   uint32_t height,
4348                   uint64_t first_frame_io_position,
4349                   bool first_frame_is_opaque);
4350   inline void invalidate();
4351   inline bool is_valid() const;
4352   inline uint64_t first_frame_io_position() const;
4353   inline bool first_frame_is_opaque() const;
4354 #endif  // __cplusplus
4355 
4356 } wuffs_base__image_config;
4357 
4358 static inline wuffs_base__image_config  //
wuffs_base__null_image_config()4359 wuffs_base__null_image_config() {
4360   wuffs_base__image_config ret;
4361   ret.pixcfg = wuffs_base__null_pixel_config();
4362   ret.private_impl.first_frame_io_position = 0;
4363   ret.private_impl.first_frame_is_opaque = false;
4364   return ret;
4365 }
4366 
4367 // TODO: Should this function return bool? An error type?
4368 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)4369 wuffs_base__image_config__set(wuffs_base__image_config* c,
4370                               uint32_t pixfmt_repr,
4371                               uint32_t pixsub_repr,
4372                               uint32_t width,
4373                               uint32_t height,
4374                               uint64_t first_frame_io_position,
4375                               bool first_frame_is_opaque) {
4376   if (!c) {
4377     return;
4378   }
4379   if (pixfmt_repr) {
4380     c->pixcfg.private_impl.pixfmt.repr = pixfmt_repr;
4381     c->pixcfg.private_impl.pixsub.repr = pixsub_repr;
4382     c->pixcfg.private_impl.width = width;
4383     c->pixcfg.private_impl.height = height;
4384     c->private_impl.first_frame_io_position = first_frame_io_position;
4385     c->private_impl.first_frame_is_opaque = first_frame_is_opaque;
4386     return;
4387   }
4388 
4389   c->pixcfg.private_impl.pixfmt.repr = 0;
4390   c->pixcfg.private_impl.pixsub.repr = 0;
4391   c->pixcfg.private_impl.width = 0;
4392   c->pixcfg.private_impl.height = 0;
4393   c->private_impl.first_frame_io_position = 0;
4394   c->private_impl.first_frame_is_opaque = 0;
4395 }
4396 
4397 static inline void  //
wuffs_base__image_config__invalidate(wuffs_base__image_config * c)4398 wuffs_base__image_config__invalidate(wuffs_base__image_config* c) {
4399   if (c) {
4400     c->pixcfg.private_impl.pixfmt.repr = 0;
4401     c->pixcfg.private_impl.pixsub.repr = 0;
4402     c->pixcfg.private_impl.width = 0;
4403     c->pixcfg.private_impl.height = 0;
4404     c->private_impl.first_frame_io_position = 0;
4405     c->private_impl.first_frame_is_opaque = 0;
4406   }
4407 }
4408 
4409 static inline bool  //
wuffs_base__image_config__is_valid(const wuffs_base__image_config * c)4410 wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {
4411   return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));
4412 }
4413 
4414 static inline uint64_t  //
wuffs_base__image_config__first_frame_io_position(const wuffs_base__image_config * c)4415 wuffs_base__image_config__first_frame_io_position(
4416     const wuffs_base__image_config* c) {
4417   return c ? c->private_impl.first_frame_io_position : 0;
4418 }
4419 
4420 static inline bool  //
wuffs_base__image_config__first_frame_is_opaque(const wuffs_base__image_config * c)4421 wuffs_base__image_config__first_frame_is_opaque(
4422     const wuffs_base__image_config* c) {
4423   return c ? c->private_impl.first_frame_is_opaque : false;
4424 }
4425 
4426 #ifdef __cplusplus
4427 
4428 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)4429 wuffs_base__image_config::set(uint32_t pixfmt_repr,
4430                               uint32_t pixsub_repr,
4431                               uint32_t width,
4432                               uint32_t height,
4433                               uint64_t first_frame_io_position,
4434                               bool first_frame_is_opaque) {
4435   wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, width, height,
4436                                 first_frame_io_position, first_frame_is_opaque);
4437 }
4438 
4439 inline void  //
invalidate()4440 wuffs_base__image_config::invalidate() {
4441   wuffs_base__image_config__invalidate(this);
4442 }
4443 
4444 inline bool  //
is_valid()4445 wuffs_base__image_config::is_valid() const {
4446   return wuffs_base__image_config__is_valid(this);
4447 }
4448 
4449 inline uint64_t  //
first_frame_io_position()4450 wuffs_base__image_config::first_frame_io_position() const {
4451   return wuffs_base__image_config__first_frame_io_position(this);
4452 }
4453 
4454 inline bool  //
first_frame_is_opaque()4455 wuffs_base__image_config::first_frame_is_opaque() const {
4456   return wuffs_base__image_config__first_frame_is_opaque(this);
4457 }
4458 
4459 #endif  // __cplusplus
4460 
4461 // --------
4462 
4463 // wuffs_base__animation_disposal encodes, for an animated image, how to
4464 // dispose of a frame after displaying it:
4465 //  - None means to draw the next frame on top of this one.
4466 //  - Restore Background means to clear the frame's dirty rectangle to "the
4467 //    background color" (in practice, this means transparent black) before
4468 //    drawing the next frame.
4469 //  - Restore Previous means to undo the current frame, so that the next frame
4470 //    is drawn on top of the previous one.
4471 typedef uint8_t wuffs_base__animation_disposal;
4472 
4473 #define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)
4474 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \
4475   ((wuffs_base__animation_disposal)1)
4476 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \
4477   ((wuffs_base__animation_disposal)2)
4478 
4479 // --------
4480 
4481 typedef struct wuffs_base__frame_config__struct {
4482   // Do not access the private_impl's fields directly. There is no API/ABI
4483   // compatibility or safety guarantee if you do so.
4484   struct {
4485     wuffs_base__rect_ie_u32 bounds;
4486     wuffs_base__flicks duration;
4487     uint64_t index;
4488     uint64_t io_position;
4489     wuffs_base__animation_disposal disposal;
4490     bool opaque_within_bounds;
4491     bool overwrite_instead_of_blend;
4492     wuffs_base__color_u32_argb_premul background_color;
4493   } private_impl;
4494 
4495 #ifdef __cplusplus
4496   inline void set(wuffs_base__rect_ie_u32 bounds,
4497                   wuffs_base__flicks duration,
4498                   uint64_t index,
4499                   uint64_t io_position,
4500                   wuffs_base__animation_disposal disposal,
4501                   bool opaque_within_bounds,
4502                   bool overwrite_instead_of_blend,
4503                   wuffs_base__color_u32_argb_premul background_color);
4504   inline wuffs_base__rect_ie_u32 bounds() const;
4505   inline uint32_t width() const;
4506   inline uint32_t height() const;
4507   inline wuffs_base__flicks duration() const;
4508   inline uint64_t index() const;
4509   inline uint64_t io_position() const;
4510   inline wuffs_base__animation_disposal disposal() const;
4511   inline bool opaque_within_bounds() const;
4512   inline bool overwrite_instead_of_blend() const;
4513   inline wuffs_base__color_u32_argb_premul background_color() const;
4514 #endif  // __cplusplus
4515 
4516 } wuffs_base__frame_config;
4517 
4518 static inline wuffs_base__frame_config  //
wuffs_base__null_frame_config()4519 wuffs_base__null_frame_config() {
4520   wuffs_base__frame_config ret;
4521   ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);
4522   ret.private_impl.duration = 0;
4523   ret.private_impl.index = 0;
4524   ret.private_impl.io_position = 0;
4525   ret.private_impl.disposal = 0;
4526   ret.private_impl.opaque_within_bounds = false;
4527   ret.private_impl.overwrite_instead_of_blend = false;
4528   return ret;
4529 }
4530 
4531 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)4532 wuffs_base__frame_config__set(
4533     wuffs_base__frame_config* c,
4534     wuffs_base__rect_ie_u32 bounds,
4535     wuffs_base__flicks duration,
4536     uint64_t index,
4537     uint64_t io_position,
4538     wuffs_base__animation_disposal disposal,
4539     bool opaque_within_bounds,
4540     bool overwrite_instead_of_blend,
4541     wuffs_base__color_u32_argb_premul background_color) {
4542   if (!c) {
4543     return;
4544   }
4545 
4546   c->private_impl.bounds = bounds;
4547   c->private_impl.duration = duration;
4548   c->private_impl.index = index;
4549   c->private_impl.io_position = io_position;
4550   c->private_impl.disposal = disposal;
4551   c->private_impl.opaque_within_bounds = opaque_within_bounds;
4552   c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
4553   c->private_impl.background_color = background_color;
4554 }
4555 
4556 static inline wuffs_base__rect_ie_u32  //
wuffs_base__frame_config__bounds(const wuffs_base__frame_config * c)4557 wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {
4558   if (c) {
4559     return c->private_impl.bounds;
4560   }
4561 
4562   wuffs_base__rect_ie_u32 ret;
4563   ret.min_incl_x = 0;
4564   ret.min_incl_y = 0;
4565   ret.max_excl_x = 0;
4566   ret.max_excl_y = 0;
4567   return ret;
4568 }
4569 
4570 static inline uint32_t  //
wuffs_base__frame_config__width(const wuffs_base__frame_config * c)4571 wuffs_base__frame_config__width(const wuffs_base__frame_config* c) {
4572   return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;
4573 }
4574 
4575 static inline uint32_t  //
wuffs_base__frame_config__height(const wuffs_base__frame_config * c)4576 wuffs_base__frame_config__height(const wuffs_base__frame_config* c) {
4577   return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;
4578 }
4579 
4580 // wuffs_base__frame_config__duration returns the amount of time to display
4581 // this frame. Zero means to display forever - a still (non-animated) image.
4582 static inline wuffs_base__flicks  //
wuffs_base__frame_config__duration(const wuffs_base__frame_config * c)4583 wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {
4584   return c ? c->private_impl.duration : 0;
4585 }
4586 
4587 // wuffs_base__frame_config__index returns the index of this frame. The first
4588 // frame in an image has index 0, the second frame has index 1, and so on.
4589 static inline uint64_t  //
wuffs_base__frame_config__index(const wuffs_base__frame_config * c)4590 wuffs_base__frame_config__index(const wuffs_base__frame_config* c) {
4591   return c ? c->private_impl.index : 0;
4592 }
4593 
4594 // wuffs_base__frame_config__io_position returns the I/O stream position before
4595 // the frame config.
4596 static inline uint64_t  //
wuffs_base__frame_config__io_position(const wuffs_base__frame_config * c)4597 wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {
4598   return c ? c->private_impl.io_position : 0;
4599 }
4600 
4601 // wuffs_base__frame_config__disposal returns, for an animated image, how to
4602 // dispose of this frame after displaying it.
4603 static inline wuffs_base__animation_disposal  //
wuffs_base__frame_config__disposal(const wuffs_base__frame_config * c)4604 wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {
4605   return c ? c->private_impl.disposal : 0;
4606 }
4607 
4608 // wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
4609 // within the frame's bounds are fully opaque. It makes no claim about pixels
4610 // outside the frame bounds but still inside the overall image. The two
4611 // bounding rectangles can differ for animated images.
4612 //
4613 // Its semantics are conservative. It is valid for a fully opaque frame to have
4614 // this value be false: a false negative.
4615 //
4616 // If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
4617 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
4618 // resultant pixels, but the former may be faster.
4619 static inline bool  //
wuffs_base__frame_config__opaque_within_bounds(const wuffs_base__frame_config * c)4620 wuffs_base__frame_config__opaque_within_bounds(
4621     const wuffs_base__frame_config* c) {
4622   return c && c->private_impl.opaque_within_bounds;
4623 }
4624 
4625 // wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
4626 // animated image, whether to ignore the previous image state (within the frame
4627 // bounds) when drawing this incremental frame. Equivalently, whether to use
4628 // WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
4629 //
4630 // The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
4631 // calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
4632 // Wuffs' "overwrite_instead_of_blend".
4633 static inline bool  //
wuffs_base__frame_config__overwrite_instead_of_blend(const wuffs_base__frame_config * c)4634 wuffs_base__frame_config__overwrite_instead_of_blend(
4635     const wuffs_base__frame_config* c) {
4636   return c && c->private_impl.overwrite_instead_of_blend;
4637 }
4638 
4639 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__frame_config__background_color(const wuffs_base__frame_config * c)4640 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
4641   return c ? c->private_impl.background_color : 0;
4642 }
4643 
4644 #ifdef __cplusplus
4645 
4646 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)4647 wuffs_base__frame_config::set(
4648     wuffs_base__rect_ie_u32 bounds,
4649     wuffs_base__flicks duration,
4650     uint64_t index,
4651     uint64_t io_position,
4652     wuffs_base__animation_disposal disposal,
4653     bool opaque_within_bounds,
4654     bool overwrite_instead_of_blend,
4655     wuffs_base__color_u32_argb_premul background_color) {
4656   wuffs_base__frame_config__set(this, bounds, duration, index, io_position,
4657                                 disposal, opaque_within_bounds,
4658                                 overwrite_instead_of_blend, background_color);
4659 }
4660 
4661 inline wuffs_base__rect_ie_u32  //
bounds()4662 wuffs_base__frame_config::bounds() const {
4663   return wuffs_base__frame_config__bounds(this);
4664 }
4665 
4666 inline uint32_t  //
width()4667 wuffs_base__frame_config::width() const {
4668   return wuffs_base__frame_config__width(this);
4669 }
4670 
4671 inline uint32_t  //
height()4672 wuffs_base__frame_config::height() const {
4673   return wuffs_base__frame_config__height(this);
4674 }
4675 
4676 inline wuffs_base__flicks  //
duration()4677 wuffs_base__frame_config::duration() const {
4678   return wuffs_base__frame_config__duration(this);
4679 }
4680 
4681 inline uint64_t  //
index()4682 wuffs_base__frame_config::index() const {
4683   return wuffs_base__frame_config__index(this);
4684 }
4685 
4686 inline uint64_t  //
io_position()4687 wuffs_base__frame_config::io_position() const {
4688   return wuffs_base__frame_config__io_position(this);
4689 }
4690 
4691 inline wuffs_base__animation_disposal  //
disposal()4692 wuffs_base__frame_config::disposal() const {
4693   return wuffs_base__frame_config__disposal(this);
4694 }
4695 
4696 inline bool  //
opaque_within_bounds()4697 wuffs_base__frame_config::opaque_within_bounds() const {
4698   return wuffs_base__frame_config__opaque_within_bounds(this);
4699 }
4700 
4701 inline bool  //
overwrite_instead_of_blend()4702 wuffs_base__frame_config::overwrite_instead_of_blend() const {
4703   return wuffs_base__frame_config__overwrite_instead_of_blend(this);
4704 }
4705 
4706 inline wuffs_base__color_u32_argb_premul  //
background_color()4707 wuffs_base__frame_config::background_color() const {
4708   return wuffs_base__frame_config__background_color(this);
4709 }
4710 
4711 #endif  // __cplusplus
4712 
4713 // --------
4714 
4715 typedef struct wuffs_base__pixel_buffer__struct {
4716   wuffs_base__pixel_config pixcfg;
4717 
4718   // Do not access the private_impl's fields directly. There is no API/ABI
4719   // compatibility or safety guarantee if you do so.
4720   struct {
4721     wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX];
4722     // TODO: color spaces.
4723   } private_impl;
4724 
4725 #ifdef __cplusplus
4726   inline wuffs_base__status set_interleaved(
4727       const wuffs_base__pixel_config* pixcfg,
4728       wuffs_base__table_u8 primary_memory,
4729       wuffs_base__slice_u8 palette_memory);
4730   inline wuffs_base__status set_from_slice(
4731       const wuffs_base__pixel_config* pixcfg,
4732       wuffs_base__slice_u8 pixbuf_memory);
4733   inline wuffs_base__status set_from_table(
4734       const wuffs_base__pixel_config* pixcfg,
4735       wuffs_base__table_u8 primary_memory);
4736   inline wuffs_base__slice_u8 palette();
4737   inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
4738   inline wuffs_base__pixel_format pixel_format() const;
4739   inline wuffs_base__table_u8 plane(uint32_t p);
4740   inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,
4741                                                         uint32_t y) const;
4742   inline wuffs_base__status set_color_u32_at(
4743       uint32_t x,
4744       uint32_t y,
4745       wuffs_base__color_u32_argb_premul color);
4746   inline wuffs_base__status set_color_u32_fill_rect(
4747       wuffs_base__rect_ie_u32 rect,
4748       wuffs_base__color_u32_argb_premul color);
4749 #endif  // __cplusplus
4750 
4751 } wuffs_base__pixel_buffer;
4752 
4753 static inline wuffs_base__pixel_buffer  //
wuffs_base__null_pixel_buffer()4754 wuffs_base__null_pixel_buffer() {
4755   wuffs_base__pixel_buffer ret;
4756   ret.pixcfg = wuffs_base__null_pixel_config();
4757   ret.private_impl.planes[0] = wuffs_base__empty_table_u8();
4758   ret.private_impl.planes[1] = wuffs_base__empty_table_u8();
4759   ret.private_impl.planes[2] = wuffs_base__empty_table_u8();
4760   ret.private_impl.planes[3] = wuffs_base__empty_table_u8();
4761   return ret;
4762 }
4763 
4764 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)4765 wuffs_base__pixel_buffer__set_interleaved(
4766     wuffs_base__pixel_buffer* pb,
4767     const wuffs_base__pixel_config* pixcfg,
4768     wuffs_base__table_u8 primary_memory,
4769     wuffs_base__slice_u8 palette_memory) {
4770   if (!pb) {
4771     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4772   }
4773   memset(pb, 0, sizeof(*pb));
4774   if (!pixcfg ||
4775       wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4776     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4777   }
4778   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
4779       (palette_memory.len <
4780        WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4781     return wuffs_base__make_status(
4782         wuffs_base__error__bad_argument_length_too_short);
4783   }
4784   uint32_t bits_per_pixel =
4785       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4786   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4787     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4788     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4789   }
4790   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4791 
4792   uint64_t width_in_bytes =
4793       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
4794   if ((width_in_bytes > primary_memory.width) ||
4795       (pixcfg->private_impl.height > primary_memory.height)) {
4796     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4797   }
4798 
4799   pb->pixcfg = *pixcfg;
4800   pb->private_impl.planes[0] = primary_memory;
4801   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
4802     wuffs_base__table_u8* tab =
4803         &pb->private_impl
4804              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4805     tab->ptr = palette_memory.ptr;
4806     tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4807     tab->height = 1;
4808     tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4809   }
4810   return wuffs_base__make_status(NULL);
4811 }
4812 
4813 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)4814 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
4815                                          const wuffs_base__pixel_config* pixcfg,
4816                                          wuffs_base__slice_u8 pixbuf_memory) {
4817   if (!pb) {
4818     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4819   }
4820   memset(pb, 0, sizeof(*pb));
4821   if (!pixcfg) {
4822     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4823   }
4824   if (wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4825     // TODO: support planar pixel formats, concious of pixel subsampling.
4826     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4827   }
4828   uint32_t bits_per_pixel =
4829       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4830   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4831     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4832     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4833   }
4834   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4835 
4836   uint8_t* ptr = pixbuf_memory.ptr;
4837   uint64_t len = pixbuf_memory.len;
4838   if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
4839     // Split a WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte
4840     // chunk (1024 bytes = 256 palette entries × 4 bytes per entry) from the
4841     // start of pixbuf_memory. We split from the start, not the end, so that
4842     // the both chunks' pointers have the same alignment as the original
4843     // pointer, up to an alignment of 1024.
4844     if (len < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
4845       return wuffs_base__make_status(
4846           wuffs_base__error__bad_argument_length_too_short);
4847     }
4848     wuffs_base__table_u8* tab =
4849         &pb->private_impl
4850              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4851     tab->ptr = ptr;
4852     tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4853     tab->height = 1;
4854     tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4855     ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4856     len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4857   }
4858 
4859   uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *
4860                 ((uint64_t)pixcfg->private_impl.height);
4861   size_t width = (size_t)(pixcfg->private_impl.width);
4862   if ((wh > (UINT64_MAX / bytes_per_pixel)) ||
4863       (width > (SIZE_MAX / bytes_per_pixel))) {
4864     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4865   }
4866   wh *= bytes_per_pixel;
4867   width = ((size_t)(width * bytes_per_pixel));
4868   if (wh > len) {
4869     return wuffs_base__make_status(
4870         wuffs_base__error__bad_argument_length_too_short);
4871   }
4872 
4873   pb->pixcfg = *pixcfg;
4874   wuffs_base__table_u8* tab = &pb->private_impl.planes[0];
4875   tab->ptr = ptr;
4876   tab->width = width;
4877   tab->height = pixcfg->private_impl.height;
4878   tab->stride = width;
4879   return wuffs_base__make_status(NULL);
4880 }
4881 
4882 // Deprecated: does not handle indexed pixel configurations. Use
4883 // wuffs_base__pixel_buffer__set_interleaved instead.
4884 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)4885 wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,
4886                                          const wuffs_base__pixel_config* pixcfg,
4887                                          wuffs_base__table_u8 primary_memory) {
4888   if (!pb) {
4889     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4890   }
4891   memset(pb, 0, sizeof(*pb));
4892   if (!pixcfg ||
4893       wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) ||
4894       wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4895     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4896   }
4897   uint32_t bits_per_pixel =
4898       wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4899   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4900     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4901     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4902   }
4903   uint64_t bytes_per_pixel = bits_per_pixel / 8;
4904 
4905   uint64_t width_in_bytes =
4906       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
4907   if ((width_in_bytes > primary_memory.width) ||
4908       (pixcfg->private_impl.height > primary_memory.height)) {
4909     return wuffs_base__make_status(wuffs_base__error__bad_argument);
4910   }
4911 
4912   pb->pixcfg = *pixcfg;
4913   pb->private_impl.planes[0] = primary_memory;
4914   return wuffs_base__make_status(NULL);
4915 }
4916 
4917 // wuffs_base__pixel_buffer__palette returns the palette color data. If
4918 // non-empty, it will have length
4919 // WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH.
4920 static inline wuffs_base__slice_u8  //
wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer * pb)4921 wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {
4922   if (pb &&
4923       wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
4924     wuffs_base__table_u8* tab =
4925         &pb->private_impl
4926              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4927     if ((tab->width ==
4928          WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
4929         (tab->height == 1)) {
4930       return wuffs_base__make_slice_u8(
4931           tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
4932     }
4933   }
4934   return wuffs_base__make_slice_u8(NULL, 0);
4935 }
4936 
4937 static inline wuffs_base__slice_u8  //
wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer * pb,wuffs_base__slice_u8 fallback)4938 wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer* pb,
4939                                           wuffs_base__slice_u8 fallback) {
4940   if (pb &&
4941       wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
4942     wuffs_base__table_u8* tab =
4943         &pb->private_impl
4944              .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4945     if ((tab->width ==
4946          WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
4947         (tab->height == 1)) {
4948       return wuffs_base__make_slice_u8(
4949           tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
4950     }
4951   }
4952   return fallback;
4953 }
4954 
4955 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer * pb)4956 wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {
4957   if (pb) {
4958     return pb->pixcfg.private_impl.pixfmt;
4959   }
4960   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);
4961 }
4962 
4963 static inline wuffs_base__table_u8  //
wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer * pb,uint32_t p)4964 wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {
4965   if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) {
4966     return pb->private_impl.planes[p];
4967   }
4968 
4969   wuffs_base__table_u8 ret;
4970   ret.ptr = NULL;
4971   ret.width = 0;
4972   ret.height = 0;
4973   ret.stride = 0;
4974   return ret;
4975 }
4976 
4977 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul  //
4978 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
4979                                        uint32_t x,
4980                                        uint32_t y);
4981 
4982 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
4983 wuffs_base__pixel_buffer__set_color_u32_at(
4984     wuffs_base__pixel_buffer* pb,
4985     uint32_t x,
4986     uint32_t y,
4987     wuffs_base__color_u32_argb_premul color);
4988 
4989 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
4990 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
4991     wuffs_base__pixel_buffer* pb,
4992     wuffs_base__rect_ie_u32 rect,
4993     wuffs_base__color_u32_argb_premul color);
4994 
4995 #ifdef __cplusplus
4996 
4997 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)4998 wuffs_base__pixel_buffer::set_interleaved(
4999     const wuffs_base__pixel_config* pixcfg_arg,
5000     wuffs_base__table_u8 primary_memory,
5001     wuffs_base__slice_u8 palette_memory) {
5002   return wuffs_base__pixel_buffer__set_interleaved(
5003       this, pixcfg_arg, primary_memory, palette_memory);
5004 }
5005 
5006 inline wuffs_base__status  //
set_from_slice(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__slice_u8 pixbuf_memory)5007 wuffs_base__pixel_buffer::set_from_slice(
5008     const wuffs_base__pixel_config* pixcfg_arg,
5009     wuffs_base__slice_u8 pixbuf_memory) {
5010   return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,
5011                                                   pixbuf_memory);
5012 }
5013 
5014 inline wuffs_base__status  //
set_from_table(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__table_u8 primary_memory)5015 wuffs_base__pixel_buffer::set_from_table(
5016     const wuffs_base__pixel_config* pixcfg_arg,
5017     wuffs_base__table_u8 primary_memory) {
5018   return wuffs_base__pixel_buffer__set_from_table(this, pixcfg_arg,
5019                                                   primary_memory);
5020 }
5021 
5022 inline wuffs_base__slice_u8  //
palette()5023 wuffs_base__pixel_buffer::palette() {
5024   return wuffs_base__pixel_buffer__palette(this);
5025 }
5026 
5027 inline wuffs_base__slice_u8  //
palette_or_else(wuffs_base__slice_u8 fallback)5028 wuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {
5029   return wuffs_base__pixel_buffer__palette_or_else(this, fallback);
5030 }
5031 
5032 inline wuffs_base__pixel_format  //
pixel_format()5033 wuffs_base__pixel_buffer::pixel_format() const {
5034   return wuffs_base__pixel_buffer__pixel_format(this);
5035 }
5036 
5037 inline wuffs_base__table_u8  //
plane(uint32_t p)5038 wuffs_base__pixel_buffer::plane(uint32_t p) {
5039   return wuffs_base__pixel_buffer__plane(this, p);
5040 }
5041 
5042 inline wuffs_base__color_u32_argb_premul  //
color_u32_at(uint32_t x,uint32_t y)5043 wuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {
5044   return wuffs_base__pixel_buffer__color_u32_at(this, x, y);
5045 }
5046 
5047 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
5048 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
5049     wuffs_base__pixel_buffer* pb,
5050     wuffs_base__rect_ie_u32 rect,
5051     wuffs_base__color_u32_argb_premul color);
5052 
5053 inline wuffs_base__status  //
set_color_u32_at(uint32_t x,uint32_t y,wuffs_base__color_u32_argb_premul color)5054 wuffs_base__pixel_buffer::set_color_u32_at(
5055     uint32_t x,
5056     uint32_t y,
5057     wuffs_base__color_u32_argb_premul color) {
5058   return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);
5059 }
5060 
5061 inline wuffs_base__status  //
set_color_u32_fill_rect(wuffs_base__rect_ie_u32 rect,wuffs_base__color_u32_argb_premul color)5062 wuffs_base__pixel_buffer::set_color_u32_fill_rect(
5063     wuffs_base__rect_ie_u32 rect,
5064     wuffs_base__color_u32_argb_premul color) {
5065   return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);
5066 }
5067 
5068 #endif  // __cplusplus
5069 
5070 // --------
5071 
5072 typedef struct wuffs_base__decode_frame_options__struct {
5073   // Do not access the private_impl's fields directly. There is no API/ABI
5074   // compatibility or safety guarantee if you do so.
5075   struct {
5076     uint8_t TODO;
5077   } private_impl;
5078 
5079 #ifdef __cplusplus
5080 #endif  // __cplusplus
5081 
5082 } wuffs_base__decode_frame_options;
5083 
5084 #ifdef __cplusplus
5085 
5086 #endif  // __cplusplus
5087 
5088 // --------
5089 
5090 // wuffs_base__pixel_palette__closest_element returns the index of the palette
5091 // element that minimizes the sum of squared differences of the four ARGB
5092 // channels, working in premultiplied alpha. Ties favor the smaller index.
5093 //
5094 // The palette_slice.len may equal (N*4), for N less than 256, which means that
5095 // only the first N palette elements are considered. It returns 0 when N is 0.
5096 //
5097 // Applying this function on a per-pixel basis will not produce whole-of-image
5098 // dithering.
5099 WUFFS_BASE__MAYBE_STATIC uint8_t  //
5100 wuffs_base__pixel_palette__closest_element(
5101     wuffs_base__slice_u8 palette_slice,
5102     wuffs_base__pixel_format palette_format,
5103     wuffs_base__color_u32_argb_premul c);
5104 
5105 // --------
5106 
5107 // TODO: should the func type take restrict pointers?
5108 typedef uint64_t (*wuffs_base__pixel_swizzler__func)(uint8_t* dst_ptr,
5109                                                      size_t dst_len,
5110                                                      uint8_t* dst_palette_ptr,
5111                                                      size_t dst_palette_len,
5112                                                      const uint8_t* src_ptr,
5113                                                      size_t src_len);
5114 
5115 typedef uint64_t (*wuffs_base__pixel_swizzler__transparent_black_func)(
5116     uint8_t* dst_ptr,
5117     size_t dst_len,
5118     uint8_t* dst_palette_ptr,
5119     size_t dst_palette_len,
5120     uint64_t num_pixels,
5121     uint32_t dst_pixfmt_bytes_per_pixel);
5122 
5123 typedef struct wuffs_base__pixel_swizzler__struct {
5124   // Do not access the private_impl's fields directly. There is no API/ABI
5125   // compatibility or safety guarantee if you do so.
5126   struct {
5127     wuffs_base__pixel_swizzler__func func;
5128     wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func;
5129     uint32_t dst_pixfmt_bytes_per_pixel;
5130     uint32_t src_pixfmt_bytes_per_pixel;
5131   } private_impl;
5132 
5133 #ifdef __cplusplus
5134   inline wuffs_base__status prepare(wuffs_base__pixel_format dst_pixfmt,
5135                                     wuffs_base__slice_u8 dst_palette,
5136                                     wuffs_base__pixel_format src_pixfmt,
5137                                     wuffs_base__slice_u8 src_palette,
5138                                     wuffs_base__pixel_blend blend);
5139   inline uint64_t swizzle_interleaved_from_slice(
5140       wuffs_base__slice_u8 dst,
5141       wuffs_base__slice_u8 dst_palette,
5142       wuffs_base__slice_u8 src) const;
5143 #endif  // __cplusplus
5144 
5145 } wuffs_base__pixel_swizzler;
5146 
5147 // wuffs_base__pixel_swizzler__prepare readies the pixel swizzler so that its
5148 // other methods may be called.
5149 //
5150 // For modular builds that divide the base module into sub-modules, using this
5151 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5152 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5153 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
5154 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
5155                                     wuffs_base__pixel_format dst_pixfmt,
5156                                     wuffs_base__slice_u8 dst_palette,
5157                                     wuffs_base__pixel_format src_pixfmt,
5158                                     wuffs_base__slice_u8 src_palette,
5159                                     wuffs_base__pixel_blend blend);
5160 
5161 // wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice converts pixels
5162 // from a source format to a destination format.
5163 //
5164 // For modular builds that divide the base module into sub-modules, using this
5165 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5166 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5167 WUFFS_BASE__MAYBE_STATIC uint64_t  //
5168 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5169     const wuffs_base__pixel_swizzler* p,
5170     wuffs_base__slice_u8 dst,
5171     wuffs_base__slice_u8 dst_palette,
5172     wuffs_base__slice_u8 src);
5173 
5174 #ifdef __cplusplus
5175 
5176 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)5177 wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_pixfmt,
5178                                     wuffs_base__slice_u8 dst_palette,
5179                                     wuffs_base__pixel_format src_pixfmt,
5180                                     wuffs_base__slice_u8 src_palette,
5181                                     wuffs_base__pixel_blend blend) {
5182   return wuffs_base__pixel_swizzler__prepare(this, dst_pixfmt, dst_palette,
5183                                              src_pixfmt, src_palette, blend);
5184 }
5185 
5186 uint64_t  //
swizzle_interleaved_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)5187 wuffs_base__pixel_swizzler::swizzle_interleaved_from_slice(
5188     wuffs_base__slice_u8 dst,
5189     wuffs_base__slice_u8 dst_palette,
5190     wuffs_base__slice_u8 src) const {
5191   return wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5192       this, dst, dst_palette, src);
5193 }
5194 
5195 #endif  // __cplusplus
5196 
5197 // ---------------- String Conversions
5198 
5199 // Options (bitwise or'ed together) for wuffs_base__parse_number_xxx
5200 // functions. The XXX options apply to both integer and floating point. The FXX
5201 // options apply only to floating point.
5202 
5203 #define WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5204 
5205 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES means to accept
5206 // inputs like "00", "0644" and "00.7". By default, they are rejected.
5207 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES \
5208   ((uint32_t)0x00000001)
5209 
5210 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES means to accept inputs like
5211 // "1__2" and "_3.141_592". By default, they are rejected.
5212 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES ((uint32_t)0x00000002)
5213 
5214 // WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to accept
5215 // "1,5" and not "1.5" as one-and-a-half.
5216 //
5217 // If the caller wants to accept either, it is responsible for canonicalizing
5218 // the input before calling wuffs_base__parse_number_fxx. The caller also has
5219 // more context on e.g. exactly how to treat something like "$1,234".
5220 #define WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5221   ((uint32_t)0x00000010)
5222 
5223 // WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN means to reject inputs that
5224 // would lead to infinite or Not-a-Number floating point values. By default,
5225 // they are accepted.
5226 //
5227 // This affects the literal "inf" as input, but also affects inputs like
5228 // "1e999" that would overflow double-precision floating point.
5229 #define WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN ((uint32_t)0x00000020)
5230 
5231 // --------
5232 
5233 // Options (bitwise or'ed together) for wuffs_base__render_number_xxx
5234 // functions. The XXX options apply to both integer and floating point. The FXX
5235 // options apply only to floating point.
5236 
5237 #define WUFFS_BASE__RENDER_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5238 
5239 // WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT means to render to the right side
5240 // (higher indexes) of the destination slice, leaving any untouched bytes on
5241 // the left side (lower indexes). The default is vice versa: rendering on the
5242 // left with slack on the right.
5243 #define WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT ((uint32_t)0x00000100)
5244 
5245 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN means to render the leading
5246 // "+" for non-negative numbers: "+0" and "+12.3" instead of "0" and "12.3".
5247 #define WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN ((uint32_t)0x00000200)
5248 
5249 // WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to render
5250 // one-and-a-half as "1,5" instead of "1.5".
5251 #define WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5252   ((uint32_t)0x00001000)
5253 
5254 // WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ETC means whether to never
5255 // (EXPONENT_ABSENT, equivalent to printf's "%f") or to always
5256 // (EXPONENT_PRESENT, equivalent to printf's "%e") render a floating point
5257 // number as "1.23e+05" instead of "123000".
5258 //
5259 // Having both bits set is the same has having neither bit set, where the
5260 // notation used depends on whether the exponent is sufficiently large: "0.5"
5261 // is preferred over "5e-01" but "5e-09" is preferred over "0.000000005".
5262 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT ((uint32_t)0x00002000)
5263 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT ((uint32_t)0x00004000)
5264 
5265 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION means to render the
5266 // smallest number of digits so that parsing the resultant string will recover
5267 // the same double-precision floating point number.
5268 //
5269 // For example, double-precision cannot distinguish between 0.3 and
5270 // 0.299999999999999988897769753748434595763683319091796875, so when this bit
5271 // is set, rendering the latter will produce "0.3" but rendering
5272 // 0.3000000000000000444089209850062616169452667236328125 will produce
5273 // "0.30000000000000004".
5274 #define WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION \
5275   ((uint32_t)0x00008000)
5276 
5277 // ---------------- IEEE 754 Floating Point
5278 
5279 // wuffs_base__ieee_754_bit_representation__etc converts between a double
5280 // precision numerical value and its IEEE 754 representations:
5281 //  - 16-bit: 1 sign bit,  5 exponent bits, 10 explicit significand bits.
5282 //  - 32-bit: 1 sign bit,  8 exponent bits, 23 explicit significand bits.
5283 //  - 64-bit: 1 sign bit, 11 exponent bits, 52 explicit significand bits.
5284 //
5285 // For example, it converts between:
5286 //  - +1.0 and 0x3C00, 0x3F80_0000 or 0x3FF0_0000_0000_0000.
5287 //  - +5.5 and 0x4580, 0x40B0_0000 or 0x4016_0000_0000_0000.
5288 //  - -inf and 0xFC00, 0xFF80_0000 or 0xFFF0_0000_0000_0000.
5289 //
5290 // Converting from f64 to shorter formats (f16 or f32, represented in C as
5291 // uint16_t and uint32_t) may be lossy. Such functions have names that look
5292 // like etc_truncate, as converting finite numbers produce equal or smaller
5293 // (closer-to-zero) finite numbers. For example, 1048576.0 is a perfectly valid
5294 // f64 number, but converting it to a f16 (with truncation) produces 65504.0,
5295 // the largest finite f16 number. Truncating a f64-typed value d to f32 does
5296 // not always produce the same result as the C-style cast ((float)d), as
5297 // casting can convert from finite numbers to infinite ones.
5298 //
5299 // Converting infinities or NaNs produces infinities or NaNs and always report
5300 // no loss, even though there a multiple NaN representations so that round-
5301 // tripping a f64-typed NaN may produce a different 64 bits. Nonetheless, the
5302 // etc_truncate functions preserve a NaN's "quiet vs signaling" bit.
5303 //
5304 // See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
5305 
5306 typedef struct wuffs_base__lossy_value_u16__struct {
5307   uint16_t value;
5308   bool lossy;
5309 } wuffs_base__lossy_value_u16;
5310 
5311 typedef struct wuffs_base__lossy_value_u32__struct {
5312   uint32_t value;
5313   bool lossy;
5314 } wuffs_base__lossy_value_u32;
5315 
5316 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16  //
5317 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f);
5318 
5319 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32  //
5320 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f);
5321 
5322 static inline uint64_t  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f)5323 wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f) {
5324   uint64_t u = 0;
5325   if (sizeof(uint64_t) == sizeof(double)) {
5326     memcpy(&u, &f, sizeof(uint64_t));
5327   }
5328   return u;
5329 }
5330 
5331 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u)5332 wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u) {
5333   uint64_t v = ((uint64_t)(u & 0x8000)) << 48;
5334 
5335   do {
5336     uint64_t exp = (u >> 10) & 0x1F;
5337     uint64_t man = u & 0x3FF;
5338     if (exp == 0x1F) {  // Infinity or NaN.
5339       exp = 2047;
5340     } else if (exp != 0) {  // Normal.
5341       exp += 1008;          // 1008 = 1023 - 15, the difference in biases.
5342     } else if (man != 0) {  // Subnormal but non-zero.
5343       uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
5344       exp = 1062 - clz;  // 1062 = 1008 + 64 - 10.
5345       man = 0x3FF & (man << (clz - 53));
5346     } else {  // Zero.
5347       break;
5348     }
5349     v |= (exp << 52) | (man << 42);
5350   } while (0);
5351 
5352   double f = 0;
5353   if (sizeof(uint64_t) == sizeof(double)) {
5354     memcpy(&f, &v, sizeof(uint64_t));
5355   }
5356   return f;
5357 }
5358 
5359 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u)5360 wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u) {
5361   float f = 0;
5362   if (sizeof(uint32_t) == sizeof(float)) {
5363     memcpy(&f, &u, sizeof(uint32_t));
5364   }
5365   return (double)f;
5366 }
5367 
5368 static inline double  //
wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u)5369 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u) {
5370   double f = 0;
5371   if (sizeof(uint64_t) == sizeof(double)) {
5372     memcpy(&f, &u, sizeof(uint64_t));
5373   }
5374   return f;
5375 }
5376 
5377 // ---------------- Parsing and Rendering Numbers
5378 
5379 // wuffs_base__parse_number_f64 parses the floating point number in s. For
5380 // example, if s contains the bytes "1.5" then it will return the double 1.5.
5381 //
5382 // It returns an error if s does not contain a floating point number.
5383 //
5384 // It does not necessarily return an error if the conversion is lossy, e.g. if
5385 // s is "0.3", which double-precision floating point cannot represent exactly.
5386 //
5387 // Similarly, the returned value may be infinite (and no error returned) even
5388 // if s was not "inf", when the input is nominally finite but sufficiently
5389 // larger than DBL_MAX, about 1.8e+308.
5390 //
5391 // It is similar to the C standard library's strtod function, but:
5392 //  - Errors are returned in-band (in a result type), not out-of-band (errno).
5393 //  - It takes a slice (a pointer and length), not a NUL-terminated C string.
5394 //  - It does not take an optional endptr argument. It does not allow a partial
5395 //    parse: it returns an error unless all of s is consumed.
5396 //  - It does not allow whitespace, leading or otherwise.
5397 //  - It does not allow hexadecimal floating point numbers.
5398 //  - It is not affected by i18n / l10n settings such as environment variables.
5399 //
5400 // The options argument can change these, but by default, it:
5401 //  - Allows "inf", "+Infinity" and "-NAN", case insensitive. Similarly,
5402 //    without an explicit opt-out, it would successfully parse "1e999" as
5403 //    infinity, even though it overflows double-precision floating point.
5404 //  - Rejects underscores. With an explicit opt-in, "_3.141_592" would
5405 //    successfully parse as an approximation to π.
5406 //  - Rejects unnecessary leading zeroes: "00", "0644" and "00.7".
5407 //  - Uses a dot '1.5' instead of a comma '1,5' for the decimal separator.
5408 //
5409 // For modular builds that divide the base module into sub-modules, using this
5410 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5411 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5412 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
5413 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options);
5414 
5415 // wuffs_base__parse_number_i64 parses the ASCII integer in s. For example, if
5416 // s contains the bytes "-123" then it will return the int64_t -123.
5417 //
5418 // It returns an error if s does not contain an integer or if the integer
5419 // within would overflow an int64_t.
5420 //
5421 // It is similar to wuffs_base__parse_number_u64 but it returns a signed
5422 // integer, not an unsigned integer. It also allows a leading '+' or '-'.
5423 //
5424 // For modular builds that divide the base module into sub-modules, using this
5425 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5426 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5427 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64  //
5428 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options);
5429 
5430 // wuffs_base__parse_number_u64 parses the ASCII integer in s. For example, if
5431 // s contains the bytes "123" then it will return the uint64_t 123.
5432 //
5433 // It returns an error if s does not contain an integer or if the integer
5434 // within would overflow a uint64_t.
5435 //
5436 // It is similar to the C standard library's strtoull function, but:
5437 //  - Errors are returned in-band (in a result type), not out-of-band (errno).
5438 //  - It takes a slice (a pointer and length), not a NUL-terminated C string.
5439 //  - It does not take an optional endptr argument. It does not allow a partial
5440 //    parse: it returns an error unless all of s is consumed.
5441 //  - It does not allow whitespace, leading or otherwise.
5442 //  - It does not allow a leading '+' or '-'.
5443 //  - It does not take a base argument (e.g. base 10 vs base 16). Instead, it
5444 //    always accepts both decimal (e.g "1234", "0d5678") and hexadecimal (e.g.
5445 //    "0x9aBC"). The caller is responsible for prior filtering of e.g. hex
5446 //    numbers if they are unwanted. For example, Wuffs' JSON decoder will only
5447 //    produce a wuffs_base__token for decimal numbers, not hexadecimal.
5448 //  - It is not affected by i18n / l10n settings such as environment variables.
5449 //
5450 // The options argument can change these, but by default, it:
5451 //  - Rejects underscores. With an explicit opt-in, "__0D_1_002" would
5452 //    successfully parse as "one thousand and two". Underscores are still
5453 //    rejected inside the optional 2-byte opening "0d" or "0X" that denotes
5454 //    base-10 or base-16.
5455 //  - Rejects unnecessary leading zeroes: "00" and "0644".
5456 //
5457 // For modular builds that divide the base module into sub-modules, using this
5458 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5459 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5460 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64  //
5461 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options);
5462 
5463 // --------
5464 
5465 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL is the string length of
5466 // "-9223372036854775808" and "+9223372036854775807", INT64_MIN and INT64_MAX.
5467 #define WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL 20
5468 
5469 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL is the string length of
5470 // "+18446744073709551615", UINT64_MAX.
5471 #define WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL 21
5472 
5473 // wuffs_base__render_number_f64 writes the decimal encoding of x to dst and
5474 // returns the number of bytes written. If dst is shorter than the entire
5475 // encoding, it returns 0 (and no bytes are written).
5476 //
5477 // For those familiar with C's printf or Go's fmt.Printf functions:
5478 //  - "%e" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT option.
5479 //  - "%f" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT  option.
5480 //  - "%g" means neither or both bits are set.
5481 //
5482 // The precision argument controls the number of digits rendered, excluding the
5483 // exponent (the "e+05" in "1.23e+05"):
5484 //  - for "%e" and "%f" it is the number of digits after the decimal separator,
5485 //  - for "%g" it is the number of significant digits (and trailing zeroes are
5486 //    removed).
5487 //
5488 // A precision of 6 gives similar output to printf's defaults.
5489 //
5490 // A precision greater than 4095 is equivalent to 4095.
5491 //
5492 // The precision argument is ignored when the
5493 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION option is set. This is
5494 // similar to Go's strconv.FormatFloat with a negative (i.e. non-sensical)
5495 // precision, but there is no corresponding feature in C's printf.
5496 //
5497 // Extreme values of x will be rendered as "NaN", "Inf" (or "+Inf" if the
5498 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN option is set) or "-Inf".
5499 //
5500 // For modular builds that divide the base module into sub-modules, using this
5501 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5502 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5503 WUFFS_BASE__MAYBE_STATIC size_t  //
5504 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
5505                               double x,
5506                               uint32_t precision,
5507                               uint32_t options);
5508 
5509 // wuffs_base__render_number_i64 writes the decimal encoding of x to dst and
5510 // returns the number of bytes written. If dst is shorter than the entire
5511 // encoding, it returns 0 (and no bytes are written).
5512 //
5513 // dst will never be too short if its length is at least 20, also known as
5514 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL.
5515 //
5516 // For modular builds that divide the base module into sub-modules, using this
5517 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5518 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5519 WUFFS_BASE__MAYBE_STATIC size_t  //
5520 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
5521                               int64_t x,
5522                               uint32_t options);
5523 
5524 // wuffs_base__render_number_u64 writes the decimal encoding of x to dst and
5525 // returns the number of bytes written. If dst is shorter than the entire
5526 // encoding, it returns 0 (and no bytes are written).
5527 //
5528 // dst will never be too short if its length is at least 21, also known as
5529 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL.
5530 //
5531 // For modular builds that divide the base module into sub-modules, using this
5532 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5533 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5534 WUFFS_BASE__MAYBE_STATIC size_t  //
5535 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
5536                               uint64_t x,
5537                               uint32_t options);
5538 
5539 // ---------------- Base-16
5540 
5541 // Options (bitwise or'ed together) for wuffs_base__base_16__xxx functions.
5542 
5543 #define WUFFS_BASE__BASE_16__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5544 
5545 // wuffs_base__base_16__decode2 converts "6A6b" to "jk", where e.g. 'j' is
5546 // U+006A. There are 2 src bytes for every dst byte.
5547 //
5548 // It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
5549 // repeated. It may write nonsense bytes if not, although it will not read or
5550 // write out of bounds.
5551 //
5552 // For modular builds that divide the base module into sub-modules, using this
5553 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5554 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5555 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5556 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
5557                              wuffs_base__slice_u8 src,
5558                              bool src_closed,
5559                              uint32_t options);
5560 
5561 // wuffs_base__base_16__decode4 converts both "\\x6A\\x6b" and "??6a??6B" to
5562 // "jk", where e.g. 'j' is U+006A. There are 4 src bytes for every dst byte.
5563 //
5564 // It assumes that the src bytes are two ignored bytes and then two hexadecimal
5565 // digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
5566 // although it will not read or write out of bounds.
5567 //
5568 // For modular builds that divide the base module into sub-modules, using this
5569 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5570 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5571 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5572 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
5573                              wuffs_base__slice_u8 src,
5574                              bool src_closed,
5575                              uint32_t options);
5576 
5577 // wuffs_base__base_16__encode2 converts "jk" to "6A6B", where e.g. 'j' is
5578 // U+006A. There are 2 dst bytes for every src byte.
5579 //
5580 // For modular builds that divide the base module into sub-modules, using this
5581 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5582 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5583 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5584 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
5585                              wuffs_base__slice_u8 src,
5586                              bool src_closed,
5587                              uint32_t options);
5588 
5589 // wuffs_base__base_16__encode4 converts "jk" to "\\x6A\\x6B", where e.g. 'j'
5590 // is U+006A. There are 4 dst bytes for every src byte.
5591 //
5592 // For modular builds that divide the base module into sub-modules, using this
5593 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5594 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5595 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5596 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
5597                              wuffs_base__slice_u8 src,
5598                              bool src_closed,
5599                              uint32_t options);
5600 
5601 // ---------------- Base-64
5602 
5603 // Options (bitwise or'ed together) for wuffs_base__base_64__xxx functions.
5604 
5605 #define WUFFS_BASE__BASE_64__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5606 
5607 // WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING means that, when decoding base-64,
5608 // the input may (but does not need to) be padded with '=' bytes so that the
5609 // overall encoded length in bytes is a multiple of 4. A successful decoding
5610 // will return a num_src that includes those padding bytes.
5611 //
5612 // Excess padding (e.g. three final '='s) will be rejected as bad data.
5613 #define WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING ((uint32_t)0x00000001)
5614 
5615 // WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING means that, when encoding base-64,
5616 // the output will be padded with '=' bytes so that the overall encoded length
5617 // in bytes is a multiple of 4.
5618 #define WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING ((uint32_t)0x00000002)
5619 
5620 // WUFFS_BASE__BASE_64__URL_ALPHABET means that, for base-64, the URL-friendly
5621 // and file-name-friendly alphabet be used, as per RFC 4648 section 5. When
5622 // this option bit is off, the standard alphabet from section 4 is used.
5623 #define WUFFS_BASE__BASE_64__URL_ALPHABET ((uint32_t)0x00000100)
5624 
5625 // wuffs_base__base_64__decode transforms base-64 encoded bytes from src to
5626 // arbitrary bytes in dst.
5627 //
5628 // It will not permit line breaks or other whitespace in src. Filtering those
5629 // out is the responsibility of the caller.
5630 //
5631 // For modular builds that divide the base module into sub-modules, using this
5632 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5633 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5634 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5635 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
5636                             wuffs_base__slice_u8 src,
5637                             bool src_closed,
5638                             uint32_t options);
5639 
5640 // wuffs_base__base_64__encode transforms arbitrary bytes from src to base-64
5641 // encoded bytes in dst.
5642 //
5643 // For modular builds that divide the base module into sub-modules, using this
5644 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5645 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5646 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output  //
5647 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
5648                             wuffs_base__slice_u8 src,
5649                             bool src_closed,
5650                             uint32_t options);
5651 
5652 // ---------------- Unicode and UTF-8
5653 
5654 #define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
5655 #define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
5656 
5657 #define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD
5658 
5659 #define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800
5660 #define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF
5661 
5662 #define WUFFS_BASE__ASCII__MIN_INCL 0x00
5663 #define WUFFS_BASE__ASCII__MAX_INCL 0x7F
5664 
5665 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1
5666 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4
5667 
5668 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000
5669 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F
5670 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080
5671 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF
5672 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800
5673 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF
5674 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MIN_INCL 0x00010000
5675 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF
5676 
5677 // --------
5678 
5679 // wuffs_base__utf_8__next__output is the type returned by
5680 // wuffs_base__utf_8__next.
5681 typedef struct wuffs_base__utf_8__next__output__struct {
5682   uint32_t code_point;
5683   uint32_t byte_length;
5684 
5685 #ifdef __cplusplus
5686   inline bool is_valid() const;
5687 #endif  // __cplusplus
5688 
5689 } wuffs_base__utf_8__next__output;
5690 
5691 static inline wuffs_base__utf_8__next__output  //
wuffs_base__make_utf_8__next__output(uint32_t code_point,uint32_t byte_length)5692 wuffs_base__make_utf_8__next__output(uint32_t code_point,
5693                                      uint32_t byte_length) {
5694   wuffs_base__utf_8__next__output ret;
5695   ret.code_point = code_point;
5696   ret.byte_length = byte_length;
5697   return ret;
5698 }
5699 
5700 static inline bool  //
wuffs_base__utf_8__next__output__is_valid(const wuffs_base__utf_8__next__output * o)5701 wuffs_base__utf_8__next__output__is_valid(
5702     const wuffs_base__utf_8__next__output* o) {
5703   if (o) {
5704     uint32_t cp = o->code_point;
5705     switch (o->byte_length) {
5706       case 1:
5707         return (cp <= 0x7F);
5708       case 2:
5709         return (0x080 <= cp) && (cp <= 0x7FF);
5710       case 3:
5711         // Avoid the 0xD800 ..= 0xDFFF surrogate range.
5712         return ((0x0800 <= cp) && (cp <= 0xD7FF)) ||
5713                ((0xE000 <= cp) && (cp <= 0xFFFF));
5714       case 4:
5715         return (0x00010000 <= cp) && (cp <= 0x0010FFFF);
5716     }
5717   }
5718   return false;
5719 }
5720 
5721 #ifdef __cplusplus
5722 
5723 inline bool  //
is_valid()5724 wuffs_base__utf_8__next__output::is_valid() const {
5725   return wuffs_base__utf_8__next__output__is_valid(this);
5726 }
5727 
5728 #endif  // __cplusplus
5729 
5730 // --------
5731 
5732 // wuffs_base__utf_8__encode writes the UTF-8 encoding of code_point to s and
5733 // returns the number of bytes written. If code_point is invalid, or if s is
5734 // shorter than the entire encoding, it returns 0 (and no bytes are written).
5735 //
5736 // s will never be too short if its length is at least 4, also known as
5737 // WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL.
5738 //
5739 // For modular builds that divide the base module into sub-modules, using this
5740 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5741 // WUFFS_CONFIG__MODULE__BASE__CORE.
5742 WUFFS_BASE__MAYBE_STATIC size_t  //
5743 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point);
5744 
5745 // wuffs_base__utf_8__next returns the next UTF-8 code point (and that code
5746 // point's byte length) at the start of the read-only slice (s_ptr, s_len).
5747 //
5748 // There are exactly two cases in which this function returns something where
5749 // wuffs_base__utf_8__next__output__is_valid is false:
5750 //  - If s is empty then it returns {.code_point=0, .byte_length=0}.
5751 //  - If s is non-empty and starts with invalid UTF-8 then it returns
5752 //    {.code_point=WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, .byte_length=1}.
5753 //
5754 // Otherwise, it returns something where
5755 // wuffs_base__utf_8__next__output__is_valid is true.
5756 //
5757 // In any case, it always returns an output that satisfies both of:
5758 //  - (output.code_point  <= WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL).
5759 //  - (output.byte_length <= s_len).
5760 //
5761 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5762 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5763 // code point, then this function may return something invalid. It is the
5764 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5765 //
5766 // For modular builds that divide the base module into sub-modules, using this
5767 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5768 // WUFFS_CONFIG__MODULE__BASE__CORE.
5769 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
5770 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len);
5771 
5772 // wuffs_base__utf_8__next_from_end is like wuffs_base__utf_8__next except that
5773 // it looks at the end of (s_ptr, s_len) instead of the start.
5774 //
5775 // For modular builds that divide the base module into sub-modules, using this
5776 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5777 // WUFFS_CONFIG__MODULE__BASE__CORE.
5778 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
5779 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len);
5780 
5781 // wuffs_base__utf_8__longest_valid_prefix returns the largest n such that the
5782 // sub-slice s[..n] is valid UTF-8, where s is the read-only slice (s_ptr,
5783 // s_len).
5784 //
5785 // In particular, it returns s_len if and only if all of s is valid UTF-8.
5786 //
5787 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5788 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5789 // code point, then this function will return less than s_len. It is the
5790 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5791 //
5792 // For modular builds that divide the base module into sub-modules, using this
5793 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5794 // WUFFS_CONFIG__MODULE__BASE__CORE.
5795 WUFFS_BASE__MAYBE_STATIC size_t  //
5796 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5797 
5798 // wuffs_base__ascii__longest_valid_prefix returns the largest n such that the
5799 // sub-slice s[..n] is valid ASCII, where s is the read-only slice (s_ptr,
5800 // s_len).
5801 //
5802 // In particular, it returns s_len if and only if all of s is valid ASCII.
5803 // Equivalently, when none of the bytes in s have the 0x80 high bit set.
5804 //
5805 // For modular builds that divide the base module into sub-modules, using this
5806 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5807 // WUFFS_CONFIG__MODULE__BASE__CORE.
5808 WUFFS_BASE__MAYBE_STATIC size_t  //
5809 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5810 
5811 // ---------------- Interface Declarations.
5812 
5813 // For modular builds that divide the base module into sub-modules, using these
5814 // functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
5815 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5816 
5817 // --------
5818 
5819 extern const char wuffs_base__hasher_u32__vtable_name[];
5820 
5821 typedef struct wuffs_base__hasher_u32__func_ptrs__struct {
5822   wuffs_base__empty_struct (*set_quirk_enabled)(
5823     void* self,
5824     uint32_t a_quirk,
5825     bool a_enabled);
5826   uint32_t (*update_u32)(
5827     void* self,
5828     wuffs_base__slice_u8 a_x);
5829 } wuffs_base__hasher_u32__func_ptrs;
5830 
5831 typedef struct wuffs_base__hasher_u32__struct wuffs_base__hasher_u32;
5832 
5833 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5834 wuffs_base__hasher_u32__set_quirk_enabled(
5835     wuffs_base__hasher_u32* self,
5836     uint32_t a_quirk,
5837     bool a_enabled);
5838 
5839 WUFFS_BASE__MAYBE_STATIC uint32_t
5840 wuffs_base__hasher_u32__update_u32(
5841     wuffs_base__hasher_u32* self,
5842     wuffs_base__slice_u8 a_x);
5843 
5844 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5845 
5846 struct wuffs_base__hasher_u32__struct {
5847   struct {
5848     uint32_t magic;
5849     uint32_t active_coroutine;
5850     wuffs_base__vtable first_vtable;
5851   } private_impl;
5852 
5853 #ifdef __cplusplus
5854 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
5855   using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, decltype(&free)>;
5856 #endif
5857 
5858   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__hasher_u32__struct5859   set_quirk_enabled(
5860       uint32_t a_quirk,
5861       bool a_enabled) {
5862     return wuffs_base__hasher_u32__set_quirk_enabled(
5863         this, a_quirk, a_enabled);
5864   }
5865 
5866   inline uint32_t
update_u32wuffs_base__hasher_u32__struct5867   update_u32(
5868       wuffs_base__slice_u8 a_x) {
5869     return wuffs_base__hasher_u32__update_u32(
5870         this, a_x);
5871   }
5872 
5873 #endif  // __cplusplus
5874 };  // struct wuffs_base__hasher_u32__struct
5875 
5876 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5877 
5878 // --------
5879 
5880 extern const char wuffs_base__image_decoder__vtable_name[];
5881 
5882 typedef struct wuffs_base__image_decoder__func_ptrs__struct {
5883   wuffs_base__status (*decode_frame)(
5884     void* self,
5885     wuffs_base__pixel_buffer* a_dst,
5886     wuffs_base__io_buffer* a_src,
5887     wuffs_base__pixel_blend a_blend,
5888     wuffs_base__slice_u8 a_workbuf,
5889     wuffs_base__decode_frame_options* a_opts);
5890   wuffs_base__status (*decode_frame_config)(
5891     void* self,
5892     wuffs_base__frame_config* a_dst,
5893     wuffs_base__io_buffer* a_src);
5894   wuffs_base__status (*decode_image_config)(
5895     void* self,
5896     wuffs_base__image_config* a_dst,
5897     wuffs_base__io_buffer* a_src);
5898   wuffs_base__rect_ie_u32 (*frame_dirty_rect)(
5899     const void* self);
5900   uint32_t (*num_animation_loops)(
5901     const void* self);
5902   uint64_t (*num_decoded_frame_configs)(
5903     const void* self);
5904   uint64_t (*num_decoded_frames)(
5905     const void* self);
5906   wuffs_base__status (*restart_frame)(
5907     void* self,
5908     uint64_t a_index,
5909     uint64_t a_io_position);
5910   wuffs_base__empty_struct (*set_quirk_enabled)(
5911     void* self,
5912     uint32_t a_quirk,
5913     bool a_enabled);
5914   wuffs_base__empty_struct (*set_report_metadata)(
5915     void* self,
5916     uint32_t a_fourcc,
5917     bool a_report);
5918   wuffs_base__status (*tell_me_more)(
5919     void* self,
5920     wuffs_base__io_buffer* a_dst,
5921     wuffs_base__more_information* a_minfo,
5922     wuffs_base__io_buffer* a_src);
5923   wuffs_base__range_ii_u64 (*workbuf_len)(
5924     const void* self);
5925 } wuffs_base__image_decoder__func_ptrs;
5926 
5927 typedef struct wuffs_base__image_decoder__struct wuffs_base__image_decoder;
5928 
5929 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5930 wuffs_base__image_decoder__decode_frame(
5931     wuffs_base__image_decoder* self,
5932     wuffs_base__pixel_buffer* a_dst,
5933     wuffs_base__io_buffer* a_src,
5934     wuffs_base__pixel_blend a_blend,
5935     wuffs_base__slice_u8 a_workbuf,
5936     wuffs_base__decode_frame_options* a_opts);
5937 
5938 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5939 wuffs_base__image_decoder__decode_frame_config(
5940     wuffs_base__image_decoder* self,
5941     wuffs_base__frame_config* a_dst,
5942     wuffs_base__io_buffer* a_src);
5943 
5944 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5945 wuffs_base__image_decoder__decode_image_config(
5946     wuffs_base__image_decoder* self,
5947     wuffs_base__image_config* a_dst,
5948     wuffs_base__io_buffer* a_src);
5949 
5950 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
5951 wuffs_base__image_decoder__frame_dirty_rect(
5952     const wuffs_base__image_decoder* self);
5953 
5954 WUFFS_BASE__MAYBE_STATIC uint32_t
5955 wuffs_base__image_decoder__num_animation_loops(
5956     const wuffs_base__image_decoder* self);
5957 
5958 WUFFS_BASE__MAYBE_STATIC uint64_t
5959 wuffs_base__image_decoder__num_decoded_frame_configs(
5960     const wuffs_base__image_decoder* self);
5961 
5962 WUFFS_BASE__MAYBE_STATIC uint64_t
5963 wuffs_base__image_decoder__num_decoded_frames(
5964     const wuffs_base__image_decoder* self);
5965 
5966 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5967 wuffs_base__image_decoder__restart_frame(
5968     wuffs_base__image_decoder* self,
5969     uint64_t a_index,
5970     uint64_t a_io_position);
5971 
5972 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5973 wuffs_base__image_decoder__set_quirk_enabled(
5974     wuffs_base__image_decoder* self,
5975     uint32_t a_quirk,
5976     bool a_enabled);
5977 
5978 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5979 wuffs_base__image_decoder__set_report_metadata(
5980     wuffs_base__image_decoder* self,
5981     uint32_t a_fourcc,
5982     bool a_report);
5983 
5984 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5985 wuffs_base__image_decoder__tell_me_more(
5986     wuffs_base__image_decoder* self,
5987     wuffs_base__io_buffer* a_dst,
5988     wuffs_base__more_information* a_minfo,
5989     wuffs_base__io_buffer* a_src);
5990 
5991 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
5992 wuffs_base__image_decoder__workbuf_len(
5993     const wuffs_base__image_decoder* self);
5994 
5995 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5996 
5997 struct wuffs_base__image_decoder__struct {
5998   struct {
5999     uint32_t magic;
6000     uint32_t active_coroutine;
6001     wuffs_base__vtable first_vtable;
6002   } private_impl;
6003 
6004 #ifdef __cplusplus
6005 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6006   using unique_ptr = std::unique_ptr<wuffs_base__image_decoder, decltype(&free)>;
6007 #endif
6008 
6009   inline wuffs_base__status
decode_framewuffs_base__image_decoder__struct6010   decode_frame(
6011       wuffs_base__pixel_buffer* a_dst,
6012       wuffs_base__io_buffer* a_src,
6013       wuffs_base__pixel_blend a_blend,
6014       wuffs_base__slice_u8 a_workbuf,
6015       wuffs_base__decode_frame_options* a_opts) {
6016     return wuffs_base__image_decoder__decode_frame(
6017         this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6018   }
6019 
6020   inline wuffs_base__status
decode_frame_configwuffs_base__image_decoder__struct6021   decode_frame_config(
6022       wuffs_base__frame_config* a_dst,
6023       wuffs_base__io_buffer* a_src) {
6024     return wuffs_base__image_decoder__decode_frame_config(
6025         this, a_dst, a_src);
6026   }
6027 
6028   inline wuffs_base__status
decode_image_configwuffs_base__image_decoder__struct6029   decode_image_config(
6030       wuffs_base__image_config* a_dst,
6031       wuffs_base__io_buffer* a_src) {
6032     return wuffs_base__image_decoder__decode_image_config(
6033         this, a_dst, a_src);
6034   }
6035 
6036   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_base__image_decoder__struct6037   frame_dirty_rect() const {
6038     return wuffs_base__image_decoder__frame_dirty_rect(this);
6039   }
6040 
6041   inline uint32_t
num_animation_loopswuffs_base__image_decoder__struct6042   num_animation_loops() const {
6043     return wuffs_base__image_decoder__num_animation_loops(this);
6044   }
6045 
6046   inline uint64_t
num_decoded_frame_configswuffs_base__image_decoder__struct6047   num_decoded_frame_configs() const {
6048     return wuffs_base__image_decoder__num_decoded_frame_configs(this);
6049   }
6050 
6051   inline uint64_t
num_decoded_frameswuffs_base__image_decoder__struct6052   num_decoded_frames() const {
6053     return wuffs_base__image_decoder__num_decoded_frames(this);
6054   }
6055 
6056   inline wuffs_base__status
restart_framewuffs_base__image_decoder__struct6057   restart_frame(
6058       uint64_t a_index,
6059       uint64_t a_io_position) {
6060     return wuffs_base__image_decoder__restart_frame(
6061         this, a_index, a_io_position);
6062   }
6063 
6064   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__image_decoder__struct6065   set_quirk_enabled(
6066       uint32_t a_quirk,
6067       bool a_enabled) {
6068     return wuffs_base__image_decoder__set_quirk_enabled(
6069         this, a_quirk, a_enabled);
6070   }
6071 
6072   inline wuffs_base__empty_struct
set_report_metadatawuffs_base__image_decoder__struct6073   set_report_metadata(
6074       uint32_t a_fourcc,
6075       bool a_report) {
6076     return wuffs_base__image_decoder__set_report_metadata(
6077         this, a_fourcc, a_report);
6078   }
6079 
6080   inline wuffs_base__status
tell_me_morewuffs_base__image_decoder__struct6081   tell_me_more(
6082       wuffs_base__io_buffer* a_dst,
6083       wuffs_base__more_information* a_minfo,
6084       wuffs_base__io_buffer* a_src) {
6085     return wuffs_base__image_decoder__tell_me_more(
6086         this, a_dst, a_minfo, a_src);
6087   }
6088 
6089   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__image_decoder__struct6090   workbuf_len() const {
6091     return wuffs_base__image_decoder__workbuf_len(this);
6092   }
6093 
6094 #endif  // __cplusplus
6095 };  // struct wuffs_base__image_decoder__struct
6096 
6097 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6098 
6099 // --------
6100 
6101 extern const char wuffs_base__io_transformer__vtable_name[];
6102 
6103 typedef struct wuffs_base__io_transformer__func_ptrs__struct {
6104   wuffs_base__empty_struct (*set_quirk_enabled)(
6105     void* self,
6106     uint32_t a_quirk,
6107     bool a_enabled);
6108   wuffs_base__status (*transform_io)(
6109     void* self,
6110     wuffs_base__io_buffer* a_dst,
6111     wuffs_base__io_buffer* a_src,
6112     wuffs_base__slice_u8 a_workbuf);
6113   wuffs_base__range_ii_u64 (*workbuf_len)(
6114     const void* self);
6115 } wuffs_base__io_transformer__func_ptrs;
6116 
6117 typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer;
6118 
6119 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6120 wuffs_base__io_transformer__set_quirk_enabled(
6121     wuffs_base__io_transformer* self,
6122     uint32_t a_quirk,
6123     bool a_enabled);
6124 
6125 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6126 wuffs_base__io_transformer__transform_io(
6127     wuffs_base__io_transformer* self,
6128     wuffs_base__io_buffer* a_dst,
6129     wuffs_base__io_buffer* a_src,
6130     wuffs_base__slice_u8 a_workbuf);
6131 
6132 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6133 wuffs_base__io_transformer__workbuf_len(
6134     const wuffs_base__io_transformer* self);
6135 
6136 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6137 
6138 struct wuffs_base__io_transformer__struct {
6139   struct {
6140     uint32_t magic;
6141     uint32_t active_coroutine;
6142     wuffs_base__vtable first_vtable;
6143   } private_impl;
6144 
6145 #ifdef __cplusplus
6146 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6147   using unique_ptr = std::unique_ptr<wuffs_base__io_transformer, decltype(&free)>;
6148 #endif
6149 
6150   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__io_transformer__struct6151   set_quirk_enabled(
6152       uint32_t a_quirk,
6153       bool a_enabled) {
6154     return wuffs_base__io_transformer__set_quirk_enabled(
6155         this, a_quirk, a_enabled);
6156   }
6157 
6158   inline wuffs_base__status
transform_iowuffs_base__io_transformer__struct6159   transform_io(
6160       wuffs_base__io_buffer* a_dst,
6161       wuffs_base__io_buffer* a_src,
6162       wuffs_base__slice_u8 a_workbuf) {
6163     return wuffs_base__io_transformer__transform_io(
6164         this, a_dst, a_src, a_workbuf);
6165   }
6166 
6167   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__io_transformer__struct6168   workbuf_len() const {
6169     return wuffs_base__io_transformer__workbuf_len(this);
6170   }
6171 
6172 #endif  // __cplusplus
6173 };  // struct wuffs_base__io_transformer__struct
6174 
6175 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6176 
6177 // --------
6178 
6179 extern const char wuffs_base__token_decoder__vtable_name[];
6180 
6181 typedef struct wuffs_base__token_decoder__func_ptrs__struct {
6182   wuffs_base__status (*decode_tokens)(
6183     void* self,
6184     wuffs_base__token_buffer* a_dst,
6185     wuffs_base__io_buffer* a_src,
6186     wuffs_base__slice_u8 a_workbuf);
6187   wuffs_base__empty_struct (*set_quirk_enabled)(
6188     void* self,
6189     uint32_t a_quirk,
6190     bool a_enabled);
6191   wuffs_base__range_ii_u64 (*workbuf_len)(
6192     const void* self);
6193 } wuffs_base__token_decoder__func_ptrs;
6194 
6195 typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
6196 
6197 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6198 wuffs_base__token_decoder__decode_tokens(
6199     wuffs_base__token_decoder* self,
6200     wuffs_base__token_buffer* a_dst,
6201     wuffs_base__io_buffer* a_src,
6202     wuffs_base__slice_u8 a_workbuf);
6203 
6204 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6205 wuffs_base__token_decoder__set_quirk_enabled(
6206     wuffs_base__token_decoder* self,
6207     uint32_t a_quirk,
6208     bool a_enabled);
6209 
6210 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6211 wuffs_base__token_decoder__workbuf_len(
6212     const wuffs_base__token_decoder* self);
6213 
6214 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6215 
6216 struct wuffs_base__token_decoder__struct {
6217   struct {
6218     uint32_t magic;
6219     uint32_t active_coroutine;
6220     wuffs_base__vtable first_vtable;
6221   } private_impl;
6222 
6223 #ifdef __cplusplus
6224 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6225   using unique_ptr = std::unique_ptr<wuffs_base__token_decoder, decltype(&free)>;
6226 #endif
6227 
6228   inline wuffs_base__status
decode_tokenswuffs_base__token_decoder__struct6229   decode_tokens(
6230       wuffs_base__token_buffer* a_dst,
6231       wuffs_base__io_buffer* a_src,
6232       wuffs_base__slice_u8 a_workbuf) {
6233     return wuffs_base__token_decoder__decode_tokens(
6234         this, a_dst, a_src, a_workbuf);
6235   }
6236 
6237   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__token_decoder__struct6238   set_quirk_enabled(
6239       uint32_t a_quirk,
6240       bool a_enabled) {
6241     return wuffs_base__token_decoder__set_quirk_enabled(
6242         this, a_quirk, a_enabled);
6243   }
6244 
6245   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__token_decoder__struct6246   workbuf_len() const {
6247     return wuffs_base__token_decoder__workbuf_len(this);
6248   }
6249 
6250 #endif  // __cplusplus
6251 };  // struct wuffs_base__token_decoder__struct
6252 
6253 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6254 
6255 // ----------------
6256 
6257 #ifdef __cplusplus
6258 }  // extern "C"
6259 #endif
6260 
6261 // ---------------- Status Codes
6262 
6263 // ---------------- Public Consts
6264 
6265 // ---------------- Struct Declarations
6266 
6267 typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
6268 
6269 #ifdef __cplusplus
6270 extern "C" {
6271 #endif
6272 
6273 // ---------------- Public Initializer Prototypes
6274 
6275 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6276 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6277 //
6278 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6279 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6280 
6281 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6282 wuffs_adler32__hasher__initialize(
6283     wuffs_adler32__hasher* self,
6284     size_t sizeof_star_self,
6285     uint64_t wuffs_version,
6286     uint32_t options);
6287 
6288 size_t
6289 sizeof__wuffs_adler32__hasher();
6290 
6291 // ---------------- Allocs
6292 
6293 // These functions allocate and initialize Wuffs structs. They return NULL if
6294 // memory allocation fails. If they return non-NULL, there is no need to call
6295 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6296 // calling free on the returned pointer. That pointer is effectively a C++
6297 // std::unique_ptr<T, decltype(&free)>.
6298 
6299 wuffs_adler32__hasher*
6300 wuffs_adler32__hasher__alloc();
6301 
6302 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32()6303 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32() {
6304   return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
6305 }
6306 
6307 // ---------------- Upcasts
6308 
6309 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(wuffs_adler32__hasher * p)6310 wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(
6311     wuffs_adler32__hasher* p) {
6312   return (wuffs_base__hasher_u32*)p;
6313 }
6314 
6315 // ---------------- Public Function Prototypes
6316 
6317 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6318 wuffs_adler32__hasher__set_quirk_enabled(
6319     wuffs_adler32__hasher* self,
6320     uint32_t a_quirk,
6321     bool a_enabled);
6322 
6323 WUFFS_BASE__MAYBE_STATIC uint32_t
6324 wuffs_adler32__hasher__update_u32(
6325     wuffs_adler32__hasher* self,
6326     wuffs_base__slice_u8 a_x);
6327 
6328 #ifdef __cplusplus
6329 }  // extern "C"
6330 #endif
6331 
6332 // ---------------- Struct Definitions
6333 
6334 // These structs' fields, and the sizeof them, are private implementation
6335 // details that aren't guaranteed to be stable across Wuffs versions.
6336 //
6337 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6338 
6339 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6340 
6341 struct wuffs_adler32__hasher__struct {
6342   // Do not access the private_impl's or private_data's fields directly. There
6343   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6344   // the wuffs_foo__bar__baz functions.
6345   //
6346   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6347   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6348 
6349   struct {
6350     uint32_t magic;
6351     uint32_t active_coroutine;
6352     wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
6353     wuffs_base__vtable null_vtable;
6354 
6355     uint32_t f_state;
6356     bool f_started;
6357 
6358     wuffs_base__empty_struct (*choosy_up)(
6359         wuffs_adler32__hasher* self,
6360         wuffs_base__slice_u8 a_x);
6361   } private_impl;
6362 
6363 #ifdef __cplusplus
6364 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6365   using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, decltype(&free)>;
6366 
6367   // On failure, the alloc_etc functions return nullptr. They don't throw.
6368 
6369   static inline unique_ptr
allocwuffs_adler32__hasher__struct6370   alloc() {
6371     return unique_ptr(wuffs_adler32__hasher__alloc(), &free);
6372   }
6373 
6374   static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6375   alloc_as__wuffs_base__hasher_u32() {
6376     return wuffs_base__hasher_u32::unique_ptr(
6377         wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(), &free);
6378   }
6379 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6380 
6381 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6382   // Disallow constructing or copying an object via standard C++ mechanisms,
6383   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6384   // size and field layout is not part of the public, stable, memory-safe API.
6385   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6386   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6387   // their first argument) rather than tweaking bar.private_impl.qux fields.
6388   //
6389   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6390   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6391   // order to provide convenience methods. These forward on "this", so that you
6392   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6393   wuffs_adler32__hasher__struct() = delete;
6394   wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
6395   wuffs_adler32__hasher__struct& operator=(
6396       const wuffs_adler32__hasher__struct&) = delete;
6397 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6398 
6399 #if !defined(WUFFS_IMPLEMENTATION)
6400   // As above, the size of the struct is not part of the public API, and unless
6401   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6402   // allocated, not stack allocated. Its size is not intended to be known at
6403   // compile time, but it is unfortunately divulged as a side effect of
6404   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6405   // instead of "sizeof T", invoking the operator. To make the two values
6406   // different, so that passing the latter will be rejected by the initialize
6407   // function, we add an arbitrary amount of dead weight.
6408   uint8_t dead_weight[123000000];  // 123 MB.
6409 #endif  // !defined(WUFFS_IMPLEMENTATION)
6410 
6411   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_adler32__hasher__struct6412   initialize(
6413       size_t sizeof_star_self,
6414       uint64_t wuffs_version,
6415       uint32_t options) {
6416     return wuffs_adler32__hasher__initialize(
6417         this, sizeof_star_self, wuffs_version, options);
6418   }
6419 
6420   inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6421   upcast_as__wuffs_base__hasher_u32() {
6422     return (wuffs_base__hasher_u32*)this;
6423   }
6424 
6425   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_adler32__hasher__struct6426   set_quirk_enabled(
6427       uint32_t a_quirk,
6428       bool a_enabled) {
6429     return wuffs_adler32__hasher__set_quirk_enabled(this, a_quirk, a_enabled);
6430   }
6431 
6432   inline uint32_t
update_u32wuffs_adler32__hasher__struct6433   update_u32(
6434       wuffs_base__slice_u8 a_x) {
6435     return wuffs_adler32__hasher__update_u32(this, a_x);
6436   }
6437 
6438 #endif  // __cplusplus
6439 };  // struct wuffs_adler32__hasher__struct
6440 
6441 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6442 
6443 // ---------------- Status Codes
6444 
6445 extern const char wuffs_bmp__error__bad_header[];
6446 extern const char wuffs_bmp__error__bad_rle_compression[];
6447 extern const char wuffs_bmp__error__unsupported_bmp_file[];
6448 
6449 // ---------------- Public Consts
6450 
6451 #define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6452 
6453 // ---------------- Struct Declarations
6454 
6455 typedef struct wuffs_bmp__decoder__struct wuffs_bmp__decoder;
6456 
6457 #ifdef __cplusplus
6458 extern "C" {
6459 #endif
6460 
6461 // ---------------- Public Initializer Prototypes
6462 
6463 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6464 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6465 //
6466 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6467 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6468 
6469 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6470 wuffs_bmp__decoder__initialize(
6471     wuffs_bmp__decoder* self,
6472     size_t sizeof_star_self,
6473     uint64_t wuffs_version,
6474     uint32_t options);
6475 
6476 size_t
6477 sizeof__wuffs_bmp__decoder();
6478 
6479 // ---------------- Allocs
6480 
6481 // These functions allocate and initialize Wuffs structs. They return NULL if
6482 // memory allocation fails. If they return non-NULL, there is no need to call
6483 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6484 // calling free on the returned pointer. That pointer is effectively a C++
6485 // std::unique_ptr<T, decltype(&free)>.
6486 
6487 wuffs_bmp__decoder*
6488 wuffs_bmp__decoder__alloc();
6489 
6490 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder()6491 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder() {
6492   return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
6493 }
6494 
6495 // ---------------- Upcasts
6496 
6497 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_bmp__decoder * p)6498 wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
6499     wuffs_bmp__decoder* p) {
6500   return (wuffs_base__image_decoder*)p;
6501 }
6502 
6503 // ---------------- Public Function Prototypes
6504 
6505 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6506 wuffs_bmp__decoder__set_quirk_enabled(
6507     wuffs_bmp__decoder* self,
6508     uint32_t a_quirk,
6509     bool a_enabled);
6510 
6511 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6512 wuffs_bmp__decoder__decode_image_config(
6513     wuffs_bmp__decoder* self,
6514     wuffs_base__image_config* a_dst,
6515     wuffs_base__io_buffer* a_src);
6516 
6517 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6518 wuffs_bmp__decoder__decode_frame_config(
6519     wuffs_bmp__decoder* self,
6520     wuffs_base__frame_config* a_dst,
6521     wuffs_base__io_buffer* a_src);
6522 
6523 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6524 wuffs_bmp__decoder__decode_frame(
6525     wuffs_bmp__decoder* self,
6526     wuffs_base__pixel_buffer* a_dst,
6527     wuffs_base__io_buffer* a_src,
6528     wuffs_base__pixel_blend a_blend,
6529     wuffs_base__slice_u8 a_workbuf,
6530     wuffs_base__decode_frame_options* a_opts);
6531 
6532 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
6533 wuffs_bmp__decoder__frame_dirty_rect(
6534     const wuffs_bmp__decoder* self);
6535 
6536 WUFFS_BASE__MAYBE_STATIC uint32_t
6537 wuffs_bmp__decoder__num_animation_loops(
6538     const wuffs_bmp__decoder* self);
6539 
6540 WUFFS_BASE__MAYBE_STATIC uint64_t
6541 wuffs_bmp__decoder__num_decoded_frame_configs(
6542     const wuffs_bmp__decoder* self);
6543 
6544 WUFFS_BASE__MAYBE_STATIC uint64_t
6545 wuffs_bmp__decoder__num_decoded_frames(
6546     const wuffs_bmp__decoder* self);
6547 
6548 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6549 wuffs_bmp__decoder__restart_frame(
6550     wuffs_bmp__decoder* self,
6551     uint64_t a_index,
6552     uint64_t a_io_position);
6553 
6554 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6555 wuffs_bmp__decoder__set_report_metadata(
6556     wuffs_bmp__decoder* self,
6557     uint32_t a_fourcc,
6558     bool a_report);
6559 
6560 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6561 wuffs_bmp__decoder__tell_me_more(
6562     wuffs_bmp__decoder* self,
6563     wuffs_base__io_buffer* a_dst,
6564     wuffs_base__more_information* a_minfo,
6565     wuffs_base__io_buffer* a_src);
6566 
6567 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6568 wuffs_bmp__decoder__workbuf_len(
6569     const wuffs_bmp__decoder* self);
6570 
6571 #ifdef __cplusplus
6572 }  // extern "C"
6573 #endif
6574 
6575 // ---------------- Struct Definitions
6576 
6577 // These structs' fields, and the sizeof them, are private implementation
6578 // details that aren't guaranteed to be stable across Wuffs versions.
6579 //
6580 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6581 
6582 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6583 
6584 struct wuffs_bmp__decoder__struct {
6585   // Do not access the private_impl's or private_data's fields directly. There
6586   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6587   // the wuffs_foo__bar__baz functions.
6588   //
6589   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6590   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6591 
6592   struct {
6593     uint32_t magic;
6594     uint32_t active_coroutine;
6595     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
6596     wuffs_base__vtable null_vtable;
6597 
6598     uint32_t f_width;
6599     uint32_t f_height;
6600     uint8_t f_call_sequence;
6601     bool f_top_down;
6602     uint32_t f_pad_per_row;
6603     uint32_t f_src_pixfmt;
6604     uint32_t f_io_redirect_fourcc;
6605     uint64_t f_io_redirect_pos;
6606     uint64_t f_frame_config_io_position;
6607     uint32_t f_bitmap_info_len;
6608     uint32_t f_padding;
6609     uint32_t f_bits_per_pixel;
6610     uint32_t f_compression;
6611     uint32_t f_channel_masks[4];
6612     uint8_t f_channel_shifts[4];
6613     uint8_t f_channel_num_bits[4];
6614     uint32_t f_dst_x;
6615     uint32_t f_dst_y;
6616     uint32_t f_dst_y_inc;
6617     uint32_t f_pending_pad;
6618     uint32_t f_rle_state;
6619     uint32_t f_rle_length;
6620     uint8_t f_rle_delta_x;
6621     bool f_rle_padded;
6622     wuffs_base__pixel_swizzler f_swizzler;
6623 
6624     uint32_t p_decode_image_config[1];
6625     uint32_t p_decode_frame_config[1];
6626     uint32_t p_decode_frame[1];
6627     uint32_t p_read_palette[1];
6628   } private_impl;
6629 
6630   struct {
6631     uint8_t f_scratch[2048];
6632     uint8_t f_src_palette[1024];
6633 
6634     struct {
6635       uint64_t scratch;
6636     } s_decode_image_config[1];
6637     struct {
6638       wuffs_base__status v_status;
6639       uint64_t scratch;
6640     } s_decode_frame[1];
6641     struct {
6642       uint32_t v_i;
6643       uint64_t scratch;
6644     } s_read_palette[1];
6645   } private_data;
6646 
6647 #ifdef __cplusplus
6648 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6649   using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, decltype(&free)>;
6650 
6651   // On failure, the alloc_etc functions return nullptr. They don't throw.
6652 
6653   static inline unique_ptr
allocwuffs_bmp__decoder__struct6654   alloc() {
6655     return unique_ptr(wuffs_bmp__decoder__alloc(), &free);
6656   }
6657 
6658   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct6659   alloc_as__wuffs_base__image_decoder() {
6660     return wuffs_base__image_decoder::unique_ptr(
6661         wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
6662   }
6663 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6664 
6665 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6666   // Disallow constructing or copying an object via standard C++ mechanisms,
6667   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6668   // size and field layout is not part of the public, stable, memory-safe API.
6669   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6670   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6671   // their first argument) rather than tweaking bar.private_impl.qux fields.
6672   //
6673   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6674   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6675   // order to provide convenience methods. These forward on "this", so that you
6676   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6677   wuffs_bmp__decoder__struct() = delete;
6678   wuffs_bmp__decoder__struct(const wuffs_bmp__decoder__struct&) = delete;
6679   wuffs_bmp__decoder__struct& operator=(
6680       const wuffs_bmp__decoder__struct&) = delete;
6681 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6682 
6683 #if !defined(WUFFS_IMPLEMENTATION)
6684   // As above, the size of the struct is not part of the public API, and unless
6685   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6686   // allocated, not stack allocated. Its size is not intended to be known at
6687   // compile time, but it is unfortunately divulged as a side effect of
6688   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6689   // instead of "sizeof T", invoking the operator. To make the two values
6690   // different, so that passing the latter will be rejected by the initialize
6691   // function, we add an arbitrary amount of dead weight.
6692   uint8_t dead_weight[123000000];  // 123 MB.
6693 #endif  // !defined(WUFFS_IMPLEMENTATION)
6694 
6695   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_bmp__decoder__struct6696   initialize(
6697       size_t sizeof_star_self,
6698       uint64_t wuffs_version,
6699       uint32_t options) {
6700     return wuffs_bmp__decoder__initialize(
6701         this, sizeof_star_self, wuffs_version, options);
6702   }
6703 
6704   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct6705   upcast_as__wuffs_base__image_decoder() {
6706     return (wuffs_base__image_decoder*)this;
6707   }
6708 
6709   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_bmp__decoder__struct6710   set_quirk_enabled(
6711       uint32_t a_quirk,
6712       bool a_enabled) {
6713     return wuffs_bmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6714   }
6715 
6716   inline wuffs_base__status
decode_image_configwuffs_bmp__decoder__struct6717   decode_image_config(
6718       wuffs_base__image_config* a_dst,
6719       wuffs_base__io_buffer* a_src) {
6720     return wuffs_bmp__decoder__decode_image_config(this, a_dst, a_src);
6721   }
6722 
6723   inline wuffs_base__status
decode_frame_configwuffs_bmp__decoder__struct6724   decode_frame_config(
6725       wuffs_base__frame_config* a_dst,
6726       wuffs_base__io_buffer* a_src) {
6727     return wuffs_bmp__decoder__decode_frame_config(this, a_dst, a_src);
6728   }
6729 
6730   inline wuffs_base__status
decode_framewuffs_bmp__decoder__struct6731   decode_frame(
6732       wuffs_base__pixel_buffer* a_dst,
6733       wuffs_base__io_buffer* a_src,
6734       wuffs_base__pixel_blend a_blend,
6735       wuffs_base__slice_u8 a_workbuf,
6736       wuffs_base__decode_frame_options* a_opts) {
6737     return wuffs_bmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6738   }
6739 
6740   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_bmp__decoder__struct6741   frame_dirty_rect() const {
6742     return wuffs_bmp__decoder__frame_dirty_rect(this);
6743   }
6744 
6745   inline uint32_t
num_animation_loopswuffs_bmp__decoder__struct6746   num_animation_loops() const {
6747     return wuffs_bmp__decoder__num_animation_loops(this);
6748   }
6749 
6750   inline uint64_t
num_decoded_frame_configswuffs_bmp__decoder__struct6751   num_decoded_frame_configs() const {
6752     return wuffs_bmp__decoder__num_decoded_frame_configs(this);
6753   }
6754 
6755   inline uint64_t
num_decoded_frameswuffs_bmp__decoder__struct6756   num_decoded_frames() const {
6757     return wuffs_bmp__decoder__num_decoded_frames(this);
6758   }
6759 
6760   inline wuffs_base__status
restart_framewuffs_bmp__decoder__struct6761   restart_frame(
6762       uint64_t a_index,
6763       uint64_t a_io_position) {
6764     return wuffs_bmp__decoder__restart_frame(this, a_index, a_io_position);
6765   }
6766 
6767   inline wuffs_base__empty_struct
set_report_metadatawuffs_bmp__decoder__struct6768   set_report_metadata(
6769       uint32_t a_fourcc,
6770       bool a_report) {
6771     return wuffs_bmp__decoder__set_report_metadata(this, a_fourcc, a_report);
6772   }
6773 
6774   inline wuffs_base__status
tell_me_morewuffs_bmp__decoder__struct6775   tell_me_more(
6776       wuffs_base__io_buffer* a_dst,
6777       wuffs_base__more_information* a_minfo,
6778       wuffs_base__io_buffer* a_src) {
6779     return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
6780   }
6781 
6782   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_bmp__decoder__struct6783   workbuf_len() const {
6784     return wuffs_bmp__decoder__workbuf_len(this);
6785   }
6786 
6787 #endif  // __cplusplus
6788 };  // struct wuffs_bmp__decoder__struct
6789 
6790 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6791 
6792 // ---------------- Status Codes
6793 
6794 extern const char wuffs_cbor__error__bad_input[];
6795 extern const char wuffs_cbor__error__unsupported_recursion_depth[];
6796 
6797 // ---------------- Public Consts
6798 
6799 #define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6800 
6801 #define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024
6802 
6803 #define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2
6804 
6805 #define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9
6806 
6807 #define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997
6808 
6809 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143
6810 
6811 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216
6812 
6813 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608
6814 
6815 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304
6816 
6817 // ---------------- Struct Declarations
6818 
6819 typedef struct wuffs_cbor__decoder__struct wuffs_cbor__decoder;
6820 
6821 #ifdef __cplusplus
6822 extern "C" {
6823 #endif
6824 
6825 // ---------------- Public Initializer Prototypes
6826 
6827 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6828 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6829 //
6830 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6831 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6832 
6833 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6834 wuffs_cbor__decoder__initialize(
6835     wuffs_cbor__decoder* self,
6836     size_t sizeof_star_self,
6837     uint64_t wuffs_version,
6838     uint32_t options);
6839 
6840 size_t
6841 sizeof__wuffs_cbor__decoder();
6842 
6843 // ---------------- Allocs
6844 
6845 // These functions allocate and initialize Wuffs structs. They return NULL if
6846 // memory allocation fails. If they return non-NULL, there is no need to call
6847 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6848 // calling free on the returned pointer. That pointer is effectively a C++
6849 // std::unique_ptr<T, decltype(&free)>.
6850 
6851 wuffs_cbor__decoder*
6852 wuffs_cbor__decoder__alloc();
6853 
6854 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder()6855 wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder() {
6856   return (wuffs_base__token_decoder*)(wuffs_cbor__decoder__alloc());
6857 }
6858 
6859 // ---------------- Upcasts
6860 
6861 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(wuffs_cbor__decoder * p)6862 wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(
6863     wuffs_cbor__decoder* p) {
6864   return (wuffs_base__token_decoder*)p;
6865 }
6866 
6867 // ---------------- Public Function Prototypes
6868 
6869 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6870 wuffs_cbor__decoder__set_quirk_enabled(
6871     wuffs_cbor__decoder* self,
6872     uint32_t a_quirk,
6873     bool a_enabled);
6874 
6875 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6876 wuffs_cbor__decoder__workbuf_len(
6877     const wuffs_cbor__decoder* self);
6878 
6879 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6880 wuffs_cbor__decoder__decode_tokens(
6881     wuffs_cbor__decoder* self,
6882     wuffs_base__token_buffer* a_dst,
6883     wuffs_base__io_buffer* a_src,
6884     wuffs_base__slice_u8 a_workbuf);
6885 
6886 #ifdef __cplusplus
6887 }  // extern "C"
6888 #endif
6889 
6890 // ---------------- Struct Definitions
6891 
6892 // These structs' fields, and the sizeof them, are private implementation
6893 // details that aren't guaranteed to be stable across Wuffs versions.
6894 //
6895 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6896 
6897 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6898 
6899 struct wuffs_cbor__decoder__struct {
6900   // Do not access the private_impl's or private_data's fields directly. There
6901   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6902   // the wuffs_foo__bar__baz functions.
6903   //
6904   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6905   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6906 
6907   struct {
6908     uint32_t magic;
6909     uint32_t active_coroutine;
6910     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
6911     wuffs_base__vtable null_vtable;
6912 
6913     bool f_end_of_data;
6914 
6915     uint32_t p_decode_tokens[1];
6916   } private_impl;
6917 
6918   struct {
6919     uint32_t f_stack[64];
6920     uint64_t f_container_num_remaining[1024];
6921 
6922     struct {
6923       uint64_t v_string_length;
6924       uint32_t v_depth;
6925       uint32_t v_token_length;
6926       bool v_tagged;
6927       uint8_t v_indefinite_string_major_type;
6928     } s_decode_tokens[1];
6929   } private_data;
6930 
6931 #ifdef __cplusplus
6932 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6933   using unique_ptr = std::unique_ptr<wuffs_cbor__decoder, decltype(&free)>;
6934 
6935   // On failure, the alloc_etc functions return nullptr. They don't throw.
6936 
6937   static inline unique_ptr
allocwuffs_cbor__decoder__struct6938   alloc() {
6939     return unique_ptr(wuffs_cbor__decoder__alloc(), &free);
6940   }
6941 
6942   static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct6943   alloc_as__wuffs_base__token_decoder() {
6944     return wuffs_base__token_decoder::unique_ptr(
6945         wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder(), &free);
6946   }
6947 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6948 
6949 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6950   // Disallow constructing or copying an object via standard C++ mechanisms,
6951   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6952   // size and field layout is not part of the public, stable, memory-safe API.
6953   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6954   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6955   // their first argument) rather than tweaking bar.private_impl.qux fields.
6956   //
6957   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6958   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6959   // order to provide convenience methods. These forward on "this", so that you
6960   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6961   wuffs_cbor__decoder__struct() = delete;
6962   wuffs_cbor__decoder__struct(const wuffs_cbor__decoder__struct&) = delete;
6963   wuffs_cbor__decoder__struct& operator=(
6964       const wuffs_cbor__decoder__struct&) = delete;
6965 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6966 
6967 #if !defined(WUFFS_IMPLEMENTATION)
6968   // As above, the size of the struct is not part of the public API, and unless
6969   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6970   // allocated, not stack allocated. Its size is not intended to be known at
6971   // compile time, but it is unfortunately divulged as a side effect of
6972   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6973   // instead of "sizeof T", invoking the operator. To make the two values
6974   // different, so that passing the latter will be rejected by the initialize
6975   // function, we add an arbitrary amount of dead weight.
6976   uint8_t dead_weight[123000000];  // 123 MB.
6977 #endif  // !defined(WUFFS_IMPLEMENTATION)
6978 
6979   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_cbor__decoder__struct6980   initialize(
6981       size_t sizeof_star_self,
6982       uint64_t wuffs_version,
6983       uint32_t options) {
6984     return wuffs_cbor__decoder__initialize(
6985         this, sizeof_star_self, wuffs_version, options);
6986   }
6987 
6988   inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct6989   upcast_as__wuffs_base__token_decoder() {
6990     return (wuffs_base__token_decoder*)this;
6991   }
6992 
6993   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_cbor__decoder__struct6994   set_quirk_enabled(
6995       uint32_t a_quirk,
6996       bool a_enabled) {
6997     return wuffs_cbor__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6998   }
6999 
7000   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_cbor__decoder__struct7001   workbuf_len() const {
7002     return wuffs_cbor__decoder__workbuf_len(this);
7003   }
7004 
7005   inline wuffs_base__status
decode_tokenswuffs_cbor__decoder__struct7006   decode_tokens(
7007       wuffs_base__token_buffer* a_dst,
7008       wuffs_base__io_buffer* a_src,
7009       wuffs_base__slice_u8 a_workbuf) {
7010     return wuffs_cbor__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
7011   }
7012 
7013 #endif  // __cplusplus
7014 };  // struct wuffs_cbor__decoder__struct
7015 
7016 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7017 
7018 // ---------------- Status Codes
7019 
7020 // ---------------- Public Consts
7021 
7022 // ---------------- Struct Declarations
7023 
7024 typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
7025 
7026 #ifdef __cplusplus
7027 extern "C" {
7028 #endif
7029 
7030 // ---------------- Public Initializer Prototypes
7031 
7032 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7033 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7034 //
7035 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7036 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7037 
7038 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7039 wuffs_crc32__ieee_hasher__initialize(
7040     wuffs_crc32__ieee_hasher* self,
7041     size_t sizeof_star_self,
7042     uint64_t wuffs_version,
7043     uint32_t options);
7044 
7045 size_t
7046 sizeof__wuffs_crc32__ieee_hasher();
7047 
7048 // ---------------- Allocs
7049 
7050 // These functions allocate and initialize Wuffs structs. They return NULL if
7051 // memory allocation fails. If they return non-NULL, there is no need to call
7052 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7053 // calling free on the returned pointer. That pointer is effectively a C++
7054 // std::unique_ptr<T, decltype(&free)>.
7055 
7056 wuffs_crc32__ieee_hasher*
7057 wuffs_crc32__ieee_hasher__alloc();
7058 
7059 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32()7060 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32() {
7061   return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
7062 }
7063 
7064 // ---------------- Upcasts
7065 
7066 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(wuffs_crc32__ieee_hasher * p)7067 wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(
7068     wuffs_crc32__ieee_hasher* p) {
7069   return (wuffs_base__hasher_u32*)p;
7070 }
7071 
7072 // ---------------- Public Function Prototypes
7073 
7074 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7075 wuffs_crc32__ieee_hasher__set_quirk_enabled(
7076     wuffs_crc32__ieee_hasher* self,
7077     uint32_t a_quirk,
7078     bool a_enabled);
7079 
7080 WUFFS_BASE__MAYBE_STATIC uint32_t
7081 wuffs_crc32__ieee_hasher__update_u32(
7082     wuffs_crc32__ieee_hasher* self,
7083     wuffs_base__slice_u8 a_x);
7084 
7085 #ifdef __cplusplus
7086 }  // extern "C"
7087 #endif
7088 
7089 // ---------------- Struct Definitions
7090 
7091 // These structs' fields, and the sizeof them, are private implementation
7092 // details that aren't guaranteed to be stable across Wuffs versions.
7093 //
7094 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7095 
7096 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7097 
7098 struct wuffs_crc32__ieee_hasher__struct {
7099   // Do not access the private_impl's or private_data's fields directly. There
7100   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7101   // the wuffs_foo__bar__baz functions.
7102   //
7103   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7104   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7105 
7106   struct {
7107     uint32_t magic;
7108     uint32_t active_coroutine;
7109     wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
7110     wuffs_base__vtable null_vtable;
7111 
7112     uint32_t f_state;
7113 
7114     wuffs_base__empty_struct (*choosy_up)(
7115         wuffs_crc32__ieee_hasher* self,
7116         wuffs_base__slice_u8 a_x);
7117   } private_impl;
7118 
7119 #ifdef __cplusplus
7120 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7121   using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, decltype(&free)>;
7122 
7123   // On failure, the alloc_etc functions return nullptr. They don't throw.
7124 
7125   static inline unique_ptr
allocwuffs_crc32__ieee_hasher__struct7126   alloc() {
7127     return unique_ptr(wuffs_crc32__ieee_hasher__alloc(), &free);
7128   }
7129 
7130   static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct7131   alloc_as__wuffs_base__hasher_u32() {
7132     return wuffs_base__hasher_u32::unique_ptr(
7133         wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(), &free);
7134   }
7135 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7136 
7137 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7138   // Disallow constructing or copying an object via standard C++ mechanisms,
7139   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7140   // size and field layout is not part of the public, stable, memory-safe API.
7141   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7142   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7143   // their first argument) rather than tweaking bar.private_impl.qux fields.
7144   //
7145   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7146   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7147   // order to provide convenience methods. These forward on "this", so that you
7148   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7149   wuffs_crc32__ieee_hasher__struct() = delete;
7150   wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) = delete;
7151   wuffs_crc32__ieee_hasher__struct& operator=(
7152       const wuffs_crc32__ieee_hasher__struct&) = delete;
7153 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7154 
7155 #if !defined(WUFFS_IMPLEMENTATION)
7156   // As above, the size of the struct is not part of the public API, and unless
7157   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7158   // allocated, not stack allocated. Its size is not intended to be known at
7159   // compile time, but it is unfortunately divulged as a side effect of
7160   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7161   // instead of "sizeof T", invoking the operator. To make the two values
7162   // different, so that passing the latter will be rejected by the initialize
7163   // function, we add an arbitrary amount of dead weight.
7164   uint8_t dead_weight[123000000];  // 123 MB.
7165 #endif  // !defined(WUFFS_IMPLEMENTATION)
7166 
7167   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_crc32__ieee_hasher__struct7168   initialize(
7169       size_t sizeof_star_self,
7170       uint64_t wuffs_version,
7171       uint32_t options) {
7172     return wuffs_crc32__ieee_hasher__initialize(
7173         this, sizeof_star_self, wuffs_version, options);
7174   }
7175 
7176   inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct7177   upcast_as__wuffs_base__hasher_u32() {
7178     return (wuffs_base__hasher_u32*)this;
7179   }
7180 
7181   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_crc32__ieee_hasher__struct7182   set_quirk_enabled(
7183       uint32_t a_quirk,
7184       bool a_enabled) {
7185     return wuffs_crc32__ieee_hasher__set_quirk_enabled(this, a_quirk, a_enabled);
7186   }
7187 
7188   inline uint32_t
update_u32wuffs_crc32__ieee_hasher__struct7189   update_u32(
7190       wuffs_base__slice_u8 a_x) {
7191     return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
7192   }
7193 
7194 #endif  // __cplusplus
7195 };  // struct wuffs_crc32__ieee_hasher__struct
7196 
7197 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7198 
7199 // ---------------- Status Codes
7200 
7201 extern const char wuffs_deflate__error__bad_huffman_code_over_subscribed[];
7202 extern const char wuffs_deflate__error__bad_huffman_code_under_subscribed[];
7203 extern const char wuffs_deflate__error__bad_huffman_code_length_count[];
7204 extern const char wuffs_deflate__error__bad_huffman_code_length_repetition[];
7205 extern const char wuffs_deflate__error__bad_huffman_code[];
7206 extern const char wuffs_deflate__error__bad_huffman_minimum_code_length[];
7207 extern const char wuffs_deflate__error__bad_block[];
7208 extern const char wuffs_deflate__error__bad_distance[];
7209 extern const char wuffs_deflate__error__bad_distance_code_count[];
7210 extern const char wuffs_deflate__error__bad_literal_length_code_count[];
7211 extern const char wuffs_deflate__error__inconsistent_stored_block_length[];
7212 extern const char wuffs_deflate__error__missing_end_of_block_code[];
7213 extern const char wuffs_deflate__error__no_huffman_codes[];
7214 
7215 // ---------------- Public Consts
7216 
7217 #define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
7218 
7219 // ---------------- Struct Declarations
7220 
7221 typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
7222 
7223 #ifdef __cplusplus
7224 extern "C" {
7225 #endif
7226 
7227 // ---------------- Public Initializer Prototypes
7228 
7229 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7230 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7231 //
7232 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7233 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7234 
7235 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7236 wuffs_deflate__decoder__initialize(
7237     wuffs_deflate__decoder* self,
7238     size_t sizeof_star_self,
7239     uint64_t wuffs_version,
7240     uint32_t options);
7241 
7242 size_t
7243 sizeof__wuffs_deflate__decoder();
7244 
7245 // ---------------- Allocs
7246 
7247 // These functions allocate and initialize Wuffs structs. They return NULL if
7248 // memory allocation fails. If they return non-NULL, there is no need to call
7249 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7250 // calling free on the returned pointer. That pointer is effectively a C++
7251 // std::unique_ptr<T, decltype(&free)>.
7252 
7253 wuffs_deflate__decoder*
7254 wuffs_deflate__decoder__alloc();
7255 
7256 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer()7257 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer() {
7258   return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
7259 }
7260 
7261 // ---------------- Upcasts
7262 
7263 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(wuffs_deflate__decoder * p)7264 wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(
7265     wuffs_deflate__decoder* p) {
7266   return (wuffs_base__io_transformer*)p;
7267 }
7268 
7269 // ---------------- Public Function Prototypes
7270 
7271 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7272 wuffs_deflate__decoder__add_history(
7273     wuffs_deflate__decoder* self,
7274     wuffs_base__slice_u8 a_hist);
7275 
7276 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7277 wuffs_deflate__decoder__set_quirk_enabled(
7278     wuffs_deflate__decoder* self,
7279     uint32_t a_quirk,
7280     bool a_enabled);
7281 
7282 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7283 wuffs_deflate__decoder__workbuf_len(
7284     const wuffs_deflate__decoder* self);
7285 
7286 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7287 wuffs_deflate__decoder__transform_io(
7288     wuffs_deflate__decoder* self,
7289     wuffs_base__io_buffer* a_dst,
7290     wuffs_base__io_buffer* a_src,
7291     wuffs_base__slice_u8 a_workbuf);
7292 
7293 #ifdef __cplusplus
7294 }  // extern "C"
7295 #endif
7296 
7297 // ---------------- Struct Definitions
7298 
7299 // These structs' fields, and the sizeof them, are private implementation
7300 // details that aren't guaranteed to be stable across Wuffs versions.
7301 //
7302 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7303 
7304 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7305 
7306 struct wuffs_deflate__decoder__struct {
7307   // Do not access the private_impl's or private_data's fields directly. There
7308   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7309   // the wuffs_foo__bar__baz functions.
7310   //
7311   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7312   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7313 
7314   struct {
7315     uint32_t magic;
7316     uint32_t active_coroutine;
7317     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7318     wuffs_base__vtable null_vtable;
7319 
7320     uint32_t f_bits;
7321     uint32_t f_n_bits;
7322     uint64_t f_transformed_history_count;
7323     uint32_t f_history_index;
7324     uint32_t f_n_huffs_bits[2];
7325     bool f_end_of_block;
7326 
7327     uint32_t p_transform_io[1];
7328     uint32_t p_decode_blocks[1];
7329     uint32_t p_decode_uncompressed[1];
7330     uint32_t p_init_dynamic_huffman[1];
7331     wuffs_base__status (*choosy_decode_huffman_fast64)(
7332         wuffs_deflate__decoder* self,
7333         wuffs_base__io_buffer* a_dst,
7334         wuffs_base__io_buffer* a_src);
7335     uint32_t p_decode_huffman_slow[1];
7336   } private_impl;
7337 
7338   struct {
7339     uint32_t f_huffs[2][1024];
7340     uint8_t f_history[33025];
7341     uint8_t f_code_lengths[320];
7342 
7343     struct {
7344       uint32_t v_final;
7345     } s_decode_blocks[1];
7346     struct {
7347       uint32_t v_length;
7348       uint64_t scratch;
7349     } s_decode_uncompressed[1];
7350     struct {
7351       uint32_t v_bits;
7352       uint32_t v_n_bits;
7353       uint32_t v_n_lit;
7354       uint32_t v_n_dist;
7355       uint32_t v_n_clen;
7356       uint32_t v_i;
7357       uint32_t v_mask;
7358       uint32_t v_table_entry;
7359       uint32_t v_n_extra_bits;
7360       uint8_t v_rep_symbol;
7361       uint32_t v_rep_count;
7362     } s_init_dynamic_huffman[1];
7363     struct {
7364       uint32_t v_bits;
7365       uint32_t v_n_bits;
7366       uint32_t v_table_entry;
7367       uint32_t v_table_entry_n_bits;
7368       uint32_t v_lmask;
7369       uint32_t v_dmask;
7370       uint32_t v_redir_top;
7371       uint32_t v_redir_mask;
7372       uint32_t v_length;
7373       uint32_t v_dist_minus_1;
7374       uint32_t v_hlen;
7375       uint64_t scratch;
7376     } s_decode_huffman_slow[1];
7377   } private_data;
7378 
7379 #ifdef __cplusplus
7380 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7381   using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, decltype(&free)>;
7382 
7383   // On failure, the alloc_etc functions return nullptr. They don't throw.
7384 
7385   static inline unique_ptr
allocwuffs_deflate__decoder__struct7386   alloc() {
7387     return unique_ptr(wuffs_deflate__decoder__alloc(), &free);
7388   }
7389 
7390   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct7391   alloc_as__wuffs_base__io_transformer() {
7392     return wuffs_base__io_transformer::unique_ptr(
7393         wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(), &free);
7394   }
7395 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7396 
7397 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7398   // Disallow constructing or copying an object via standard C++ mechanisms,
7399   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7400   // size and field layout is not part of the public, stable, memory-safe API.
7401   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7402   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7403   // their first argument) rather than tweaking bar.private_impl.qux fields.
7404   //
7405   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7406   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7407   // order to provide convenience methods. These forward on "this", so that you
7408   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7409   wuffs_deflate__decoder__struct() = delete;
7410   wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = delete;
7411   wuffs_deflate__decoder__struct& operator=(
7412       const wuffs_deflate__decoder__struct&) = delete;
7413 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7414 
7415 #if !defined(WUFFS_IMPLEMENTATION)
7416   // As above, the size of the struct is not part of the public API, and unless
7417   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7418   // allocated, not stack allocated. Its size is not intended to be known at
7419   // compile time, but it is unfortunately divulged as a side effect of
7420   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7421   // instead of "sizeof T", invoking the operator. To make the two values
7422   // different, so that passing the latter will be rejected by the initialize
7423   // function, we add an arbitrary amount of dead weight.
7424   uint8_t dead_weight[123000000];  // 123 MB.
7425 #endif  // !defined(WUFFS_IMPLEMENTATION)
7426 
7427   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_deflate__decoder__struct7428   initialize(
7429       size_t sizeof_star_self,
7430       uint64_t wuffs_version,
7431       uint32_t options) {
7432     return wuffs_deflate__decoder__initialize(
7433         this, sizeof_star_self, wuffs_version, options);
7434   }
7435 
7436   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct7437   upcast_as__wuffs_base__io_transformer() {
7438     return (wuffs_base__io_transformer*)this;
7439   }
7440 
7441   inline wuffs_base__empty_struct
add_historywuffs_deflate__decoder__struct7442   add_history(
7443       wuffs_base__slice_u8 a_hist) {
7444     return wuffs_deflate__decoder__add_history(this, a_hist);
7445   }
7446 
7447   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_deflate__decoder__struct7448   set_quirk_enabled(
7449       uint32_t a_quirk,
7450       bool a_enabled) {
7451     return wuffs_deflate__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7452   }
7453 
7454   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_deflate__decoder__struct7455   workbuf_len() const {
7456     return wuffs_deflate__decoder__workbuf_len(this);
7457   }
7458 
7459   inline wuffs_base__status
transform_iowuffs_deflate__decoder__struct7460   transform_io(
7461       wuffs_base__io_buffer* a_dst,
7462       wuffs_base__io_buffer* a_src,
7463       wuffs_base__slice_u8 a_workbuf) {
7464     return wuffs_deflate__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7465   }
7466 
7467 #endif  // __cplusplus
7468 };  // struct wuffs_deflate__decoder__struct
7469 
7470 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7471 
7472 // ---------------- Status Codes
7473 
7474 extern const char wuffs_lzw__error__bad_code[];
7475 
7476 // ---------------- Public Consts
7477 
7478 #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7479 
7480 // ---------------- Struct Declarations
7481 
7482 typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
7483 
7484 #ifdef __cplusplus
7485 extern "C" {
7486 #endif
7487 
7488 // ---------------- Public Initializer Prototypes
7489 
7490 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7491 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7492 //
7493 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7494 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7495 
7496 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7497 wuffs_lzw__decoder__initialize(
7498     wuffs_lzw__decoder* self,
7499     size_t sizeof_star_self,
7500     uint64_t wuffs_version,
7501     uint32_t options);
7502 
7503 size_t
7504 sizeof__wuffs_lzw__decoder();
7505 
7506 // ---------------- Allocs
7507 
7508 // These functions allocate and initialize Wuffs structs. They return NULL if
7509 // memory allocation fails. If they return non-NULL, there is no need to call
7510 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7511 // calling free on the returned pointer. That pointer is effectively a C++
7512 // std::unique_ptr<T, decltype(&free)>.
7513 
7514 wuffs_lzw__decoder*
7515 wuffs_lzw__decoder__alloc();
7516 
7517 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer()7518 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer() {
7519   return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
7520 }
7521 
7522 // ---------------- Upcasts
7523 
7524 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(wuffs_lzw__decoder * p)7525 wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(
7526     wuffs_lzw__decoder* p) {
7527   return (wuffs_base__io_transformer*)p;
7528 }
7529 
7530 // ---------------- Public Function Prototypes
7531 
7532 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7533 wuffs_lzw__decoder__set_quirk_enabled(
7534     wuffs_lzw__decoder* self,
7535     uint32_t a_quirk,
7536     bool a_enabled);
7537 
7538 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7539 wuffs_lzw__decoder__set_literal_width(
7540     wuffs_lzw__decoder* self,
7541     uint32_t a_lw);
7542 
7543 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7544 wuffs_lzw__decoder__workbuf_len(
7545     const wuffs_lzw__decoder* self);
7546 
7547 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7548 wuffs_lzw__decoder__transform_io(
7549     wuffs_lzw__decoder* self,
7550     wuffs_base__io_buffer* a_dst,
7551     wuffs_base__io_buffer* a_src,
7552     wuffs_base__slice_u8 a_workbuf);
7553 
7554 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
7555 wuffs_lzw__decoder__flush(
7556     wuffs_lzw__decoder* self);
7557 
7558 #ifdef __cplusplus
7559 }  // extern "C"
7560 #endif
7561 
7562 // ---------------- Struct Definitions
7563 
7564 // These structs' fields, and the sizeof them, are private implementation
7565 // details that aren't guaranteed to be stable across Wuffs versions.
7566 //
7567 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7568 
7569 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7570 
7571 struct wuffs_lzw__decoder__struct {
7572   // Do not access the private_impl's or private_data's fields directly. There
7573   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7574   // the wuffs_foo__bar__baz functions.
7575   //
7576   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7577   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7578 
7579   struct {
7580     uint32_t magic;
7581     uint32_t active_coroutine;
7582     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7583     wuffs_base__vtable null_vtable;
7584 
7585     uint32_t f_set_literal_width_arg;
7586     uint32_t f_literal_width;
7587     uint32_t f_clear_code;
7588     uint32_t f_end_code;
7589     uint32_t f_save_code;
7590     uint32_t f_prev_code;
7591     uint32_t f_width;
7592     uint32_t f_bits;
7593     uint32_t f_n_bits;
7594     uint32_t f_output_ri;
7595     uint32_t f_output_wi;
7596     uint32_t f_read_from_return_value;
7597     uint16_t f_prefixes[4096];
7598 
7599     uint32_t p_transform_io[1];
7600     uint32_t p_write_to[1];
7601   } private_impl;
7602 
7603   struct {
7604     uint8_t f_suffixes[4096][8];
7605     uint16_t f_lm1s[4096];
7606     uint8_t f_output[8199];
7607   } private_data;
7608 
7609 #ifdef __cplusplus
7610 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7611   using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, decltype(&free)>;
7612 
7613   // On failure, the alloc_etc functions return nullptr. They don't throw.
7614 
7615   static inline unique_ptr
allocwuffs_lzw__decoder__struct7616   alloc() {
7617     return unique_ptr(wuffs_lzw__decoder__alloc(), &free);
7618   }
7619 
7620   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct7621   alloc_as__wuffs_base__io_transformer() {
7622     return wuffs_base__io_transformer::unique_ptr(
7623         wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(), &free);
7624   }
7625 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7626 
7627 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7628   // Disallow constructing or copying an object via standard C++ mechanisms,
7629   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7630   // size and field layout is not part of the public, stable, memory-safe API.
7631   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7632   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7633   // their first argument) rather than tweaking bar.private_impl.qux fields.
7634   //
7635   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7636   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7637   // order to provide convenience methods. These forward on "this", so that you
7638   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7639   wuffs_lzw__decoder__struct() = delete;
7640   wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
7641   wuffs_lzw__decoder__struct& operator=(
7642       const wuffs_lzw__decoder__struct&) = delete;
7643 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7644 
7645 #if !defined(WUFFS_IMPLEMENTATION)
7646   // As above, the size of the struct is not part of the public API, and unless
7647   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7648   // allocated, not stack allocated. Its size is not intended to be known at
7649   // compile time, but it is unfortunately divulged as a side effect of
7650   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7651   // instead of "sizeof T", invoking the operator. To make the two values
7652   // different, so that passing the latter will be rejected by the initialize
7653   // function, we add an arbitrary amount of dead weight.
7654   uint8_t dead_weight[123000000];  // 123 MB.
7655 #endif  // !defined(WUFFS_IMPLEMENTATION)
7656 
7657   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_lzw__decoder__struct7658   initialize(
7659       size_t sizeof_star_self,
7660       uint64_t wuffs_version,
7661       uint32_t options) {
7662     return wuffs_lzw__decoder__initialize(
7663         this, sizeof_star_self, wuffs_version, options);
7664   }
7665 
7666   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct7667   upcast_as__wuffs_base__io_transformer() {
7668     return (wuffs_base__io_transformer*)this;
7669   }
7670 
7671   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_lzw__decoder__struct7672   set_quirk_enabled(
7673       uint32_t a_quirk,
7674       bool a_enabled) {
7675     return wuffs_lzw__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7676   }
7677 
7678   inline wuffs_base__empty_struct
set_literal_widthwuffs_lzw__decoder__struct7679   set_literal_width(
7680       uint32_t a_lw) {
7681     return wuffs_lzw__decoder__set_literal_width(this, a_lw);
7682   }
7683 
7684   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_lzw__decoder__struct7685   workbuf_len() const {
7686     return wuffs_lzw__decoder__workbuf_len(this);
7687   }
7688 
7689   inline wuffs_base__status
transform_iowuffs_lzw__decoder__struct7690   transform_io(
7691       wuffs_base__io_buffer* a_dst,
7692       wuffs_base__io_buffer* a_src,
7693       wuffs_base__slice_u8 a_workbuf) {
7694     return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7695   }
7696 
7697   inline wuffs_base__slice_u8
flushwuffs_lzw__decoder__struct7698   flush() {
7699     return wuffs_lzw__decoder__flush(this);
7700   }
7701 
7702 #endif  // __cplusplus
7703 };  // struct wuffs_lzw__decoder__struct
7704 
7705 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7706 
7707 // ---------------- Status Codes
7708 
7709 extern const char wuffs_gif__error__bad_extension_label[];
7710 extern const char wuffs_gif__error__bad_frame_size[];
7711 extern const char wuffs_gif__error__bad_graphic_control[];
7712 extern const char wuffs_gif__error__bad_header[];
7713 extern const char wuffs_gif__error__bad_literal_width[];
7714 extern const char wuffs_gif__error__bad_palette[];
7715 
7716 // ---------------- Public Consts
7717 
7718 #define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7719 
7720 #define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328
7721 
7722 #define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329
7723 
7724 #define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330
7725 
7726 #define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331
7727 
7728 #define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332
7729 
7730 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333
7731 
7732 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334
7733 
7734 // ---------------- Struct Declarations
7735 
7736 typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder;
7737 
7738 #ifdef __cplusplus
7739 extern "C" {
7740 #endif
7741 
7742 // ---------------- Public Initializer Prototypes
7743 
7744 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7745 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7746 //
7747 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7748 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7749 
7750 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7751 wuffs_gif__decoder__initialize(
7752     wuffs_gif__decoder* self,
7753     size_t sizeof_star_self,
7754     uint64_t wuffs_version,
7755     uint32_t options);
7756 
7757 size_t
7758 sizeof__wuffs_gif__decoder();
7759 
7760 // ---------------- Allocs
7761 
7762 // These functions allocate and initialize Wuffs structs. They return NULL if
7763 // memory allocation fails. If they return non-NULL, there is no need to call
7764 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7765 // calling free on the returned pointer. That pointer is effectively a C++
7766 // std::unique_ptr<T, decltype(&free)>.
7767 
7768 wuffs_gif__decoder*
7769 wuffs_gif__decoder__alloc();
7770 
7771 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder()7772 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder() {
7773   return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
7774 }
7775 
7776 // ---------------- Upcasts
7777 
7778 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(wuffs_gif__decoder * p)7779 wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
7780     wuffs_gif__decoder* p) {
7781   return (wuffs_base__image_decoder*)p;
7782 }
7783 
7784 // ---------------- Public Function Prototypes
7785 
7786 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7787 wuffs_gif__decoder__set_quirk_enabled(
7788     wuffs_gif__decoder* self,
7789     uint32_t a_quirk,
7790     bool a_enabled);
7791 
7792 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7793 wuffs_gif__decoder__decode_image_config(
7794     wuffs_gif__decoder* self,
7795     wuffs_base__image_config* a_dst,
7796     wuffs_base__io_buffer* a_src);
7797 
7798 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7799 wuffs_gif__decoder__set_report_metadata(
7800     wuffs_gif__decoder* self,
7801     uint32_t a_fourcc,
7802     bool a_report);
7803 
7804 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7805 wuffs_gif__decoder__tell_me_more(
7806     wuffs_gif__decoder* self,
7807     wuffs_base__io_buffer* a_dst,
7808     wuffs_base__more_information* a_minfo,
7809     wuffs_base__io_buffer* a_src);
7810 
7811 WUFFS_BASE__MAYBE_STATIC uint32_t
7812 wuffs_gif__decoder__num_animation_loops(
7813     const wuffs_gif__decoder* self);
7814 
7815 WUFFS_BASE__MAYBE_STATIC uint64_t
7816 wuffs_gif__decoder__num_decoded_frame_configs(
7817     const wuffs_gif__decoder* self);
7818 
7819 WUFFS_BASE__MAYBE_STATIC uint64_t
7820 wuffs_gif__decoder__num_decoded_frames(
7821     const wuffs_gif__decoder* self);
7822 
7823 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
7824 wuffs_gif__decoder__frame_dirty_rect(
7825     const wuffs_gif__decoder* self);
7826 
7827 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7828 wuffs_gif__decoder__workbuf_len(
7829     const wuffs_gif__decoder* self);
7830 
7831 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7832 wuffs_gif__decoder__restart_frame(
7833     wuffs_gif__decoder* self,
7834     uint64_t a_index,
7835     uint64_t a_io_position);
7836 
7837 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7838 wuffs_gif__decoder__decode_frame_config(
7839     wuffs_gif__decoder* self,
7840     wuffs_base__frame_config* a_dst,
7841     wuffs_base__io_buffer* a_src);
7842 
7843 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7844 wuffs_gif__decoder__decode_frame(
7845     wuffs_gif__decoder* self,
7846     wuffs_base__pixel_buffer* a_dst,
7847     wuffs_base__io_buffer* a_src,
7848     wuffs_base__pixel_blend a_blend,
7849     wuffs_base__slice_u8 a_workbuf,
7850     wuffs_base__decode_frame_options* a_opts);
7851 
7852 #ifdef __cplusplus
7853 }  // extern "C"
7854 #endif
7855 
7856 // ---------------- Struct Definitions
7857 
7858 // These structs' fields, and the sizeof them, are private implementation
7859 // details that aren't guaranteed to be stable across Wuffs versions.
7860 //
7861 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7862 
7863 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7864 
7865 struct wuffs_gif__decoder__struct {
7866   // Do not access the private_impl's or private_data's fields directly. There
7867   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7868   // the wuffs_foo__bar__baz functions.
7869   //
7870   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7871   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7872 
7873   struct {
7874     uint32_t magic;
7875     uint32_t active_coroutine;
7876     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
7877     wuffs_base__vtable null_vtable;
7878 
7879     uint32_t f_width;
7880     uint32_t f_height;
7881     uint8_t f_call_sequence;
7882     bool f_ignore_metadata;
7883     bool f_report_metadata_iccp;
7884     bool f_report_metadata_xmp;
7885     uint32_t f_metadata_fourcc;
7886     uint64_t f_metadata_io_position;
7887     bool f_quirks[7];
7888     bool f_delayed_num_decoded_frames;
7889     bool f_end_of_data;
7890     bool f_restarted;
7891     bool f_previous_lzw_decode_ended_abruptly;
7892     bool f_has_global_palette;
7893     uint8_t f_interlace;
7894     bool f_seen_num_animation_loops_value;
7895     uint32_t f_num_animation_loops_value;
7896     uint32_t f_background_color_u32_argb_premul;
7897     uint32_t f_black_color_u32_argb_premul;
7898     bool f_gc_has_transparent_index;
7899     uint8_t f_gc_transparent_index;
7900     uint8_t f_gc_disposal;
7901     uint64_t f_gc_duration;
7902     uint64_t f_frame_config_io_position;
7903     uint64_t f_num_decoded_frame_configs_value;
7904     uint64_t f_num_decoded_frames_value;
7905     uint32_t f_frame_rect_x0;
7906     uint32_t f_frame_rect_y0;
7907     uint32_t f_frame_rect_x1;
7908     uint32_t f_frame_rect_y1;
7909     uint32_t f_dst_x;
7910     uint32_t f_dst_y;
7911     uint32_t f_dirty_max_excl_y;
7912     uint64_t f_compressed_ri;
7913     uint64_t f_compressed_wi;
7914     wuffs_base__pixel_swizzler f_swizzler;
7915 
7916     uint32_t p_decode_image_config[1];
7917     uint32_t p_tell_me_more[1];
7918     uint32_t p_decode_frame_config[1];
7919     uint32_t p_skip_frame[1];
7920     uint32_t p_decode_frame[1];
7921     uint32_t p_decode_up_to_id_part1[1];
7922     uint32_t p_decode_header[1];
7923     uint32_t p_decode_lsd[1];
7924     uint32_t p_decode_extension[1];
7925     uint32_t p_skip_blocks[1];
7926     uint32_t p_decode_ae[1];
7927     uint32_t p_decode_gc[1];
7928     uint32_t p_decode_id_part0[1];
7929     uint32_t p_decode_id_part1[1];
7930     uint32_t p_decode_id_part2[1];
7931   } private_impl;
7932 
7933   struct {
7934     uint8_t f_compressed[4096];
7935     uint8_t f_palettes[2][1024];
7936     uint8_t f_dst_palette[1024];
7937     wuffs_lzw__decoder f_lzw;
7938 
7939     struct {
7940       uint32_t v_background_color;
7941     } s_decode_frame_config[1];
7942     struct {
7943       uint64_t scratch;
7944     } s_skip_frame[1];
7945     struct {
7946       uint8_t v_c[6];
7947       uint32_t v_i;
7948     } s_decode_header[1];
7949     struct {
7950       uint8_t v_flags;
7951       uint8_t v_background_color_index;
7952       uint32_t v_num_palette_entries;
7953       uint32_t v_i;
7954       uint64_t scratch;
7955     } s_decode_lsd[1];
7956     struct {
7957       uint64_t scratch;
7958     } s_skip_blocks[1];
7959     struct {
7960       uint8_t v_block_size;
7961       bool v_is_animexts;
7962       bool v_is_netscape;
7963       bool v_is_iccp;
7964       bool v_is_xmp;
7965       uint64_t scratch;
7966     } s_decode_ae[1];
7967     struct {
7968       uint64_t scratch;
7969     } s_decode_gc[1];
7970     struct {
7971       uint64_t scratch;
7972     } s_decode_id_part0[1];
7973     struct {
7974       uint8_t v_which_palette;
7975       uint32_t v_num_palette_entries;
7976       uint32_t v_i;
7977       uint64_t scratch;
7978     } s_decode_id_part1[1];
7979     struct {
7980       uint64_t v_block_size;
7981       bool v_need_block_size;
7982       wuffs_base__status v_lzw_status;
7983       uint64_t scratch;
7984     } s_decode_id_part2[1];
7985   } private_data;
7986 
7987 #ifdef __cplusplus
7988 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7989   using unique_ptr = std::unique_ptr<wuffs_gif__decoder, decltype(&free)>;
7990 
7991   // On failure, the alloc_etc functions return nullptr. They don't throw.
7992 
7993   static inline unique_ptr
allocwuffs_gif__decoder__struct7994   alloc() {
7995     return unique_ptr(wuffs_gif__decoder__alloc(), &free);
7996   }
7997 
7998   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_gif__decoder__struct7999   alloc_as__wuffs_base__image_decoder() {
8000     return wuffs_base__image_decoder::unique_ptr(
8001         wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(), &free);
8002   }
8003 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8004 
8005 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8006   // Disallow constructing or copying an object via standard C++ mechanisms,
8007   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8008   // size and field layout is not part of the public, stable, memory-safe API.
8009   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8010   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8011   // their first argument) rather than tweaking bar.private_impl.qux fields.
8012   //
8013   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8014   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8015   // order to provide convenience methods. These forward on "this", so that you
8016   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8017   wuffs_gif__decoder__struct() = delete;
8018   wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
8019   wuffs_gif__decoder__struct& operator=(
8020       const wuffs_gif__decoder__struct&) = delete;
8021 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8022 
8023 #if !defined(WUFFS_IMPLEMENTATION)
8024   // As above, the size of the struct is not part of the public API, and unless
8025   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8026   // allocated, not stack allocated. Its size is not intended to be known at
8027   // compile time, but it is unfortunately divulged as a side effect of
8028   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8029   // instead of "sizeof T", invoking the operator. To make the two values
8030   // different, so that passing the latter will be rejected by the initialize
8031   // function, we add an arbitrary amount of dead weight.
8032   uint8_t dead_weight[123000000];  // 123 MB.
8033 #endif  // !defined(WUFFS_IMPLEMENTATION)
8034 
8035   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_gif__decoder__struct8036   initialize(
8037       size_t sizeof_star_self,
8038       uint64_t wuffs_version,
8039       uint32_t options) {
8040     return wuffs_gif__decoder__initialize(
8041         this, sizeof_star_self, wuffs_version, options);
8042   }
8043 
8044   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_gif__decoder__struct8045   upcast_as__wuffs_base__image_decoder() {
8046     return (wuffs_base__image_decoder*)this;
8047   }
8048 
8049   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_gif__decoder__struct8050   set_quirk_enabled(
8051       uint32_t a_quirk,
8052       bool a_enabled) {
8053     return wuffs_gif__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8054   }
8055 
8056   inline wuffs_base__status
decode_image_configwuffs_gif__decoder__struct8057   decode_image_config(
8058       wuffs_base__image_config* a_dst,
8059       wuffs_base__io_buffer* a_src) {
8060     return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
8061   }
8062 
8063   inline wuffs_base__empty_struct
set_report_metadatawuffs_gif__decoder__struct8064   set_report_metadata(
8065       uint32_t a_fourcc,
8066       bool a_report) {
8067     return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
8068   }
8069 
8070   inline wuffs_base__status
tell_me_morewuffs_gif__decoder__struct8071   tell_me_more(
8072       wuffs_base__io_buffer* a_dst,
8073       wuffs_base__more_information* a_minfo,
8074       wuffs_base__io_buffer* a_src) {
8075     return wuffs_gif__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
8076   }
8077 
8078   inline uint32_t
num_animation_loopswuffs_gif__decoder__struct8079   num_animation_loops() const {
8080     return wuffs_gif__decoder__num_animation_loops(this);
8081   }
8082 
8083   inline uint64_t
num_decoded_frame_configswuffs_gif__decoder__struct8084   num_decoded_frame_configs() const {
8085     return wuffs_gif__decoder__num_decoded_frame_configs(this);
8086   }
8087 
8088   inline uint64_t
num_decoded_frameswuffs_gif__decoder__struct8089   num_decoded_frames() const {
8090     return wuffs_gif__decoder__num_decoded_frames(this);
8091   }
8092 
8093   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_gif__decoder__struct8094   frame_dirty_rect() const {
8095     return wuffs_gif__decoder__frame_dirty_rect(this);
8096   }
8097 
8098   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gif__decoder__struct8099   workbuf_len() const {
8100     return wuffs_gif__decoder__workbuf_len(this);
8101   }
8102 
8103   inline wuffs_base__status
restart_framewuffs_gif__decoder__struct8104   restart_frame(
8105       uint64_t a_index,
8106       uint64_t a_io_position) {
8107     return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
8108   }
8109 
8110   inline wuffs_base__status
decode_frame_configwuffs_gif__decoder__struct8111   decode_frame_config(
8112       wuffs_base__frame_config* a_dst,
8113       wuffs_base__io_buffer* a_src) {
8114     return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
8115   }
8116 
8117   inline wuffs_base__status
decode_framewuffs_gif__decoder__struct8118   decode_frame(
8119       wuffs_base__pixel_buffer* a_dst,
8120       wuffs_base__io_buffer* a_src,
8121       wuffs_base__pixel_blend a_blend,
8122       wuffs_base__slice_u8 a_workbuf,
8123       wuffs_base__decode_frame_options* a_opts) {
8124     return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
8125   }
8126 
8127 #endif  // __cplusplus
8128 };  // struct wuffs_gif__decoder__struct
8129 
8130 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8131 
8132 // ---------------- Status Codes
8133 
8134 extern const char wuffs_gzip__error__bad_checksum[];
8135 extern const char wuffs_gzip__error__bad_compression_method[];
8136 extern const char wuffs_gzip__error__bad_encoding_flags[];
8137 extern const char wuffs_gzip__error__bad_header[];
8138 
8139 // ---------------- Public Consts
8140 
8141 #define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8142 
8143 // ---------------- Struct Declarations
8144 
8145 typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
8146 
8147 #ifdef __cplusplus
8148 extern "C" {
8149 #endif
8150 
8151 // ---------------- Public Initializer Prototypes
8152 
8153 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8154 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8155 //
8156 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8157 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8158 
8159 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8160 wuffs_gzip__decoder__initialize(
8161     wuffs_gzip__decoder* self,
8162     size_t sizeof_star_self,
8163     uint64_t wuffs_version,
8164     uint32_t options);
8165 
8166 size_t
8167 sizeof__wuffs_gzip__decoder();
8168 
8169 // ---------------- Allocs
8170 
8171 // These functions allocate and initialize Wuffs structs. They return NULL if
8172 // memory allocation fails. If they return non-NULL, there is no need to call
8173 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8174 // calling free on the returned pointer. That pointer is effectively a C++
8175 // std::unique_ptr<T, decltype(&free)>.
8176 
8177 wuffs_gzip__decoder*
8178 wuffs_gzip__decoder__alloc();
8179 
8180 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer()8181 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer() {
8182   return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
8183 }
8184 
8185 // ---------------- Upcasts
8186 
8187 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(wuffs_gzip__decoder * p)8188 wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(
8189     wuffs_gzip__decoder* p) {
8190   return (wuffs_base__io_transformer*)p;
8191 }
8192 
8193 // ---------------- Public Function Prototypes
8194 
8195 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8196 wuffs_gzip__decoder__set_quirk_enabled(
8197     wuffs_gzip__decoder* self,
8198     uint32_t a_quirk,
8199     bool a_enabled);
8200 
8201 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8202 wuffs_gzip__decoder__workbuf_len(
8203     const wuffs_gzip__decoder* self);
8204 
8205 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8206 wuffs_gzip__decoder__transform_io(
8207     wuffs_gzip__decoder* self,
8208     wuffs_base__io_buffer* a_dst,
8209     wuffs_base__io_buffer* a_src,
8210     wuffs_base__slice_u8 a_workbuf);
8211 
8212 #ifdef __cplusplus
8213 }  // extern "C"
8214 #endif
8215 
8216 // ---------------- Struct Definitions
8217 
8218 // These structs' fields, and the sizeof them, are private implementation
8219 // details that aren't guaranteed to be stable across Wuffs versions.
8220 //
8221 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8222 
8223 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8224 
8225 struct wuffs_gzip__decoder__struct {
8226   // Do not access the private_impl's or private_data's fields directly. There
8227   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8228   // the wuffs_foo__bar__baz functions.
8229   //
8230   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8231   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8232 
8233   struct {
8234     uint32_t magic;
8235     uint32_t active_coroutine;
8236     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
8237     wuffs_base__vtable null_vtable;
8238 
8239     bool f_ignore_checksum;
8240 
8241     uint32_t p_transform_io[1];
8242   } private_impl;
8243 
8244   struct {
8245     wuffs_crc32__ieee_hasher f_checksum;
8246     wuffs_deflate__decoder f_flate;
8247 
8248     struct {
8249       uint8_t v_flags;
8250       uint32_t v_checksum_got;
8251       uint32_t v_decoded_length_got;
8252       uint32_t v_checksum_want;
8253       uint64_t scratch;
8254     } s_transform_io[1];
8255   } private_data;
8256 
8257 #ifdef __cplusplus
8258 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8259   using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, decltype(&free)>;
8260 
8261   // On failure, the alloc_etc functions return nullptr. They don't throw.
8262 
8263   static inline unique_ptr
allocwuffs_gzip__decoder__struct8264   alloc() {
8265     return unique_ptr(wuffs_gzip__decoder__alloc(), &free);
8266   }
8267 
8268   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct8269   alloc_as__wuffs_base__io_transformer() {
8270     return wuffs_base__io_transformer::unique_ptr(
8271         wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(), &free);
8272   }
8273 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8274 
8275 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8276   // Disallow constructing or copying an object via standard C++ mechanisms,
8277   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8278   // size and field layout is not part of the public, stable, memory-safe API.
8279   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8280   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8281   // their first argument) rather than tweaking bar.private_impl.qux fields.
8282   //
8283   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8284   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8285   // order to provide convenience methods. These forward on "this", so that you
8286   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8287   wuffs_gzip__decoder__struct() = delete;
8288   wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
8289   wuffs_gzip__decoder__struct& operator=(
8290       const wuffs_gzip__decoder__struct&) = delete;
8291 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8292 
8293 #if !defined(WUFFS_IMPLEMENTATION)
8294   // As above, the size of the struct is not part of the public API, and unless
8295   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8296   // allocated, not stack allocated. Its size is not intended to be known at
8297   // compile time, but it is unfortunately divulged as a side effect of
8298   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8299   // instead of "sizeof T", invoking the operator. To make the two values
8300   // different, so that passing the latter will be rejected by the initialize
8301   // function, we add an arbitrary amount of dead weight.
8302   uint8_t dead_weight[123000000];  // 123 MB.
8303 #endif  // !defined(WUFFS_IMPLEMENTATION)
8304 
8305   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_gzip__decoder__struct8306   initialize(
8307       size_t sizeof_star_self,
8308       uint64_t wuffs_version,
8309       uint32_t options) {
8310     return wuffs_gzip__decoder__initialize(
8311         this, sizeof_star_self, wuffs_version, options);
8312   }
8313 
8314   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct8315   upcast_as__wuffs_base__io_transformer() {
8316     return (wuffs_base__io_transformer*)this;
8317   }
8318 
8319   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_gzip__decoder__struct8320   set_quirk_enabled(
8321       uint32_t a_quirk,
8322       bool a_enabled) {
8323     return wuffs_gzip__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8324   }
8325 
8326   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gzip__decoder__struct8327   workbuf_len() const {
8328     return wuffs_gzip__decoder__workbuf_len(this);
8329   }
8330 
8331   inline wuffs_base__status
transform_iowuffs_gzip__decoder__struct8332   transform_io(
8333       wuffs_base__io_buffer* a_dst,
8334       wuffs_base__io_buffer* a_src,
8335       wuffs_base__slice_u8 a_workbuf) {
8336     return wuffs_gzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
8337   }
8338 
8339 #endif  // __cplusplus
8340 };  // struct wuffs_gzip__decoder__struct
8341 
8342 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8343 
8344 // ---------------- Status Codes
8345 
8346 extern const char wuffs_json__error__bad_c0_control_code[];
8347 extern const char wuffs_json__error__bad_utf_8[];
8348 extern const char wuffs_json__error__bad_backslash_escape[];
8349 extern const char wuffs_json__error__bad_input[];
8350 extern const char wuffs_json__error__bad_new_line_in_a_string[];
8351 extern const char wuffs_json__error__bad_quirk_combination[];
8352 extern const char wuffs_json__error__unsupported_number_length[];
8353 extern const char wuffs_json__error__unsupported_recursion_depth[];
8354 
8355 // ---------------- Public Consts
8356 
8357 #define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
8358 
8359 #define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024
8360 
8361 #define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1
8362 
8363 #define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100
8364 
8365 #define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480
8366 
8367 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481
8368 
8369 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482
8370 
8371 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483
8372 
8373 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484
8374 
8375 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485
8376 
8377 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486
8378 
8379 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487
8380 
8381 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489
8382 
8383 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490
8384 
8385 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491
8386 
8387 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492
8388 
8389 #define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493
8390 
8391 #define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494
8392 
8393 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495
8394 
8395 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496
8396 
8397 #define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497
8398 
8399 #define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498
8400 
8401 #define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499
8402 
8403 #define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500
8404 
8405 // ---------------- Struct Declarations
8406 
8407 typedef struct wuffs_json__decoder__struct wuffs_json__decoder;
8408 
8409 #ifdef __cplusplus
8410 extern "C" {
8411 #endif
8412 
8413 // ---------------- Public Initializer Prototypes
8414 
8415 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8416 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8417 //
8418 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8419 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8420 
8421 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8422 wuffs_json__decoder__initialize(
8423     wuffs_json__decoder* self,
8424     size_t sizeof_star_self,
8425     uint64_t wuffs_version,
8426     uint32_t options);
8427 
8428 size_t
8429 sizeof__wuffs_json__decoder();
8430 
8431 // ---------------- Allocs
8432 
8433 // These functions allocate and initialize Wuffs structs. They return NULL if
8434 // memory allocation fails. If they return non-NULL, there is no need to call
8435 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8436 // calling free on the returned pointer. That pointer is effectively a C++
8437 // std::unique_ptr<T, decltype(&free)>.
8438 
8439 wuffs_json__decoder*
8440 wuffs_json__decoder__alloc();
8441 
8442 static inline wuffs_base__token_decoder*
wuffs_json__decoder__alloc_as__wuffs_base__token_decoder()8443 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder() {
8444   return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
8445 }
8446 
8447 // ---------------- Upcasts
8448 
8449 static inline wuffs_base__token_decoder*
wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(wuffs_json__decoder * p)8450 wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
8451     wuffs_json__decoder* p) {
8452   return (wuffs_base__token_decoder*)p;
8453 }
8454 
8455 // ---------------- Public Function Prototypes
8456 
8457 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8458 wuffs_json__decoder__set_quirk_enabled(
8459     wuffs_json__decoder* self,
8460     uint32_t a_quirk,
8461     bool a_enabled);
8462 
8463 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8464 wuffs_json__decoder__workbuf_len(
8465     const wuffs_json__decoder* self);
8466 
8467 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8468 wuffs_json__decoder__decode_tokens(
8469     wuffs_json__decoder* self,
8470     wuffs_base__token_buffer* a_dst,
8471     wuffs_base__io_buffer* a_src,
8472     wuffs_base__slice_u8 a_workbuf);
8473 
8474 #ifdef __cplusplus
8475 }  // extern "C"
8476 #endif
8477 
8478 // ---------------- Struct Definitions
8479 
8480 // These structs' fields, and the sizeof them, are private implementation
8481 // details that aren't guaranteed to be stable across Wuffs versions.
8482 //
8483 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8484 
8485 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8486 
8487 struct wuffs_json__decoder__struct {
8488   // Do not access the private_impl's or private_data's fields directly. There
8489   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8490   // the wuffs_foo__bar__baz functions.
8491   //
8492   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8493   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8494 
8495   struct {
8496     uint32_t magic;
8497     uint32_t active_coroutine;
8498     wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
8499     wuffs_base__vtable null_vtable;
8500 
8501     bool f_quirks[21];
8502     bool f_allow_leading_ars;
8503     bool f_allow_leading_ubom;
8504     bool f_end_of_data;
8505     uint8_t f_trailer_stop;
8506     uint8_t f_comment_type;
8507 
8508     uint32_t p_decode_tokens[1];
8509     uint32_t p_decode_leading[1];
8510     uint32_t p_decode_comment[1];
8511     uint32_t p_decode_inf_nan[1];
8512     uint32_t p_decode_trailer[1];
8513   } private_impl;
8514 
8515   struct {
8516     uint32_t f_stack[32];
8517 
8518     struct {
8519       uint32_t v_depth;
8520       uint32_t v_expect;
8521       uint32_t v_expect_after_value;
8522     } s_decode_tokens[1];
8523     struct {
8524       uint32_t v_neg;
8525     } s_decode_inf_nan[1];
8526   } private_data;
8527 
8528 #ifdef __cplusplus
8529 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8530   using unique_ptr = std::unique_ptr<wuffs_json__decoder, decltype(&free)>;
8531 
8532   // On failure, the alloc_etc functions return nullptr. They don't throw.
8533 
8534   static inline unique_ptr
allocwuffs_json__decoder__struct8535   alloc() {
8536     return unique_ptr(wuffs_json__decoder__alloc(), &free);
8537   }
8538 
8539   static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_json__decoder__struct8540   alloc_as__wuffs_base__token_decoder() {
8541     return wuffs_base__token_decoder::unique_ptr(
8542         wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(), &free);
8543   }
8544 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8545 
8546 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8547   // Disallow constructing or copying an object via standard C++ mechanisms,
8548   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8549   // size and field layout is not part of the public, stable, memory-safe API.
8550   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8551   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8552   // their first argument) rather than tweaking bar.private_impl.qux fields.
8553   //
8554   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8555   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8556   // order to provide convenience methods. These forward on "this", so that you
8557   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8558   wuffs_json__decoder__struct() = delete;
8559   wuffs_json__decoder__struct(const wuffs_json__decoder__struct&) = delete;
8560   wuffs_json__decoder__struct& operator=(
8561       const wuffs_json__decoder__struct&) = delete;
8562 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8563 
8564 #if !defined(WUFFS_IMPLEMENTATION)
8565   // As above, the size of the struct is not part of the public API, and unless
8566   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8567   // allocated, not stack allocated. Its size is not intended to be known at
8568   // compile time, but it is unfortunately divulged as a side effect of
8569   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8570   // instead of "sizeof T", invoking the operator. To make the two values
8571   // different, so that passing the latter will be rejected by the initialize
8572   // function, we add an arbitrary amount of dead weight.
8573   uint8_t dead_weight[123000000];  // 123 MB.
8574 #endif  // !defined(WUFFS_IMPLEMENTATION)
8575 
8576   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_json__decoder__struct8577   initialize(
8578       size_t sizeof_star_self,
8579       uint64_t wuffs_version,
8580       uint32_t options) {
8581     return wuffs_json__decoder__initialize(
8582         this, sizeof_star_self, wuffs_version, options);
8583   }
8584 
8585   inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_json__decoder__struct8586   upcast_as__wuffs_base__token_decoder() {
8587     return (wuffs_base__token_decoder*)this;
8588   }
8589 
8590   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_json__decoder__struct8591   set_quirk_enabled(
8592       uint32_t a_quirk,
8593       bool a_enabled) {
8594     return wuffs_json__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8595   }
8596 
8597   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_json__decoder__struct8598   workbuf_len() const {
8599     return wuffs_json__decoder__workbuf_len(this);
8600   }
8601 
8602   inline wuffs_base__status
decode_tokenswuffs_json__decoder__struct8603   decode_tokens(
8604       wuffs_base__token_buffer* a_dst,
8605       wuffs_base__io_buffer* a_src,
8606       wuffs_base__slice_u8 a_workbuf) {
8607     return wuffs_json__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
8608   }
8609 
8610 #endif  // __cplusplus
8611 };  // struct wuffs_json__decoder__struct
8612 
8613 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8614 
8615 // ---------------- Status Codes
8616 
8617 extern const char wuffs_nie__error__bad_header[];
8618 extern const char wuffs_nie__error__unsupported_nie_file[];
8619 
8620 // ---------------- Public Consts
8621 
8622 #define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
8623 
8624 // ---------------- Struct Declarations
8625 
8626 typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder;
8627 
8628 #ifdef __cplusplus
8629 extern "C" {
8630 #endif
8631 
8632 // ---------------- Public Initializer Prototypes
8633 
8634 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8635 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8636 //
8637 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8638 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8639 
8640 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8641 wuffs_nie__decoder__initialize(
8642     wuffs_nie__decoder* self,
8643     size_t sizeof_star_self,
8644     uint64_t wuffs_version,
8645     uint32_t options);
8646 
8647 size_t
8648 sizeof__wuffs_nie__decoder();
8649 
8650 // ---------------- Allocs
8651 
8652 // These functions allocate and initialize Wuffs structs. They return NULL if
8653 // memory allocation fails. If they return non-NULL, there is no need to call
8654 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8655 // calling free on the returned pointer. That pointer is effectively a C++
8656 // std::unique_ptr<T, decltype(&free)>.
8657 
8658 wuffs_nie__decoder*
8659 wuffs_nie__decoder__alloc();
8660 
8661 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder()8662 wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder() {
8663   return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc());
8664 }
8665 
8666 // ---------------- Upcasts
8667 
8668 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(wuffs_nie__decoder * p)8669 wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(
8670     wuffs_nie__decoder* p) {
8671   return (wuffs_base__image_decoder*)p;
8672 }
8673 
8674 // ---------------- Public Function Prototypes
8675 
8676 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8677 wuffs_nie__decoder__set_quirk_enabled(
8678     wuffs_nie__decoder* self,
8679     uint32_t a_quirk,
8680     bool a_enabled);
8681 
8682 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8683 wuffs_nie__decoder__decode_image_config(
8684     wuffs_nie__decoder* self,
8685     wuffs_base__image_config* a_dst,
8686     wuffs_base__io_buffer* a_src);
8687 
8688 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8689 wuffs_nie__decoder__decode_frame_config(
8690     wuffs_nie__decoder* self,
8691     wuffs_base__frame_config* a_dst,
8692     wuffs_base__io_buffer* a_src);
8693 
8694 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8695 wuffs_nie__decoder__decode_frame(
8696     wuffs_nie__decoder* self,
8697     wuffs_base__pixel_buffer* a_dst,
8698     wuffs_base__io_buffer* a_src,
8699     wuffs_base__pixel_blend a_blend,
8700     wuffs_base__slice_u8 a_workbuf,
8701     wuffs_base__decode_frame_options* a_opts);
8702 
8703 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
8704 wuffs_nie__decoder__frame_dirty_rect(
8705     const wuffs_nie__decoder* self);
8706 
8707 WUFFS_BASE__MAYBE_STATIC uint32_t
8708 wuffs_nie__decoder__num_animation_loops(
8709     const wuffs_nie__decoder* self);
8710 
8711 WUFFS_BASE__MAYBE_STATIC uint64_t
8712 wuffs_nie__decoder__num_decoded_frame_configs(
8713     const wuffs_nie__decoder* self);
8714 
8715 WUFFS_BASE__MAYBE_STATIC uint64_t
8716 wuffs_nie__decoder__num_decoded_frames(
8717     const wuffs_nie__decoder* self);
8718 
8719 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8720 wuffs_nie__decoder__restart_frame(
8721     wuffs_nie__decoder* self,
8722     uint64_t a_index,
8723     uint64_t a_io_position);
8724 
8725 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8726 wuffs_nie__decoder__set_report_metadata(
8727     wuffs_nie__decoder* self,
8728     uint32_t a_fourcc,
8729     bool a_report);
8730 
8731 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8732 wuffs_nie__decoder__tell_me_more(
8733     wuffs_nie__decoder* self,
8734     wuffs_base__io_buffer* a_dst,
8735     wuffs_base__more_information* a_minfo,
8736     wuffs_base__io_buffer* a_src);
8737 
8738 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8739 wuffs_nie__decoder__workbuf_len(
8740     const wuffs_nie__decoder* self);
8741 
8742 #ifdef __cplusplus
8743 }  // extern "C"
8744 #endif
8745 
8746 // ---------------- Struct Definitions
8747 
8748 // These structs' fields, and the sizeof them, are private implementation
8749 // details that aren't guaranteed to be stable across Wuffs versions.
8750 //
8751 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8752 
8753 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8754 
8755 struct wuffs_nie__decoder__struct {
8756   // Do not access the private_impl's or private_data's fields directly. There
8757   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8758   // the wuffs_foo__bar__baz functions.
8759   //
8760   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8761   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8762 
8763   struct {
8764     uint32_t magic;
8765     uint32_t active_coroutine;
8766     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
8767     wuffs_base__vtable null_vtable;
8768 
8769     uint32_t f_pixfmt;
8770     uint32_t f_width;
8771     uint32_t f_height;
8772     uint8_t f_call_sequence;
8773     uint32_t f_dst_x;
8774     uint32_t f_dst_y;
8775     wuffs_base__pixel_swizzler f_swizzler;
8776 
8777     uint32_t p_decode_image_config[1];
8778     uint32_t p_decode_frame_config[1];
8779     uint32_t p_decode_frame[1];
8780   } private_impl;
8781 
8782   struct {
8783     struct {
8784       uint64_t scratch;
8785     } s_decode_image_config[1];
8786   } private_data;
8787 
8788 #ifdef __cplusplus
8789 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8790   using unique_ptr = std::unique_ptr<wuffs_nie__decoder, decltype(&free)>;
8791 
8792   // On failure, the alloc_etc functions return nullptr. They don't throw.
8793 
8794   static inline unique_ptr
allocwuffs_nie__decoder__struct8795   alloc() {
8796     return unique_ptr(wuffs_nie__decoder__alloc(), &free);
8797   }
8798 
8799   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_nie__decoder__struct8800   alloc_as__wuffs_base__image_decoder() {
8801     return wuffs_base__image_decoder::unique_ptr(
8802         wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(), &free);
8803   }
8804 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8805 
8806 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8807   // Disallow constructing or copying an object via standard C++ mechanisms,
8808   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8809   // size and field layout is not part of the public, stable, memory-safe API.
8810   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8811   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8812   // their first argument) rather than tweaking bar.private_impl.qux fields.
8813   //
8814   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8815   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8816   // order to provide convenience methods. These forward on "this", so that you
8817   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8818   wuffs_nie__decoder__struct() = delete;
8819   wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete;
8820   wuffs_nie__decoder__struct& operator=(
8821       const wuffs_nie__decoder__struct&) = delete;
8822 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8823 
8824 #if !defined(WUFFS_IMPLEMENTATION)
8825   // As above, the size of the struct is not part of the public API, and unless
8826   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8827   // allocated, not stack allocated. Its size is not intended to be known at
8828   // compile time, but it is unfortunately divulged as a side effect of
8829   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8830   // instead of "sizeof T", invoking the operator. To make the two values
8831   // different, so that passing the latter will be rejected by the initialize
8832   // function, we add an arbitrary amount of dead weight.
8833   uint8_t dead_weight[123000000];  // 123 MB.
8834 #endif  // !defined(WUFFS_IMPLEMENTATION)
8835 
8836   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_nie__decoder__struct8837   initialize(
8838       size_t sizeof_star_self,
8839       uint64_t wuffs_version,
8840       uint32_t options) {
8841     return wuffs_nie__decoder__initialize(
8842         this, sizeof_star_self, wuffs_version, options);
8843   }
8844 
8845   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_nie__decoder__struct8846   upcast_as__wuffs_base__image_decoder() {
8847     return (wuffs_base__image_decoder*)this;
8848   }
8849 
8850   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_nie__decoder__struct8851   set_quirk_enabled(
8852       uint32_t a_quirk,
8853       bool a_enabled) {
8854     return wuffs_nie__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8855   }
8856 
8857   inline wuffs_base__status
decode_image_configwuffs_nie__decoder__struct8858   decode_image_config(
8859       wuffs_base__image_config* a_dst,
8860       wuffs_base__io_buffer* a_src) {
8861     return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src);
8862   }
8863 
8864   inline wuffs_base__status
decode_frame_configwuffs_nie__decoder__struct8865   decode_frame_config(
8866       wuffs_base__frame_config* a_dst,
8867       wuffs_base__io_buffer* a_src) {
8868     return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src);
8869   }
8870 
8871   inline wuffs_base__status
decode_framewuffs_nie__decoder__struct8872   decode_frame(
8873       wuffs_base__pixel_buffer* a_dst,
8874       wuffs_base__io_buffer* a_src,
8875       wuffs_base__pixel_blend a_blend,
8876       wuffs_base__slice_u8 a_workbuf,
8877       wuffs_base__decode_frame_options* a_opts) {
8878     return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
8879   }
8880 
8881   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_nie__decoder__struct8882   frame_dirty_rect() const {
8883     return wuffs_nie__decoder__frame_dirty_rect(this);
8884   }
8885 
8886   inline uint32_t
num_animation_loopswuffs_nie__decoder__struct8887   num_animation_loops() const {
8888     return wuffs_nie__decoder__num_animation_loops(this);
8889   }
8890 
8891   inline uint64_t
num_decoded_frame_configswuffs_nie__decoder__struct8892   num_decoded_frame_configs() const {
8893     return wuffs_nie__decoder__num_decoded_frame_configs(this);
8894   }
8895 
8896   inline uint64_t
num_decoded_frameswuffs_nie__decoder__struct8897   num_decoded_frames() const {
8898     return wuffs_nie__decoder__num_decoded_frames(this);
8899   }
8900 
8901   inline wuffs_base__status
restart_framewuffs_nie__decoder__struct8902   restart_frame(
8903       uint64_t a_index,
8904       uint64_t a_io_position) {
8905     return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position);
8906   }
8907 
8908   inline wuffs_base__empty_struct
set_report_metadatawuffs_nie__decoder__struct8909   set_report_metadata(
8910       uint32_t a_fourcc,
8911       bool a_report) {
8912     return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report);
8913   }
8914 
8915   inline wuffs_base__status
tell_me_morewuffs_nie__decoder__struct8916   tell_me_more(
8917       wuffs_base__io_buffer* a_dst,
8918       wuffs_base__more_information* a_minfo,
8919       wuffs_base__io_buffer* a_src) {
8920     return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
8921   }
8922 
8923   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_nie__decoder__struct8924   workbuf_len() const {
8925     return wuffs_nie__decoder__workbuf_len(this);
8926   }
8927 
8928 #endif  // __cplusplus
8929 };  // struct wuffs_nie__decoder__struct
8930 
8931 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8932 
8933 // ---------------- Status Codes
8934 
8935 extern const char wuffs_zlib__note__dictionary_required[];
8936 extern const char wuffs_zlib__error__bad_checksum[];
8937 extern const char wuffs_zlib__error__bad_compression_method[];
8938 extern const char wuffs_zlib__error__bad_compression_window_size[];
8939 extern const char wuffs_zlib__error__bad_parity_check[];
8940 extern const char wuffs_zlib__error__incorrect_dictionary[];
8941 
8942 // ---------------- Public Consts
8943 
8944 #define WUFFS_ZLIB__QUIRK_JUST_RAW_DEFLATE 2113790976
8945 
8946 #define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8947 
8948 // ---------------- Struct Declarations
8949 
8950 typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
8951 
8952 #ifdef __cplusplus
8953 extern "C" {
8954 #endif
8955 
8956 // ---------------- Public Initializer Prototypes
8957 
8958 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8959 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8960 //
8961 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8962 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8963 
8964 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8965 wuffs_zlib__decoder__initialize(
8966     wuffs_zlib__decoder* self,
8967     size_t sizeof_star_self,
8968     uint64_t wuffs_version,
8969     uint32_t options);
8970 
8971 size_t
8972 sizeof__wuffs_zlib__decoder();
8973 
8974 // ---------------- Allocs
8975 
8976 // These functions allocate and initialize Wuffs structs. They return NULL if
8977 // memory allocation fails. If they return non-NULL, there is no need to call
8978 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8979 // calling free on the returned pointer. That pointer is effectively a C++
8980 // std::unique_ptr<T, decltype(&free)>.
8981 
8982 wuffs_zlib__decoder*
8983 wuffs_zlib__decoder__alloc();
8984 
8985 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer()8986 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer() {
8987   return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
8988 }
8989 
8990 // ---------------- Upcasts
8991 
8992 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(wuffs_zlib__decoder * p)8993 wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(
8994     wuffs_zlib__decoder* p) {
8995   return (wuffs_base__io_transformer*)p;
8996 }
8997 
8998 // ---------------- Public Function Prototypes
8999 
9000 WUFFS_BASE__MAYBE_STATIC uint32_t
9001 wuffs_zlib__decoder__dictionary_id(
9002     const wuffs_zlib__decoder* self);
9003 
9004 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9005 wuffs_zlib__decoder__add_dictionary(
9006     wuffs_zlib__decoder* self,
9007     wuffs_base__slice_u8 a_dict);
9008 
9009 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9010 wuffs_zlib__decoder__set_quirk_enabled(
9011     wuffs_zlib__decoder* self,
9012     uint32_t a_quirk,
9013     bool a_enabled);
9014 
9015 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9016 wuffs_zlib__decoder__workbuf_len(
9017     const wuffs_zlib__decoder* self);
9018 
9019 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9020 wuffs_zlib__decoder__transform_io(
9021     wuffs_zlib__decoder* self,
9022     wuffs_base__io_buffer* a_dst,
9023     wuffs_base__io_buffer* a_src,
9024     wuffs_base__slice_u8 a_workbuf);
9025 
9026 #ifdef __cplusplus
9027 }  // extern "C"
9028 #endif
9029 
9030 // ---------------- Struct Definitions
9031 
9032 // These structs' fields, and the sizeof them, are private implementation
9033 // details that aren't guaranteed to be stable across Wuffs versions.
9034 //
9035 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9036 
9037 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9038 
9039 struct wuffs_zlib__decoder__struct {
9040   // Do not access the private_impl's or private_data's fields directly. There
9041   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9042   // the wuffs_foo__bar__baz functions.
9043   //
9044   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9045   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9046 
9047   struct {
9048     uint32_t magic;
9049     uint32_t active_coroutine;
9050     wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
9051     wuffs_base__vtable null_vtable;
9052 
9053     bool f_bad_call_sequence;
9054     bool f_header_complete;
9055     bool f_got_dictionary;
9056     bool f_want_dictionary;
9057     bool f_quirks[1];
9058     bool f_ignore_checksum;
9059     uint32_t f_dict_id_got;
9060     uint32_t f_dict_id_want;
9061 
9062     uint32_t p_transform_io[1];
9063   } private_impl;
9064 
9065   struct {
9066     wuffs_adler32__hasher f_checksum;
9067     wuffs_adler32__hasher f_dict_id_hasher;
9068     wuffs_deflate__decoder f_flate;
9069 
9070     struct {
9071       uint32_t v_checksum_got;
9072       uint64_t scratch;
9073     } s_transform_io[1];
9074   } private_data;
9075 
9076 #ifdef __cplusplus
9077 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9078   using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, decltype(&free)>;
9079 
9080   // On failure, the alloc_etc functions return nullptr. They don't throw.
9081 
9082   static inline unique_ptr
allocwuffs_zlib__decoder__struct9083   alloc() {
9084     return unique_ptr(wuffs_zlib__decoder__alloc(), &free);
9085   }
9086 
9087   static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct9088   alloc_as__wuffs_base__io_transformer() {
9089     return wuffs_base__io_transformer::unique_ptr(
9090         wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(), &free);
9091   }
9092 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9093 
9094 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9095   // Disallow constructing or copying an object via standard C++ mechanisms,
9096   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9097   // size and field layout is not part of the public, stable, memory-safe API.
9098   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9099   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9100   // their first argument) rather than tweaking bar.private_impl.qux fields.
9101   //
9102   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9103   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9104   // order to provide convenience methods. These forward on "this", so that you
9105   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9106   wuffs_zlib__decoder__struct() = delete;
9107   wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
9108   wuffs_zlib__decoder__struct& operator=(
9109       const wuffs_zlib__decoder__struct&) = delete;
9110 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9111 
9112 #if !defined(WUFFS_IMPLEMENTATION)
9113   // As above, the size of the struct is not part of the public API, and unless
9114   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9115   // allocated, not stack allocated. Its size is not intended to be known at
9116   // compile time, but it is unfortunately divulged as a side effect of
9117   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9118   // instead of "sizeof T", invoking the operator. To make the two values
9119   // different, so that passing the latter will be rejected by the initialize
9120   // function, we add an arbitrary amount of dead weight.
9121   uint8_t dead_weight[123000000];  // 123 MB.
9122 #endif  // !defined(WUFFS_IMPLEMENTATION)
9123 
9124   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_zlib__decoder__struct9125   initialize(
9126       size_t sizeof_star_self,
9127       uint64_t wuffs_version,
9128       uint32_t options) {
9129     return wuffs_zlib__decoder__initialize(
9130         this, sizeof_star_self, wuffs_version, options);
9131   }
9132 
9133   inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct9134   upcast_as__wuffs_base__io_transformer() {
9135     return (wuffs_base__io_transformer*)this;
9136   }
9137 
9138   inline uint32_t
dictionary_idwuffs_zlib__decoder__struct9139   dictionary_id() const {
9140     return wuffs_zlib__decoder__dictionary_id(this);
9141   }
9142 
9143   inline wuffs_base__empty_struct
add_dictionarywuffs_zlib__decoder__struct9144   add_dictionary(
9145       wuffs_base__slice_u8 a_dict) {
9146     return wuffs_zlib__decoder__add_dictionary(this, a_dict);
9147   }
9148 
9149   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_zlib__decoder__struct9150   set_quirk_enabled(
9151       uint32_t a_quirk,
9152       bool a_enabled) {
9153     return wuffs_zlib__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9154   }
9155 
9156   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_zlib__decoder__struct9157   workbuf_len() const {
9158     return wuffs_zlib__decoder__workbuf_len(this);
9159   }
9160 
9161   inline wuffs_base__status
transform_iowuffs_zlib__decoder__struct9162   transform_io(
9163       wuffs_base__io_buffer* a_dst,
9164       wuffs_base__io_buffer* a_src,
9165       wuffs_base__slice_u8 a_workbuf) {
9166     return wuffs_zlib__decoder__transform_io(this, a_dst, a_src, a_workbuf);
9167   }
9168 
9169 #endif  // __cplusplus
9170 };  // struct wuffs_zlib__decoder__struct
9171 
9172 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9173 
9174 // ---------------- Status Codes
9175 
9176 extern const char wuffs_png__error__bad_animation_sequence_number[];
9177 extern const char wuffs_png__error__bad_checksum[];
9178 extern const char wuffs_png__error__bad_chunk[];
9179 extern const char wuffs_png__error__bad_filter[];
9180 extern const char wuffs_png__error__bad_header[];
9181 extern const char wuffs_png__error__bad_text_chunk_not_latin_1[];
9182 extern const char wuffs_png__error__missing_palette[];
9183 extern const char wuffs_png__error__unsupported_png_compression_method[];
9184 extern const char wuffs_png__error__unsupported_png_file[];
9185 
9186 // ---------------- Public Consts
9187 
9188 #define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9189 
9190 #define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8
9191 
9192 // ---------------- Struct Declarations
9193 
9194 typedef struct wuffs_png__decoder__struct wuffs_png__decoder;
9195 
9196 #ifdef __cplusplus
9197 extern "C" {
9198 #endif
9199 
9200 // ---------------- Public Initializer Prototypes
9201 
9202 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9203 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9204 //
9205 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9206 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9207 
9208 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9209 wuffs_png__decoder__initialize(
9210     wuffs_png__decoder* self,
9211     size_t sizeof_star_self,
9212     uint64_t wuffs_version,
9213     uint32_t options);
9214 
9215 size_t
9216 sizeof__wuffs_png__decoder();
9217 
9218 // ---------------- Allocs
9219 
9220 // These functions allocate and initialize Wuffs structs. They return NULL if
9221 // memory allocation fails. If they return non-NULL, there is no need to call
9222 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9223 // calling free on the returned pointer. That pointer is effectively a C++
9224 // std::unique_ptr<T, decltype(&free)>.
9225 
9226 wuffs_png__decoder*
9227 wuffs_png__decoder__alloc();
9228 
9229 static inline wuffs_base__image_decoder*
wuffs_png__decoder__alloc_as__wuffs_base__image_decoder()9230 wuffs_png__decoder__alloc_as__wuffs_base__image_decoder() {
9231   return (wuffs_base__image_decoder*)(wuffs_png__decoder__alloc());
9232 }
9233 
9234 // ---------------- Upcasts
9235 
9236 static inline wuffs_base__image_decoder*
wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(wuffs_png__decoder * p)9237 wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(
9238     wuffs_png__decoder* p) {
9239   return (wuffs_base__image_decoder*)p;
9240 }
9241 
9242 // ---------------- Public Function Prototypes
9243 
9244 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9245 wuffs_png__decoder__set_quirk_enabled(
9246     wuffs_png__decoder* self,
9247     uint32_t a_quirk,
9248     bool a_enabled);
9249 
9250 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9251 wuffs_png__decoder__decode_image_config(
9252     wuffs_png__decoder* self,
9253     wuffs_base__image_config* a_dst,
9254     wuffs_base__io_buffer* a_src);
9255 
9256 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9257 wuffs_png__decoder__decode_frame_config(
9258     wuffs_png__decoder* self,
9259     wuffs_base__frame_config* a_dst,
9260     wuffs_base__io_buffer* a_src);
9261 
9262 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9263 wuffs_png__decoder__decode_frame(
9264     wuffs_png__decoder* self,
9265     wuffs_base__pixel_buffer* a_dst,
9266     wuffs_base__io_buffer* a_src,
9267     wuffs_base__pixel_blend a_blend,
9268     wuffs_base__slice_u8 a_workbuf,
9269     wuffs_base__decode_frame_options* a_opts);
9270 
9271 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9272 wuffs_png__decoder__frame_dirty_rect(
9273     const wuffs_png__decoder* self);
9274 
9275 WUFFS_BASE__MAYBE_STATIC uint32_t
9276 wuffs_png__decoder__num_animation_loops(
9277     const wuffs_png__decoder* self);
9278 
9279 WUFFS_BASE__MAYBE_STATIC uint64_t
9280 wuffs_png__decoder__num_decoded_frame_configs(
9281     const wuffs_png__decoder* self);
9282 
9283 WUFFS_BASE__MAYBE_STATIC uint64_t
9284 wuffs_png__decoder__num_decoded_frames(
9285     const wuffs_png__decoder* self);
9286 
9287 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9288 wuffs_png__decoder__restart_frame(
9289     wuffs_png__decoder* self,
9290     uint64_t a_index,
9291     uint64_t a_io_position);
9292 
9293 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9294 wuffs_png__decoder__set_report_metadata(
9295     wuffs_png__decoder* self,
9296     uint32_t a_fourcc,
9297     bool a_report);
9298 
9299 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9300 wuffs_png__decoder__tell_me_more(
9301     wuffs_png__decoder* self,
9302     wuffs_base__io_buffer* a_dst,
9303     wuffs_base__more_information* a_minfo,
9304     wuffs_base__io_buffer* a_src);
9305 
9306 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9307 wuffs_png__decoder__workbuf_len(
9308     const wuffs_png__decoder* self);
9309 
9310 #ifdef __cplusplus
9311 }  // extern "C"
9312 #endif
9313 
9314 // ---------------- Struct Definitions
9315 
9316 // These structs' fields, and the sizeof them, are private implementation
9317 // details that aren't guaranteed to be stable across Wuffs versions.
9318 //
9319 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9320 
9321 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9322 
9323 struct wuffs_png__decoder__struct {
9324   // Do not access the private_impl's or private_data's fields directly. There
9325   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9326   // the wuffs_foo__bar__baz functions.
9327   //
9328   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9329   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9330 
9331   struct {
9332     uint32_t magic;
9333     uint32_t active_coroutine;
9334     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9335     wuffs_base__vtable null_vtable;
9336 
9337     uint32_t f_width;
9338     uint32_t f_height;
9339     uint64_t f_pass_bytes_per_row;
9340     uint64_t f_workbuf_wi;
9341     uint64_t f_workbuf_hist_pos_base;
9342     uint64_t f_overall_workbuf_length;
9343     uint64_t f_pass_workbuf_length;
9344     uint8_t f_call_sequence;
9345     bool f_report_metadata_chrm;
9346     bool f_report_metadata_exif;
9347     bool f_report_metadata_gama;
9348     bool f_report_metadata_iccp;
9349     bool f_report_metadata_kvp;
9350     bool f_report_metadata_srgb;
9351     bool f_ignore_checksum;
9352     uint8_t f_depth;
9353     uint8_t f_color_type;
9354     uint8_t f_filter_distance;
9355     uint8_t f_interlace_pass;
9356     bool f_seen_actl;
9357     bool f_seen_chrm;
9358     bool f_seen_fctl;
9359     bool f_seen_exif;
9360     bool f_seen_gama;
9361     bool f_seen_iccp;
9362     bool f_seen_idat;
9363     bool f_seen_plte;
9364     bool f_seen_srgb;
9365     bool f_seen_trns;
9366     bool f_metadata_is_zlib_compressed;
9367     bool f_zlib_is_dirty;
9368     uint32_t f_chunk_type;
9369     uint8_t f_chunk_type_array[4];
9370     uint32_t f_chunk_length;
9371     uint64_t f_remap_transparency;
9372     uint32_t f_dst_pixfmt;
9373     uint32_t f_src_pixfmt;
9374     uint32_t f_num_animation_frames_value;
9375     uint32_t f_num_animation_loops_value;
9376     uint32_t f_num_decoded_frame_configs_value;
9377     uint32_t f_num_decoded_frames_value;
9378     uint32_t f_frame_rect_x0;
9379     uint32_t f_frame_rect_y0;
9380     uint32_t f_frame_rect_x1;
9381     uint32_t f_frame_rect_y1;
9382     uint32_t f_first_rect_x0;
9383     uint32_t f_first_rect_y0;
9384     uint32_t f_first_rect_x1;
9385     uint32_t f_first_rect_y1;
9386     uint64_t f_frame_config_io_position;
9387     uint64_t f_first_config_io_position;
9388     uint64_t f_frame_duration;
9389     uint64_t f_first_duration;
9390     uint8_t f_frame_disposal;
9391     uint8_t f_first_disposal;
9392     bool f_frame_overwrite_instead_of_blend;
9393     bool f_first_overwrite_instead_of_blend;
9394     uint32_t f_next_animation_seq_num;
9395     uint32_t f_metadata_flavor;
9396     uint32_t f_metadata_fourcc;
9397     uint64_t f_metadata_x;
9398     uint64_t f_metadata_y;
9399     uint64_t f_metadata_z;
9400     uint32_t f_ztxt_ri;
9401     uint32_t f_ztxt_wi;
9402     uint64_t f_ztxt_hist_pos;
9403     wuffs_base__pixel_swizzler f_swizzler;
9404 
9405     wuffs_base__empty_struct (*choosy_filter_1)(
9406         wuffs_png__decoder* self,
9407         wuffs_base__slice_u8 a_curr);
9408     wuffs_base__empty_struct (*choosy_filter_3)(
9409         wuffs_png__decoder* self,
9410         wuffs_base__slice_u8 a_curr,
9411         wuffs_base__slice_u8 a_prev);
9412     wuffs_base__empty_struct (*choosy_filter_4)(
9413         wuffs_png__decoder* self,
9414         wuffs_base__slice_u8 a_curr,
9415         wuffs_base__slice_u8 a_prev);
9416     uint32_t p_decode_image_config[1];
9417     uint32_t p_decode_ihdr[1];
9418     uint32_t p_decode_other_chunk[1];
9419     uint32_t p_decode_actl[1];
9420     uint32_t p_decode_chrm[1];
9421     uint32_t p_decode_fctl[1];
9422     uint32_t p_decode_gama[1];
9423     uint32_t p_decode_iccp[1];
9424     uint32_t p_decode_plte[1];
9425     uint32_t p_decode_srgb[1];
9426     uint32_t p_decode_trns[1];
9427     uint32_t p_decode_frame_config[1];
9428     uint32_t p_skip_frame[1];
9429     uint32_t p_decode_frame[1];
9430     uint32_t p_decode_pass[1];
9431     uint32_t p_tell_me_more[1];
9432     wuffs_base__status (*choosy_filter_and_swizzle)(
9433         wuffs_png__decoder* self,
9434         wuffs_base__pixel_buffer* a_dst,
9435         wuffs_base__slice_u8 a_workbuf);
9436   } private_impl;
9437 
9438   struct {
9439     wuffs_crc32__ieee_hasher f_crc32;
9440     wuffs_zlib__decoder f_zlib;
9441     uint8_t f_dst_palette[1024];
9442     uint8_t f_src_palette[1024];
9443 
9444     struct {
9445       uint32_t v_checksum_have;
9446       uint64_t scratch;
9447     } s_decode_image_config[1];
9448     struct {
9449       uint64_t scratch;
9450     } s_decode_ihdr[1];
9451     struct {
9452       uint64_t scratch;
9453     } s_decode_other_chunk[1];
9454     struct {
9455       uint64_t scratch;
9456     } s_decode_actl[1];
9457     struct {
9458       uint64_t scratch;
9459     } s_decode_chrm[1];
9460     struct {
9461       uint32_t v_x0;
9462       uint32_t v_x1;
9463       uint32_t v_y1;
9464       uint64_t scratch;
9465     } s_decode_fctl[1];
9466     struct {
9467       uint64_t scratch;
9468     } s_decode_gama[1];
9469     struct {
9470       uint32_t v_num_entries;
9471       uint32_t v_i;
9472       uint64_t scratch;
9473     } s_decode_plte[1];
9474     struct {
9475       uint32_t v_i;
9476       uint32_t v_n;
9477       uint64_t scratch;
9478     } s_decode_trns[1];
9479     struct {
9480       uint64_t scratch;
9481     } s_decode_frame_config[1];
9482     struct {
9483       uint64_t scratch;
9484     } s_skip_frame[1];
9485     struct {
9486       uint64_t scratch;
9487     } s_decode_frame[1];
9488     struct {
9489       uint64_t scratch;
9490     } s_decode_pass[1];
9491     struct {
9492       wuffs_base__status v_zlib_status;
9493       uint64_t scratch;
9494     } s_tell_me_more[1];
9495   } private_data;
9496 
9497 #ifdef __cplusplus
9498 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9499   using unique_ptr = std::unique_ptr<wuffs_png__decoder, decltype(&free)>;
9500 
9501   // On failure, the alloc_etc functions return nullptr. They don't throw.
9502 
9503   static inline unique_ptr
allocwuffs_png__decoder__struct9504   alloc() {
9505     return unique_ptr(wuffs_png__decoder__alloc(), &free);
9506   }
9507 
9508   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_png__decoder__struct9509   alloc_as__wuffs_base__image_decoder() {
9510     return wuffs_base__image_decoder::unique_ptr(
9511         wuffs_png__decoder__alloc_as__wuffs_base__image_decoder(), &free);
9512   }
9513 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9514 
9515 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9516   // Disallow constructing or copying an object via standard C++ mechanisms,
9517   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9518   // size and field layout is not part of the public, stable, memory-safe API.
9519   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9520   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9521   // their first argument) rather than tweaking bar.private_impl.qux fields.
9522   //
9523   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9524   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9525   // order to provide convenience methods. These forward on "this", so that you
9526   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9527   wuffs_png__decoder__struct() = delete;
9528   wuffs_png__decoder__struct(const wuffs_png__decoder__struct&) = delete;
9529   wuffs_png__decoder__struct& operator=(
9530       const wuffs_png__decoder__struct&) = delete;
9531 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9532 
9533 #if !defined(WUFFS_IMPLEMENTATION)
9534   // As above, the size of the struct is not part of the public API, and unless
9535   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9536   // allocated, not stack allocated. Its size is not intended to be known at
9537   // compile time, but it is unfortunately divulged as a side effect of
9538   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9539   // instead of "sizeof T", invoking the operator. To make the two values
9540   // different, so that passing the latter will be rejected by the initialize
9541   // function, we add an arbitrary amount of dead weight.
9542   uint8_t dead_weight[123000000];  // 123 MB.
9543 #endif  // !defined(WUFFS_IMPLEMENTATION)
9544 
9545   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_png__decoder__struct9546   initialize(
9547       size_t sizeof_star_self,
9548       uint64_t wuffs_version,
9549       uint32_t options) {
9550     return wuffs_png__decoder__initialize(
9551         this, sizeof_star_self, wuffs_version, options);
9552   }
9553 
9554   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_png__decoder__struct9555   upcast_as__wuffs_base__image_decoder() {
9556     return (wuffs_base__image_decoder*)this;
9557   }
9558 
9559   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_png__decoder__struct9560   set_quirk_enabled(
9561       uint32_t a_quirk,
9562       bool a_enabled) {
9563     return wuffs_png__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9564   }
9565 
9566   inline wuffs_base__status
decode_image_configwuffs_png__decoder__struct9567   decode_image_config(
9568       wuffs_base__image_config* a_dst,
9569       wuffs_base__io_buffer* a_src) {
9570     return wuffs_png__decoder__decode_image_config(this, a_dst, a_src);
9571   }
9572 
9573   inline wuffs_base__status
decode_frame_configwuffs_png__decoder__struct9574   decode_frame_config(
9575       wuffs_base__frame_config* a_dst,
9576       wuffs_base__io_buffer* a_src) {
9577     return wuffs_png__decoder__decode_frame_config(this, a_dst, a_src);
9578   }
9579 
9580   inline wuffs_base__status
decode_framewuffs_png__decoder__struct9581   decode_frame(
9582       wuffs_base__pixel_buffer* a_dst,
9583       wuffs_base__io_buffer* a_src,
9584       wuffs_base__pixel_blend a_blend,
9585       wuffs_base__slice_u8 a_workbuf,
9586       wuffs_base__decode_frame_options* a_opts) {
9587     return wuffs_png__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9588   }
9589 
9590   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_png__decoder__struct9591   frame_dirty_rect() const {
9592     return wuffs_png__decoder__frame_dirty_rect(this);
9593   }
9594 
9595   inline uint32_t
num_animation_loopswuffs_png__decoder__struct9596   num_animation_loops() const {
9597     return wuffs_png__decoder__num_animation_loops(this);
9598   }
9599 
9600   inline uint64_t
num_decoded_frame_configswuffs_png__decoder__struct9601   num_decoded_frame_configs() const {
9602     return wuffs_png__decoder__num_decoded_frame_configs(this);
9603   }
9604 
9605   inline uint64_t
num_decoded_frameswuffs_png__decoder__struct9606   num_decoded_frames() const {
9607     return wuffs_png__decoder__num_decoded_frames(this);
9608   }
9609 
9610   inline wuffs_base__status
restart_framewuffs_png__decoder__struct9611   restart_frame(
9612       uint64_t a_index,
9613       uint64_t a_io_position) {
9614     return wuffs_png__decoder__restart_frame(this, a_index, a_io_position);
9615   }
9616 
9617   inline wuffs_base__empty_struct
set_report_metadatawuffs_png__decoder__struct9618   set_report_metadata(
9619       uint32_t a_fourcc,
9620       bool a_report) {
9621     return wuffs_png__decoder__set_report_metadata(this, a_fourcc, a_report);
9622   }
9623 
9624   inline wuffs_base__status
tell_me_morewuffs_png__decoder__struct9625   tell_me_more(
9626       wuffs_base__io_buffer* a_dst,
9627       wuffs_base__more_information* a_minfo,
9628       wuffs_base__io_buffer* a_src) {
9629     return wuffs_png__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9630   }
9631 
9632   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_png__decoder__struct9633   workbuf_len() const {
9634     return wuffs_png__decoder__workbuf_len(this);
9635   }
9636 
9637 #endif  // __cplusplus
9638 };  // struct wuffs_png__decoder__struct
9639 
9640 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9641 
9642 // ---------------- Status Codes
9643 
9644 extern const char wuffs_tga__error__bad_header[];
9645 extern const char wuffs_tga__error__bad_run_length_encoding[];
9646 extern const char wuffs_tga__error__unsupported_tga_file[];
9647 
9648 // ---------------- Public Consts
9649 
9650 #define WUFFS_TGA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9651 
9652 // ---------------- Struct Declarations
9653 
9654 typedef struct wuffs_tga__decoder__struct wuffs_tga__decoder;
9655 
9656 #ifdef __cplusplus
9657 extern "C" {
9658 #endif
9659 
9660 // ---------------- Public Initializer Prototypes
9661 
9662 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9663 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9664 //
9665 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9666 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9667 
9668 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9669 wuffs_tga__decoder__initialize(
9670     wuffs_tga__decoder* self,
9671     size_t sizeof_star_self,
9672     uint64_t wuffs_version,
9673     uint32_t options);
9674 
9675 size_t
9676 sizeof__wuffs_tga__decoder();
9677 
9678 // ---------------- Allocs
9679 
9680 // These functions allocate and initialize Wuffs structs. They return NULL if
9681 // memory allocation fails. If they return non-NULL, there is no need to call
9682 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9683 // calling free on the returned pointer. That pointer is effectively a C++
9684 // std::unique_ptr<T, decltype(&free)>.
9685 
9686 wuffs_tga__decoder*
9687 wuffs_tga__decoder__alloc();
9688 
9689 static inline wuffs_base__image_decoder*
wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder()9690 wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder() {
9691   return (wuffs_base__image_decoder*)(wuffs_tga__decoder__alloc());
9692 }
9693 
9694 // ---------------- Upcasts
9695 
9696 static inline wuffs_base__image_decoder*
wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(wuffs_tga__decoder * p)9697 wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(
9698     wuffs_tga__decoder* p) {
9699   return (wuffs_base__image_decoder*)p;
9700 }
9701 
9702 // ---------------- Public Function Prototypes
9703 
9704 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9705 wuffs_tga__decoder__set_quirk_enabled(
9706     wuffs_tga__decoder* self,
9707     uint32_t a_quirk,
9708     bool a_enabled);
9709 
9710 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9711 wuffs_tga__decoder__decode_image_config(
9712     wuffs_tga__decoder* self,
9713     wuffs_base__image_config* a_dst,
9714     wuffs_base__io_buffer* a_src);
9715 
9716 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9717 wuffs_tga__decoder__decode_frame_config(
9718     wuffs_tga__decoder* self,
9719     wuffs_base__frame_config* a_dst,
9720     wuffs_base__io_buffer* a_src);
9721 
9722 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9723 wuffs_tga__decoder__decode_frame(
9724     wuffs_tga__decoder* self,
9725     wuffs_base__pixel_buffer* a_dst,
9726     wuffs_base__io_buffer* a_src,
9727     wuffs_base__pixel_blend a_blend,
9728     wuffs_base__slice_u8 a_workbuf,
9729     wuffs_base__decode_frame_options* a_opts);
9730 
9731 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9732 wuffs_tga__decoder__frame_dirty_rect(
9733     const wuffs_tga__decoder* self);
9734 
9735 WUFFS_BASE__MAYBE_STATIC uint32_t
9736 wuffs_tga__decoder__num_animation_loops(
9737     const wuffs_tga__decoder* self);
9738 
9739 WUFFS_BASE__MAYBE_STATIC uint64_t
9740 wuffs_tga__decoder__num_decoded_frame_configs(
9741     const wuffs_tga__decoder* self);
9742 
9743 WUFFS_BASE__MAYBE_STATIC uint64_t
9744 wuffs_tga__decoder__num_decoded_frames(
9745     const wuffs_tga__decoder* self);
9746 
9747 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9748 wuffs_tga__decoder__restart_frame(
9749     wuffs_tga__decoder* self,
9750     uint64_t a_index,
9751     uint64_t a_io_position);
9752 
9753 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9754 wuffs_tga__decoder__set_report_metadata(
9755     wuffs_tga__decoder* self,
9756     uint32_t a_fourcc,
9757     bool a_report);
9758 
9759 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9760 wuffs_tga__decoder__tell_me_more(
9761     wuffs_tga__decoder* self,
9762     wuffs_base__io_buffer* a_dst,
9763     wuffs_base__more_information* a_minfo,
9764     wuffs_base__io_buffer* a_src);
9765 
9766 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9767 wuffs_tga__decoder__workbuf_len(
9768     const wuffs_tga__decoder* self);
9769 
9770 #ifdef __cplusplus
9771 }  // extern "C"
9772 #endif
9773 
9774 // ---------------- Struct Definitions
9775 
9776 // These structs' fields, and the sizeof them, are private implementation
9777 // details that aren't guaranteed to be stable across Wuffs versions.
9778 //
9779 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9780 
9781 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9782 
9783 struct wuffs_tga__decoder__struct {
9784   // Do not access the private_impl's or private_data's fields directly. There
9785   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9786   // the wuffs_foo__bar__baz functions.
9787   //
9788   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9789   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9790 
9791   struct {
9792     uint32_t magic;
9793     uint32_t active_coroutine;
9794     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9795     wuffs_base__vtable null_vtable;
9796 
9797     uint32_t f_width;
9798     uint32_t f_height;
9799     uint8_t f_call_sequence;
9800     uint8_t f_header_id_length;
9801     uint8_t f_header_color_map_type;
9802     uint8_t f_header_image_type;
9803     uint16_t f_header_color_map_first_entry_index;
9804     uint16_t f_header_color_map_length;
9805     uint8_t f_header_color_map_entry_size;
9806     uint8_t f_header_pixel_depth;
9807     uint8_t f_header_image_descriptor;
9808     bool f_opaque;
9809     uint32_t f_scratch_bytes_per_pixel;
9810     uint32_t f_src_bytes_per_pixel;
9811     uint32_t f_src_pixfmt;
9812     uint64_t f_frame_config_io_position;
9813     wuffs_base__pixel_swizzler f_swizzler;
9814 
9815     uint32_t p_decode_image_config[1];
9816     uint32_t p_decode_frame_config[1];
9817     uint32_t p_decode_frame[1];
9818   } private_impl;
9819 
9820   struct {
9821     uint8_t f_dst_palette[1024];
9822     uint8_t f_src_palette[1024];
9823     uint8_t f_scratch[4];
9824 
9825     struct {
9826       uint32_t v_i;
9827       uint64_t scratch;
9828     } s_decode_image_config[1];
9829     struct {
9830       uint64_t v_dst_bytes_per_pixel;
9831       uint32_t v_dst_x;
9832       uint32_t v_dst_y;
9833       uint64_t v_mark;
9834       uint32_t v_num_pixels32;
9835       uint32_t v_lit_length;
9836       uint32_t v_run_length;
9837       uint64_t v_num_dst_bytes;
9838       uint64_t scratch;
9839     } s_decode_frame[1];
9840   } private_data;
9841 
9842 #ifdef __cplusplus
9843 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9844   using unique_ptr = std::unique_ptr<wuffs_tga__decoder, decltype(&free)>;
9845 
9846   // On failure, the alloc_etc functions return nullptr. They don't throw.
9847 
9848   static inline unique_ptr
allocwuffs_tga__decoder__struct9849   alloc() {
9850     return unique_ptr(wuffs_tga__decoder__alloc(), &free);
9851   }
9852 
9853   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_tga__decoder__struct9854   alloc_as__wuffs_base__image_decoder() {
9855     return wuffs_base__image_decoder::unique_ptr(
9856         wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(), &free);
9857   }
9858 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9859 
9860 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9861   // Disallow constructing or copying an object via standard C++ mechanisms,
9862   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9863   // size and field layout is not part of the public, stable, memory-safe API.
9864   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9865   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9866   // their first argument) rather than tweaking bar.private_impl.qux fields.
9867   //
9868   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9869   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9870   // order to provide convenience methods. These forward on "this", so that you
9871   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9872   wuffs_tga__decoder__struct() = delete;
9873   wuffs_tga__decoder__struct(const wuffs_tga__decoder__struct&) = delete;
9874   wuffs_tga__decoder__struct& operator=(
9875       const wuffs_tga__decoder__struct&) = delete;
9876 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9877 
9878 #if !defined(WUFFS_IMPLEMENTATION)
9879   // As above, the size of the struct is not part of the public API, and unless
9880   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9881   // allocated, not stack allocated. Its size is not intended to be known at
9882   // compile time, but it is unfortunately divulged as a side effect of
9883   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9884   // instead of "sizeof T", invoking the operator. To make the two values
9885   // different, so that passing the latter will be rejected by the initialize
9886   // function, we add an arbitrary amount of dead weight.
9887   uint8_t dead_weight[123000000];  // 123 MB.
9888 #endif  // !defined(WUFFS_IMPLEMENTATION)
9889 
9890   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_tga__decoder__struct9891   initialize(
9892       size_t sizeof_star_self,
9893       uint64_t wuffs_version,
9894       uint32_t options) {
9895     return wuffs_tga__decoder__initialize(
9896         this, sizeof_star_self, wuffs_version, options);
9897   }
9898 
9899   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_tga__decoder__struct9900   upcast_as__wuffs_base__image_decoder() {
9901     return (wuffs_base__image_decoder*)this;
9902   }
9903 
9904   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_tga__decoder__struct9905   set_quirk_enabled(
9906       uint32_t a_quirk,
9907       bool a_enabled) {
9908     return wuffs_tga__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9909   }
9910 
9911   inline wuffs_base__status
decode_image_configwuffs_tga__decoder__struct9912   decode_image_config(
9913       wuffs_base__image_config* a_dst,
9914       wuffs_base__io_buffer* a_src) {
9915     return wuffs_tga__decoder__decode_image_config(this, a_dst, a_src);
9916   }
9917 
9918   inline wuffs_base__status
decode_frame_configwuffs_tga__decoder__struct9919   decode_frame_config(
9920       wuffs_base__frame_config* a_dst,
9921       wuffs_base__io_buffer* a_src) {
9922     return wuffs_tga__decoder__decode_frame_config(this, a_dst, a_src);
9923   }
9924 
9925   inline wuffs_base__status
decode_framewuffs_tga__decoder__struct9926   decode_frame(
9927       wuffs_base__pixel_buffer* a_dst,
9928       wuffs_base__io_buffer* a_src,
9929       wuffs_base__pixel_blend a_blend,
9930       wuffs_base__slice_u8 a_workbuf,
9931       wuffs_base__decode_frame_options* a_opts) {
9932     return wuffs_tga__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9933   }
9934 
9935   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_tga__decoder__struct9936   frame_dirty_rect() const {
9937     return wuffs_tga__decoder__frame_dirty_rect(this);
9938   }
9939 
9940   inline uint32_t
num_animation_loopswuffs_tga__decoder__struct9941   num_animation_loops() const {
9942     return wuffs_tga__decoder__num_animation_loops(this);
9943   }
9944 
9945   inline uint64_t
num_decoded_frame_configswuffs_tga__decoder__struct9946   num_decoded_frame_configs() const {
9947     return wuffs_tga__decoder__num_decoded_frame_configs(this);
9948   }
9949 
9950   inline uint64_t
num_decoded_frameswuffs_tga__decoder__struct9951   num_decoded_frames() const {
9952     return wuffs_tga__decoder__num_decoded_frames(this);
9953   }
9954 
9955   inline wuffs_base__status
restart_framewuffs_tga__decoder__struct9956   restart_frame(
9957       uint64_t a_index,
9958       uint64_t a_io_position) {
9959     return wuffs_tga__decoder__restart_frame(this, a_index, a_io_position);
9960   }
9961 
9962   inline wuffs_base__empty_struct
set_report_metadatawuffs_tga__decoder__struct9963   set_report_metadata(
9964       uint32_t a_fourcc,
9965       bool a_report) {
9966     return wuffs_tga__decoder__set_report_metadata(this, a_fourcc, a_report);
9967   }
9968 
9969   inline wuffs_base__status
tell_me_morewuffs_tga__decoder__struct9970   tell_me_more(
9971       wuffs_base__io_buffer* a_dst,
9972       wuffs_base__more_information* a_minfo,
9973       wuffs_base__io_buffer* a_src) {
9974     return wuffs_tga__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9975   }
9976 
9977   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_tga__decoder__struct9978   workbuf_len() const {
9979     return wuffs_tga__decoder__workbuf_len(this);
9980   }
9981 
9982 #endif  // __cplusplus
9983 };  // struct wuffs_tga__decoder__struct
9984 
9985 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9986 
9987 // ---------------- Status Codes
9988 
9989 extern const char wuffs_wbmp__error__bad_header[];
9990 
9991 // ---------------- Public Consts
9992 
9993 #define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9994 
9995 // ---------------- Struct Declarations
9996 
9997 typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder;
9998 
9999 #ifdef __cplusplus
10000 extern "C" {
10001 #endif
10002 
10003 // ---------------- Public Initializer Prototypes
10004 
10005 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10006 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10007 //
10008 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10009 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10010 
10011 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10012 wuffs_wbmp__decoder__initialize(
10013     wuffs_wbmp__decoder* self,
10014     size_t sizeof_star_self,
10015     uint64_t wuffs_version,
10016     uint32_t options);
10017 
10018 size_t
10019 sizeof__wuffs_wbmp__decoder();
10020 
10021 // ---------------- Allocs
10022 
10023 // These functions allocate and initialize Wuffs structs. They return NULL if
10024 // memory allocation fails. If they return non-NULL, there is no need to call
10025 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10026 // calling free on the returned pointer. That pointer is effectively a C++
10027 // std::unique_ptr<T, decltype(&free)>.
10028 
10029 wuffs_wbmp__decoder*
10030 wuffs_wbmp__decoder__alloc();
10031 
10032 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder()10033 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder() {
10034   return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
10035 }
10036 
10037 // ---------------- Upcasts
10038 
10039 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_wbmp__decoder * p)10040 wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
10041     wuffs_wbmp__decoder* p) {
10042   return (wuffs_base__image_decoder*)p;
10043 }
10044 
10045 // ---------------- Public Function Prototypes
10046 
10047 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
10048 wuffs_wbmp__decoder__set_quirk_enabled(
10049     wuffs_wbmp__decoder* self,
10050     uint32_t a_quirk,
10051     bool a_enabled);
10052 
10053 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10054 wuffs_wbmp__decoder__decode_image_config(
10055     wuffs_wbmp__decoder* self,
10056     wuffs_base__image_config* a_dst,
10057     wuffs_base__io_buffer* a_src);
10058 
10059 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10060 wuffs_wbmp__decoder__decode_frame_config(
10061     wuffs_wbmp__decoder* self,
10062     wuffs_base__frame_config* a_dst,
10063     wuffs_base__io_buffer* a_src);
10064 
10065 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10066 wuffs_wbmp__decoder__decode_frame(
10067     wuffs_wbmp__decoder* self,
10068     wuffs_base__pixel_buffer* a_dst,
10069     wuffs_base__io_buffer* a_src,
10070     wuffs_base__pixel_blend a_blend,
10071     wuffs_base__slice_u8 a_workbuf,
10072     wuffs_base__decode_frame_options* a_opts);
10073 
10074 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
10075 wuffs_wbmp__decoder__frame_dirty_rect(
10076     const wuffs_wbmp__decoder* self);
10077 
10078 WUFFS_BASE__MAYBE_STATIC uint32_t
10079 wuffs_wbmp__decoder__num_animation_loops(
10080     const wuffs_wbmp__decoder* self);
10081 
10082 WUFFS_BASE__MAYBE_STATIC uint64_t
10083 wuffs_wbmp__decoder__num_decoded_frame_configs(
10084     const wuffs_wbmp__decoder* self);
10085 
10086 WUFFS_BASE__MAYBE_STATIC uint64_t
10087 wuffs_wbmp__decoder__num_decoded_frames(
10088     const wuffs_wbmp__decoder* self);
10089 
10090 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10091 wuffs_wbmp__decoder__restart_frame(
10092     wuffs_wbmp__decoder* self,
10093     uint64_t a_index,
10094     uint64_t a_io_position);
10095 
10096 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
10097 wuffs_wbmp__decoder__set_report_metadata(
10098     wuffs_wbmp__decoder* self,
10099     uint32_t a_fourcc,
10100     bool a_report);
10101 
10102 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10103 wuffs_wbmp__decoder__tell_me_more(
10104     wuffs_wbmp__decoder* self,
10105     wuffs_base__io_buffer* a_dst,
10106     wuffs_base__more_information* a_minfo,
10107     wuffs_base__io_buffer* a_src);
10108 
10109 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10110 wuffs_wbmp__decoder__workbuf_len(
10111     const wuffs_wbmp__decoder* self);
10112 
10113 #ifdef __cplusplus
10114 }  // extern "C"
10115 #endif
10116 
10117 // ---------------- Struct Definitions
10118 
10119 // These structs' fields, and the sizeof them, are private implementation
10120 // details that aren't guaranteed to be stable across Wuffs versions.
10121 //
10122 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10123 
10124 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10125 
10126 struct wuffs_wbmp__decoder__struct {
10127   // Do not access the private_impl's or private_data's fields directly. There
10128   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10129   // the wuffs_foo__bar__baz functions.
10130   //
10131   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10132   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10133 
10134   struct {
10135     uint32_t magic;
10136     uint32_t active_coroutine;
10137     wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
10138     wuffs_base__vtable null_vtable;
10139 
10140     uint32_t f_width;
10141     uint32_t f_height;
10142     uint8_t f_call_sequence;
10143     uint64_t f_frame_config_io_position;
10144     wuffs_base__pixel_swizzler f_swizzler;
10145 
10146     uint32_t p_decode_image_config[1];
10147     uint32_t p_decode_frame_config[1];
10148     uint32_t p_decode_frame[1];
10149   } private_impl;
10150 
10151   struct {
10152     struct {
10153       uint32_t v_i;
10154       uint32_t v_x32;
10155     } s_decode_image_config[1];
10156     struct {
10157       uint64_t v_dst_bytes_per_pixel;
10158       uint32_t v_dst_x;
10159       uint32_t v_dst_y;
10160       uint8_t v_src[1];
10161       uint8_t v_c;
10162     } s_decode_frame[1];
10163   } private_data;
10164 
10165 #ifdef __cplusplus
10166 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10167   using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, decltype(&free)>;
10168 
10169   // On failure, the alloc_etc functions return nullptr. They don't throw.
10170 
10171   static inline unique_ptr
allocwuffs_wbmp__decoder__struct10172   alloc() {
10173     return unique_ptr(wuffs_wbmp__decoder__alloc(), &free);
10174   }
10175 
10176   static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct10177   alloc_as__wuffs_base__image_decoder() {
10178     return wuffs_base__image_decoder::unique_ptr(
10179         wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
10180   }
10181 #endif  // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10182 
10183 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10184   // Disallow constructing or copying an object via standard C++ mechanisms,
10185   // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10186   // size and field layout is not part of the public, stable, memory-safe API.
10187   // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10188   // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10189   // their first argument) rather than tweaking bar.private_impl.qux fields.
10190   //
10191   // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10192   // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10193   // order to provide convenience methods. These forward on "this", so that you
10194   // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10195   wuffs_wbmp__decoder__struct() = delete;
10196   wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete;
10197   wuffs_wbmp__decoder__struct& operator=(
10198       const wuffs_wbmp__decoder__struct&) = delete;
10199 #endif  // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10200 
10201 #if !defined(WUFFS_IMPLEMENTATION)
10202   // As above, the size of the struct is not part of the public API, and unless
10203   // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10204   // allocated, not stack allocated. Its size is not intended to be known at
10205   // compile time, but it is unfortunately divulged as a side effect of
10206   // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10207   // instead of "sizeof T", invoking the operator. To make the two values
10208   // different, so that passing the latter will be rejected by the initialize
10209   // function, we add an arbitrary amount of dead weight.
10210   uint8_t dead_weight[123000000];  // 123 MB.
10211 #endif  // !defined(WUFFS_IMPLEMENTATION)
10212 
10213   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_wbmp__decoder__struct10214   initialize(
10215       size_t sizeof_star_self,
10216       uint64_t wuffs_version,
10217       uint32_t options) {
10218     return wuffs_wbmp__decoder__initialize(
10219         this, sizeof_star_self, wuffs_version, options);
10220   }
10221 
10222   inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct10223   upcast_as__wuffs_base__image_decoder() {
10224     return (wuffs_base__image_decoder*)this;
10225   }
10226 
10227   inline wuffs_base__empty_struct
set_quirk_enabledwuffs_wbmp__decoder__struct10228   set_quirk_enabled(
10229       uint32_t a_quirk,
10230       bool a_enabled) {
10231     return wuffs_wbmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
10232   }
10233 
10234   inline wuffs_base__status
decode_image_configwuffs_wbmp__decoder__struct10235   decode_image_config(
10236       wuffs_base__image_config* a_dst,
10237       wuffs_base__io_buffer* a_src) {
10238     return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src);
10239   }
10240 
10241   inline wuffs_base__status
decode_frame_configwuffs_wbmp__decoder__struct10242   decode_frame_config(
10243       wuffs_base__frame_config* a_dst,
10244       wuffs_base__io_buffer* a_src) {
10245     return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src);
10246   }
10247 
10248   inline wuffs_base__status
decode_framewuffs_wbmp__decoder__struct10249   decode_frame(
10250       wuffs_base__pixel_buffer* a_dst,
10251       wuffs_base__io_buffer* a_src,
10252       wuffs_base__pixel_blend a_blend,
10253       wuffs_base__slice_u8 a_workbuf,
10254       wuffs_base__decode_frame_options* a_opts) {
10255     return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
10256   }
10257 
10258   inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_wbmp__decoder__struct10259   frame_dirty_rect() const {
10260     return wuffs_wbmp__decoder__frame_dirty_rect(this);
10261   }
10262 
10263   inline uint32_t
num_animation_loopswuffs_wbmp__decoder__struct10264   num_animation_loops() const {
10265     return wuffs_wbmp__decoder__num_animation_loops(this);
10266   }
10267 
10268   inline uint64_t
num_decoded_frame_configswuffs_wbmp__decoder__struct10269   num_decoded_frame_configs() const {
10270     return wuffs_wbmp__decoder__num_decoded_frame_configs(this);
10271   }
10272 
10273   inline uint64_t
num_decoded_frameswuffs_wbmp__decoder__struct10274   num_decoded_frames() const {
10275     return wuffs_wbmp__decoder__num_decoded_frames(this);
10276   }
10277 
10278   inline wuffs_base__status
restart_framewuffs_wbmp__decoder__struct10279   restart_frame(
10280       uint64_t a_index,
10281       uint64_t a_io_position) {
10282     return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position);
10283   }
10284 
10285   inline wuffs_base__empty_struct
set_report_metadatawuffs_wbmp__decoder__struct10286   set_report_metadata(
10287       uint32_t a_fourcc,
10288       bool a_report) {
10289     return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report);
10290   }
10291 
10292   inline wuffs_base__status
tell_me_morewuffs_wbmp__decoder__struct10293   tell_me_more(
10294       wuffs_base__io_buffer* a_dst,
10295       wuffs_base__more_information* a_minfo,
10296       wuffs_base__io_buffer* a_src) {
10297     return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
10298   }
10299 
10300   inline wuffs_base__range_ii_u64
workbuf_lenwuffs_wbmp__decoder__struct10301   workbuf_len() const {
10302     return wuffs_wbmp__decoder__workbuf_len(this);
10303   }
10304 
10305 #endif  // __cplusplus
10306 };  // struct wuffs_wbmp__decoder__struct
10307 
10308 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10309 
10310 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10311 
10312 // ---------------- Auxiliary - Base
10313 
10314 // Auxiliary code is discussed at
10315 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
10316 
10317 #include <stdio.h>
10318 
10319 #include <string>
10320 
10321 namespace wuffs_aux {
10322 
10323 using IOBuffer = wuffs_base__io_buffer;
10324 
10325 // MemOwner represents ownership of some memory. Dynamically allocated memory
10326 // (e.g. from malloc or new) is typically paired with free or delete, invoked
10327 // when the std::unique_ptr is destroyed. Statically allocated memory might use
10328 // MemOwner(nullptr, &free), even if that statically allocated memory is not
10329 // nullptr, since calling free(nullptr) is a no-op.
10330 using MemOwner = std::unique_ptr<void, decltype(&free)>;
10331 
10332 namespace sync_io {
10333 
10334 // --------
10335 
10336 // DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array.
10337 // It owns that backing array and will free it in its destructor.
10338 //
10339 // The array size can be explicitly extended (by calling the grow method) but,
10340 // unlike a C++ std::vector, there is no implicit extension (e.g. by calling
10341 // std::vector::insert) and its maximum size is capped by the max_incl
10342 // constructor argument.
10343 //
10344 // It contains an IOBuffer-typed field whose reader side provides access to
10345 // previously written bytes and whose writer side provides access to the
10346 // allocated but not-yet-written-to slack space. For Go programmers, this slack
10347 // space is roughly analogous to the s[len(s):cap(s)] space of a slice s.
10348 class DynIOBuffer {
10349  public:
10350   enum GrowResult {
10351     OK = 0,
10352     FailedMaxInclExceeded = 1,
10353     FailedOutOfMemory = 2,
10354   };
10355 
10356   // m_buf holds the dynamically sized byte array and its read/write indexes:
10357   //  - m_buf.meta.wi  is roughly analogous to a Go slice's length.
10358   //  - m_buf.data.len is roughly analogous to a Go slice's capacity. It is
10359   //    also equal to the m_buf.data.ptr malloc/realloc size.
10360   //
10361   // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as
10362   // they are conceptually private to this class), but they can modify the
10363   // bytes referenced by that pointer-length pair (e.g. compactions).
10364   IOBuffer m_buf;
10365 
10366   // m_max_incl is an inclusive upper bound on the backing array size.
10367   const uint64_t m_max_incl;
10368 
10369   // Constructor and destructor.
10370   explicit DynIOBuffer(uint64_t max_incl);
10371   ~DynIOBuffer();
10372 
10373   // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be
10374   // used after a drop call. It just restarts from zero.
10375   void drop();
10376 
10377   // grow ensures that the byte array size is at least min_incl and at most
10378   // max_incl. It returns FailedMaxInclExceeded if that would require
10379   // allocating more than max_incl bytes, including the case where (min_incl >
10380   // max_incl). It returns FailedOutOfMemory if memory allocation failed.
10381   GrowResult grow(uint64_t min_incl);
10382 
10383  private:
10384   // Delete the copy and assign constructors.
10385   DynIOBuffer(const DynIOBuffer&) = delete;
10386   DynIOBuffer& operator=(const DynIOBuffer&) = delete;
10387 
10388   static uint64_t round_up(uint64_t min_incl, uint64_t max_incl);
10389 };
10390 
10391 // --------
10392 
10393 class Input {
10394  public:
10395   virtual ~Input();
10396 
10397   virtual IOBuffer* BringsItsOwnIOBuffer();
10398   virtual std::string CopyIn(IOBuffer* dst) = 0;
10399 };
10400 
10401 // --------
10402 
10403 // FileInput is an Input that reads from a file source.
10404 //
10405 // It does not take responsibility for closing the file when done.
10406 class FileInput : public Input {
10407  public:
10408   FileInput(FILE* f);
10409 
10410   virtual std::string CopyIn(IOBuffer* dst);
10411 
10412  private:
10413   FILE* m_f;
10414 
10415   // Delete the copy and assign constructors.
10416   FileInput(const FileInput&) = delete;
10417   FileInput& operator=(const FileInput&) = delete;
10418 };
10419 
10420 // --------
10421 
10422 // MemoryInput is an Input that reads from an in-memory source.
10423 //
10424 // It does not take responsibility for freeing the memory when done.
10425 class MemoryInput : public Input {
10426  public:
10427   MemoryInput(const char* ptr, size_t len);
10428   MemoryInput(const uint8_t* ptr, size_t len);
10429 
10430   virtual IOBuffer* BringsItsOwnIOBuffer();
10431   virtual std::string CopyIn(IOBuffer* dst);
10432 
10433  private:
10434   IOBuffer m_io;
10435 
10436   // Delete the copy and assign constructors.
10437   MemoryInput(const MemoryInput&) = delete;
10438   MemoryInput& operator=(const MemoryInput&) = delete;
10439 };
10440 
10441 // --------
10442 
10443 }  // namespace sync_io
10444 
10445 }  // namespace wuffs_aux
10446 
10447 // ---------------- Auxiliary - CBOR
10448 
10449 namespace wuffs_aux {
10450 
10451 struct DecodeCborResult {
10452   DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0);
10453 
10454   std::string error_message;
10455   uint64_t cursor_position;
10456 };
10457 
10458 class DecodeCborCallbacks {
10459  public:
10460   virtual ~DecodeCborCallbacks();
10461 
10462   // AppendXxx are called for leaf nodes: literals, numbers, strings, etc.
10463 
10464   virtual std::string AppendNull() = 0;
10465   virtual std::string AppendUndefined() = 0;
10466   virtual std::string AppendBool(bool val) = 0;
10467   virtual std::string AppendF64(double val) = 0;
10468   virtual std::string AppendI64(int64_t val) = 0;
10469   virtual std::string AppendU64(uint64_t val) = 0;
10470   virtual std::string AppendByteString(std::string&& val) = 0;
10471   virtual std::string AppendTextString(std::string&& val) = 0;
10472   virtual std::string AppendMinus1MinusX(uint64_t val) = 0;
10473   virtual std::string AppendCborSimpleValue(uint8_t val) = 0;
10474   virtual std::string AppendCborTag(uint64_t val) = 0;
10475 
10476   // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR
10477   // maps (dictionaries).
10478   //
10479   // The flags bits combine exactly one of:
10480   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
10481   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
10482   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
10483   // and exactly one of:
10484   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
10485   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
10486   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
10487 
10488   virtual std::string Push(uint32_t flags) = 0;
10489   virtual std::string Pop(uint32_t flags) = 0;
10490 
10491   // Done is always the last Callback method called by DecodeCbor, whether or
10492   // not parsing the input as CBOR encountered an error. Even when successful,
10493   // trailing data may remain in input and buffer.
10494   //
10495   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10496   // as DecodeCbor may then de-allocate the backing array.
10497   //
10498   // The default Done implementation is a no-op.
10499   virtual void  //
10500   Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer);
10501 };
10502 
10503 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10504 // inner representations for several reasons:
10505 //  - It provides a home for the DefaultValue static method, for Foo callers
10506 //    that want to override some but not all optional arguments.
10507 //  - It provides the "Bar" name at Foo call sites, which can help self-
10508 //    document Foo calls with many arguemnts.
10509 //  - It provides some type safety against accidentally transposing or omitting
10510 //    adjacent fundamentally-numeric-typed optional arguments.
10511 
10512 // DecodeCborArgQuirks wraps an optional argument to DecodeCbor.
10513 struct DecodeCborArgQuirks {
10514   explicit DecodeCborArgQuirks(wuffs_base__slice_u32 repr0);
10515   explicit DecodeCborArgQuirks(uint32_t* ptr, size_t len);
10516 
10517   // DefaultValue returns an empty slice.
10518   static DecodeCborArgQuirks DefaultValue();
10519 
10520   wuffs_base__slice_u32 repr;
10521 };
10522 
10523 // DecodeCbor calls callbacks based on the CBOR-formatted data in input.
10524 //
10525 // On success, the returned error_message is empty and cursor_position counts
10526 // the number of bytes consumed. On failure, error_message is non-empty and
10527 // cursor_position is the location of the error. That error may be a content
10528 // error (invalid CBOR) or an input error (e.g. network failure).
10529 DecodeCborResult  //
10530 DecodeCbor(DecodeCborCallbacks& callbacks,
10531            sync_io::Input& input,
10532            DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue());
10533 
10534 }  // namespace wuffs_aux
10535 
10536 // ---------------- Auxiliary - Image
10537 
10538 namespace wuffs_aux {
10539 
10540 struct DecodeImageResult {
10541   DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
10542                     wuffs_base__pixel_buffer pixbuf0,
10543                     std::string&& error_message0);
10544   DecodeImageResult(std::string&& error_message0);
10545 
10546   MemOwner pixbuf_mem_owner;
10547   wuffs_base__pixel_buffer pixbuf;
10548   std::string error_message;
10549 };
10550 
10551 // DecodeImageCallbacks are the callbacks given to DecodeImage. They are always
10552 // called in this order:
10553 //  1. SelectDecoder
10554 //  2. HandleMetadata
10555 //  3. SelectPixfmt
10556 //  4. AllocPixbuf
10557 //  5. AllocWorkbuf
10558 //  6. Done
10559 //
10560 // It may return early - the third callback might not be invoked if the second
10561 // one fails - but the final callback (Done) is always invoked.
10562 class DecodeImageCallbacks {
10563  public:
10564   // AllocPixbufResult holds a memory allocation (the result of malloc or new,
10565   // a statically allocated pointer, etc), or an error message. The memory is
10566   // de-allocated when mem_owner goes out of scope and is destroyed.
10567   struct AllocPixbufResult {
10568     AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
10569     AllocPixbufResult(std::string&& error_message0);
10570 
10571     MemOwner mem_owner;
10572     wuffs_base__pixel_buffer pixbuf;
10573     std::string error_message;
10574   };
10575 
10576   // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
10577   // a statically allocated pointer, etc), or an error message. The memory is
10578   // de-allocated when mem_owner goes out of scope and is destroyed.
10579   struct AllocWorkbufResult {
10580     AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
10581     AllocWorkbufResult(std::string&& error_message0);
10582 
10583     MemOwner mem_owner;
10584     wuffs_base__slice_u8 workbuf;
10585     std::string error_message;
10586   };
10587 
10588   virtual ~DecodeImageCallbacks();
10589 
10590   // SelectDecoder returns the image decoder for the input data's file format.
10591   // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
10592   //
10593   // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
10594   // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that Wuffs'
10595   // standard library did not recognize the image format but if SelectDecoder
10596   // was overridden, it may examine the input data's starting bytes and still
10597   // provide its own image decoder, e.g. for an exotic image file format that's
10598   // not in Wuffs' standard library. The prefix_etc fields have the same
10599   // meaning as wuffs_base__magic_number_guess_fourcc arguments. SelectDecoder
10600   // implementations should not modify prefix_data's contents.
10601   //
10602   // SelectDecoder might be called more than once, since some image file
10603   // formats can wrap others. For example, a nominal BMP file can actually
10604   // contain a JPEG or a PNG.
10605   //
10606   // The default SelectDecoder accepts the FOURCC codes listed below. For
10607   // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
10608   // of the ETC file format is optional (for each value of ETC) and depends on
10609   // the corresponding module to be enabled at compile time (i.e. #define'ing
10610   // WUFFS_CONFIG__MODULE__ETC).
10611   //  - WUFFS_BASE__FOURCC__BMP
10612   //  - WUFFS_BASE__FOURCC__GIF
10613   //  - WUFFS_BASE__FOURCC__NIE
10614   //  - WUFFS_BASE__FOURCC__PNG
10615   //  - WUFFS_BASE__FOURCC__TGA
10616   //  - WUFFS_BASE__FOURCC__WBMP
10617   virtual wuffs_base__image_decoder::unique_ptr  //
10618   SelectDecoder(uint32_t fourcc,
10619                 wuffs_base__slice_u8 prefix_data,
10620                 bool prefix_closed);
10621 
10622   // HandleMetadata acknowledges image metadata. minfo.flavor will be one of:
10623   //  - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH
10624   //  - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED
10625   // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those
10626   // bytes should not be retained beyond the the HandleMetadata call.
10627   //
10628   // minfo.metadata__fourcc() will typically match one of the
10629   // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM |
10630   // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC
10631   // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA.
10632   //
10633   // It returns an error message, or an empty string on success.
10634   virtual std::string  //
10635   HandleMetadata(const wuffs_base__more_information& minfo,
10636                  wuffs_base__slice_u8 raw);
10637 
10638   // SelectPixfmt returns the destination pixel format for AllocPixbuf. It
10639   // should return wuffs_base__make_pixel_format(etc) called with one of:
10640   //  - WUFFS_BASE__PIXEL_FORMAT__BGR_565
10641   //  - WUFFS_BASE__PIXEL_FORMAT__BGR
10642   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL
10643   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
10644   //  - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL
10645   //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL
10646   //  - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL
10647   // or return image_config.pixcfg.pixel_format(). The latter means to use the
10648   // image file's natural pixel format. For example, GIF images' natural pixel
10649   // format is an indexed one.
10650   //
10651   // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).
10652   //
10653   // The default SelectPixfmt implementation returns
10654   // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which
10655   // is 4 bytes per pixel (8 bits per channel × 4 channels).
10656   virtual wuffs_base__pixel_format  //
10657   SelectPixfmt(const wuffs_base__image_config& image_config);
10658 
10659   // AllocPixbuf allocates the pixel buffer.
10660   //
10661   // allow_uninitialized_memory will be true if a valid background_color was
10662   // passed to DecodeImage, since the pixel buffer's contents will be
10663   // overwritten with that color after AllocPixbuf returns.
10664   //
10665   // The default AllocPixbuf implementation allocates either uninitialized or
10666   // zeroed memory. Zeroed memory typically corresponds to filling with opaque
10667   // black or transparent black, depending on the pixel format.
10668   virtual AllocPixbufResult  //
10669   AllocPixbuf(const wuffs_base__image_config& image_config,
10670               bool allow_uninitialized_memory);
10671 
10672   // AllocWorkbuf allocates the work buffer. The allocated buffer's length
10673   // should be at least len_range.min_incl, but larger allocations (up to
10674   // len_range.max_incl) may have better performance (by using more memory).
10675   //
10676   // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
10677   // of either uninitialized or zeroed memory.
10678   virtual AllocWorkbufResult  //
10679   AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
10680                bool allow_uninitialized_memory);
10681 
10682   // Done is always the last Callback method called by DecodeImage, whether or
10683   // not parsing the input encountered an error. Even when successful, trailing
10684   // data may remain in input and buffer.
10685   //
10686   // The image_decoder is the one returned by SelectDecoder (if SelectDecoder
10687   // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,
10688   // ownership moves to the Done implementation.
10689   //
10690   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10691   // as DecodeImage may then de-allocate the backing array.
10692   //
10693   // The default Done implementation is a no-op, other than running the
10694   // image_decoder unique_ptr destructor.
10695   virtual void  //
10696   Done(DecodeImageResult& result,
10697        sync_io::Input& input,
10698        IOBuffer& buffer,
10699        wuffs_base__image_decoder::unique_ptr image_decoder);
10700 };
10701 
10702 extern const char DecodeImage_BufferIsTooShort[];
10703 extern const char DecodeImage_MaxInclDimensionExceeded[];
10704 extern const char DecodeImage_MaxInclMetadataLengthExceeded[];
10705 extern const char DecodeImage_OutOfMemory[];
10706 extern const char DecodeImage_UnexpectedEndOfFile[];
10707 extern const char DecodeImage_UnsupportedImageFormat[];
10708 extern const char DecodeImage_UnsupportedMetadata[];
10709 extern const char DecodeImage_UnsupportedPixelBlend[];
10710 extern const char DecodeImage_UnsupportedPixelConfiguration[];
10711 extern const char DecodeImage_UnsupportedPixelFormat[];
10712 
10713 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10714 // inner representations for several reasons:
10715 //  - It provides a home for the DefaultValue static method, for Foo callers
10716 //    that want to override some but not all optional arguments.
10717 //  - It provides the "Bar" name at Foo call sites, which can help self-
10718 //    document Foo calls with many arguemnts.
10719 //  - It provides some type safety against accidentally transposing or omitting
10720 //    adjacent fundamentally-numeric-typed optional arguments.
10721 
10722 // DecodeImageArgQuirks wraps an optional argument to DecodeImage.
10723 struct DecodeImageArgQuirks {
10724   explicit DecodeImageArgQuirks(wuffs_base__slice_u32 repr0);
10725   explicit DecodeImageArgQuirks(uint32_t* ptr, size_t len);
10726 
10727   // DefaultValue returns an empty slice.
10728   static DecodeImageArgQuirks DefaultValue();
10729 
10730   wuffs_base__slice_u32 repr;
10731 };
10732 
10733 // DecodeImageArgFlags wraps an optional argument to DecodeImage.
10734 struct DecodeImageArgFlags {
10735   explicit DecodeImageArgFlags(uint64_t repr0);
10736 
10737   // DefaultValue returns 0.
10738   static DecodeImageArgFlags DefaultValue();
10739 
10740   // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, EXIF,
10741   // GAMA, ICCP, KVP, SRGB and XMP.
10742 
10743   // Background Color.
10744   static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001;
10745   // Primary Chromaticities and White Point.
10746   static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002;
10747   // Exchangeable Image File Format.
10748   static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004;
10749   // Gamma Correction.
10750   static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008;
10751   // International Color Consortium Profile.
10752   static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010;
10753   // Key-Value Pair.
10754   //
10755   // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the
10756   // HandleMetadata callback, the raw argument contains UTF-8 strings.
10757   static constexpr uint64_t REPORT_METADATA_KVP = 0x0020;
10758   // Modification Time.
10759   static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040;
10760   // Offset (2-Dimensional).
10761   static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080;
10762   // Physical Dimensions.
10763   static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100;
10764   // Standard Red Green Blue (Rendering Intent).
10765   static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200;
10766   // Extensible Metadata Platform.
10767   static constexpr uint64_t REPORT_METADATA_XMP = 0x0400;
10768 
10769   uint64_t repr;
10770 };
10771 
10772 // DecodeImageArgPixelBlend wraps an optional argument to DecodeImage.
10773 struct DecodeImageArgPixelBlend {
10774   explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0);
10775 
10776   // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC.
10777   static DecodeImageArgPixelBlend DefaultValue();
10778 
10779   wuffs_base__pixel_blend repr;
10780 };
10781 
10782 // DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage.
10783 struct DecodeImageArgBackgroundColor {
10784   explicit DecodeImageArgBackgroundColor(
10785       wuffs_base__color_u32_argb_premul repr0);
10786 
10787   // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul.
10788   static DecodeImageArgBackgroundColor DefaultValue();
10789 
10790   wuffs_base__color_u32_argb_premul repr;
10791 };
10792 
10793 // DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage.
10794 struct DecodeImageArgMaxInclDimension {
10795   explicit DecodeImageArgMaxInclDimension(uint32_t repr0);
10796 
10797   // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels.
10798   static DecodeImageArgMaxInclDimension DefaultValue();
10799 
10800   uint32_t repr;
10801 };
10802 
10803 // DecodeImageArgMaxInclMetadataLength wraps an optional argument to
10804 // DecodeImage.
10805 struct DecodeImageArgMaxInclMetadataLength {
10806   explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0);
10807 
10808   // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB.
10809   static DecodeImageArgMaxInclMetadataLength DefaultValue();
10810 
10811   uint64_t repr;
10812 };
10813 
10814 // DecodeImage decodes the image data in input. A variety of image file formats
10815 // can be decoded, depending on what callbacks.SelectDecoder returns.
10816 //
10817 // For animated formats, only the first frame is returned, since the API is
10818 // simpler for synchronous I/O and having DecodeImage only return when
10819 // completely done, but rendering animation often involves handling other
10820 // events in between animation frames. To decode multiple frames of animated
10821 // images, or for asynchronous I/O (e.g. when decoding an image streamed over
10822 // the network), use Wuffs' lower level C API instead of its higher level,
10823 // simplified C++ API (the wuffs_aux API).
10824 //
10825 // The DecodeImageResult's fields depend on whether decoding succeeded:
10826 //  - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()
10827 //    is true.
10828 //  - On partial success (e.g. the input file was truncated but we are still
10829 //    able to decode some of the pixels), error_message is non-empty but
10830 //    pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to
10831 //    accept or reject partial success.
10832 //  - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()
10833 //    is false.
10834 //
10835 // The callbacks allocate the pixel buffer memory and work buffer memory. On
10836 // success, pixel buffer memory ownership is passed to the DecodeImage caller
10837 // as the returned pixbuf_mem_owner. Regardless of success or failure, the work
10838 // buffer memory is deleted.
10839 //
10840 // The pixel_blend (one of the constants listed below) determines how to
10841 // composite the decoded image over the pixel buffer's original pixels (as
10842 // returned by callbacks.AllocPixbuf):
10843 //  - WUFFS_BASE__PIXEL_BLEND__SRC
10844 //  - WUFFS_BASE__PIXEL_BLEND__SRC_OVER
10845 //
10846 // The background_color is used to fill the pixel buffer after
10847 // callbacks.AllocPixbuf returns, if it is valid in the
10848 // wuffs_base__color_u32_argb_premul__is_valid sense. The default value,
10849 // 0x0000_0001, is not valid since its Blue channel value (0x01) is greater
10850 // than its Alpha channel value (0x00). A valid background_color will typically
10851 // be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might
10852 // still be visible on partial (not total) success or when pixel_blend is
10853 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.
10854 //
10855 // Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's
10856 // width or height is greater than max_incl_dimension or if any opted-in (via
10857 // flags bits) metadata is longer than max_incl_metadata_length.
10858 DecodeImageResult  //
10859 DecodeImage(DecodeImageCallbacks& callbacks,
10860             sync_io::Input& input,
10861             DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(),
10862             DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(),
10863             DecodeImageArgPixelBlend pixel_blend =
10864                 DecodeImageArgPixelBlend::DefaultValue(),
10865             DecodeImageArgBackgroundColor background_color =
10866                 DecodeImageArgBackgroundColor::DefaultValue(),
10867             DecodeImageArgMaxInclDimension max_incl_dimension =
10868                 DecodeImageArgMaxInclDimension::DefaultValue(),
10869             DecodeImageArgMaxInclMetadataLength max_incl_metadata_length =
10870                 DecodeImageArgMaxInclMetadataLength::DefaultValue());
10871 
10872 }  // namespace wuffs_aux
10873 
10874 // ---------------- Auxiliary - JSON
10875 
10876 namespace wuffs_aux {
10877 
10878 struct DecodeJsonResult {
10879   DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0);
10880 
10881   std::string error_message;
10882   uint64_t cursor_position;
10883 };
10884 
10885 class DecodeJsonCallbacks {
10886  public:
10887   virtual ~DecodeJsonCallbacks();
10888 
10889   // AppendXxx are called for leaf nodes: literals, numbers and strings. For
10890   // strings, the Callbacks implementation is responsible for tracking map keys
10891   // versus other values.
10892 
10893   virtual std::string AppendNull() = 0;
10894   virtual std::string AppendBool(bool val) = 0;
10895   virtual std::string AppendF64(double val) = 0;
10896   virtual std::string AppendI64(int64_t val) = 0;
10897   virtual std::string AppendTextString(std::string&& val) = 0;
10898 
10899   // Push and Pop are called for container nodes: JSON arrays (lists) and JSON
10900   // objects (dictionaries).
10901   //
10902   // The flags bits combine exactly one of:
10903   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
10904   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
10905   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
10906   // and exactly one of:
10907   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
10908   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
10909   //  - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
10910 
10911   virtual std::string Push(uint32_t flags) = 0;
10912   virtual std::string Pop(uint32_t flags) = 0;
10913 
10914   // Done is always the last Callback method called by DecodeJson, whether or
10915   // not parsing the input as JSON encountered an error. Even when successful,
10916   // trailing data may remain in input and buffer. See "Unintuitive JSON
10917   // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON
10918   // parsing and when it stops.
10919   //
10920   // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10921   // as DecodeJson may then de-allocate the backing array.
10922   //
10923   // The default Done implementation is a no-op.
10924   virtual void  //
10925   Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer);
10926 };
10927 
10928 extern const char DecodeJson_BadJsonPointer[];
10929 extern const char DecodeJson_NoMatch[];
10930 
10931 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10932 // inner representations for several reasons:
10933 //  - It provides a home for the DefaultValue static method, for Foo callers
10934 //    that want to override some but not all optional arguments.
10935 //  - It provides the "Bar" name at Foo call sites, which can help self-
10936 //    document Foo calls with many arguemnts.
10937 //  - It provides some type safety against accidentally transposing or omitting
10938 //    adjacent fundamentally-numeric-typed optional arguments.
10939 
10940 // DecodeJsonArgQuirks wraps an optional argument to DecodeJson.
10941 struct DecodeJsonArgQuirks {
10942   explicit DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0);
10943   explicit DecodeJsonArgQuirks(uint32_t* ptr, size_t len);
10944 
10945   // DefaultValue returns an empty slice.
10946   static DecodeJsonArgQuirks DefaultValue();
10947 
10948   wuffs_base__slice_u32 repr;
10949 };
10950 
10951 // DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson.
10952 struct DecodeJsonArgJsonPointer {
10953   explicit DecodeJsonArgJsonPointer(std::string repr0);
10954 
10955   // DefaultValue returns an empty string.
10956   static DecodeJsonArgJsonPointer DefaultValue();
10957 
10958   std::string repr;
10959 };
10960 
10961 // DecodeJson calls callbacks based on the JSON-formatted data in input.
10962 //
10963 // On success, the returned error_message is empty and cursor_position counts
10964 // the number of bytes consumed. On failure, error_message is non-empty and
10965 // cursor_position is the location of the error. That error may be a content
10966 // error (invalid JSON) or an input error (e.g. network failure).
10967 //
10968 // json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks
10969 // run for the input's sub-node that matches the query. DecodeJson_NoMatch is
10970 // returned if no matching sub-node was found. The empty query matches the
10971 // input's root node, consistent with JSON Pointer semantics.
10972 //
10973 // The JSON Pointer implementation is greedy: duplicate keys are not rejected
10974 // but only the first match for each '/'-separated fragment is followed.
10975 DecodeJsonResult  //
10976 DecodeJson(DecodeJsonCallbacks& callbacks,
10977            sync_io::Input& input,
10978            DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(),
10979            DecodeJsonArgJsonPointer json_pointer =
10980                DecodeJsonArgJsonPointer::DefaultValue());
10981 
10982 }  // namespace wuffs_aux
10983 
10984 #endif  // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10985 
10986 // ‼ WUFFS C HEADER ENDS HERE.
10987 #ifdef WUFFS_IMPLEMENTATION
10988 
10989 #ifdef __cplusplus
10990 extern "C" {
10991 #endif
10992 
10993 // ---------------- Fundamentals
10994 
10995 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
10996 // It's not foolproof, given C doesn't automatically zero memory before use,
10997 // but it should catch 99.99% of cases.
10998 //
10999 // Its (non-zero) value is arbitrary, based on md5sum("wuffs").
11000 #define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
11001 
11002 // WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
11003 // error was previously encountered.
11004 //
11005 // Its (non-zero) value is arbitrary, based on md5sum("disabled").
11006 #define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
11007 
11008 // Use switch cases for coroutine suspension points, similar to the technique
11009 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
11010 //
11011 // The implicit fallthrough is intentional.
11012 //
11013 // We use trivial macros instead of an explicit assignment and case statement
11014 // so that clang-format doesn't get confused by the unusual "case"s.
11015 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
11016 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
11017   coro_susp_point = n;                            \
11018   case n:;
11019 
11020 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
11021   if (!status.repr) {                                           \
11022     goto ok;                                                    \
11023   } else if (*status.repr != '$') {                             \
11024     goto exit;                                                  \
11025   }                                                             \
11026   coro_susp_point = n;                                          \
11027   goto suspend;                                                 \
11028   case n:;
11029 
11030 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
11031 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
11032 #if defined(__GNUC__) || defined(__clang__)
11033 #define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
11034 #define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
11035 #else
11036 #define WUFFS_BASE__LIKELY(expr) (expr)
11037 #define WUFFS_BASE__UNLIKELY(expr) (expr)
11038 #endif
11039 
11040 // --------
11041 
11042 static inline wuffs_base__empty_struct  //
wuffs_base__ignore_status(wuffs_base__status z)11043 wuffs_base__ignore_status(wuffs_base__status z) {
11044   return wuffs_base__make_empty_struct();
11045 }
11046 
11047 static inline wuffs_base__status  //
wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z)11048 wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
11049   if (z.repr && (*z.repr == '$')) {
11050     z.repr = wuffs_base__error__cannot_return_a_suspension;
11051   }
11052   return z;
11053 }
11054 
11055 // --------
11056 
11057 // wuffs_base__iterate_total_advance returns the exclusive pointer-offset at
11058 // which iteration should stop. The overall slice has length total_len, each
11059 // iteration's sub-slice has length iter_len and are placed iter_advance apart.
11060 //
11061 // The iter_advance may not be larger than iter_len. The iter_advance may be
11062 // smaller than iter_len, in which case the sub-slices will overlap.
11063 //
11064 // The return value r satisfies ((0 <= r) && (r <= total_len)).
11065 //
11066 // For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are
11067 // four iterations at offsets 0, 3, 6 and 9. This function returns 12.
11068 //
11069 // 0123456789012345
11070 // [....]
11071 //    [....]
11072 //       [....]
11073 //          [....]
11074 //             $
11075 // 0123456789012345
11076 //
11077 // For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are
11078 // three iterations at offsets 0, 5 and 10. This function returns 15.
11079 //
11080 // 0123456789012345
11081 // [....]
11082 //      [....]
11083 //           [....]
11084 //                $
11085 // 0123456789012345
11086 static inline size_t  //
wuffs_base__iterate_total_advance(size_t total_len,size_t iter_len,size_t iter_advance)11087 wuffs_base__iterate_total_advance(size_t total_len,
11088                                   size_t iter_len,
11089                                   size_t iter_advance) {
11090   if (total_len >= iter_len) {
11091     size_t n = total_len - iter_len;
11092     return ((n / iter_advance) * iter_advance) + iter_advance;
11093   }
11094   return 0;
11095 }
11096 
11097 // ---------------- Numeric Types
11098 
11099 extern const uint8_t wuffs_base__low_bits_mask__u8[8];
11100 extern const uint16_t wuffs_base__low_bits_mask__u16[16];
11101 extern const uint32_t wuffs_base__low_bits_mask__u32[32];
11102 extern const uint64_t wuffs_base__low_bits_mask__u64[64];
11103 
11104 #define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
11105 #define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
11106 #define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
11107 #define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
11108 
11109 // --------
11110 
11111 static inline void  //
wuffs_base__u8__sat_add_indirect(uint8_t * x,uint8_t y)11112 wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
11113   *x = wuffs_base__u8__sat_add(*x, y);
11114 }
11115 
11116 static inline void  //
wuffs_base__u8__sat_sub_indirect(uint8_t * x,uint8_t y)11117 wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
11118   *x = wuffs_base__u8__sat_sub(*x, y);
11119 }
11120 
11121 static inline void  //
wuffs_base__u16__sat_add_indirect(uint16_t * x,uint16_t y)11122 wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
11123   *x = wuffs_base__u16__sat_add(*x, y);
11124 }
11125 
11126 static inline void  //
wuffs_base__u16__sat_sub_indirect(uint16_t * x,uint16_t y)11127 wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
11128   *x = wuffs_base__u16__sat_sub(*x, y);
11129 }
11130 
11131 static inline void  //
wuffs_base__u32__sat_add_indirect(uint32_t * x,uint32_t y)11132 wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
11133   *x = wuffs_base__u32__sat_add(*x, y);
11134 }
11135 
11136 static inline void  //
wuffs_base__u32__sat_sub_indirect(uint32_t * x,uint32_t y)11137 wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
11138   *x = wuffs_base__u32__sat_sub(*x, y);
11139 }
11140 
11141 static inline void  //
wuffs_base__u64__sat_add_indirect(uint64_t * x,uint64_t y)11142 wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
11143   *x = wuffs_base__u64__sat_add(*x, y);
11144 }
11145 
11146 static inline void  //
wuffs_base__u64__sat_sub_indirect(uint64_t * x,uint64_t y)11147 wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
11148   *x = wuffs_base__u64__sat_sub(*x, y);
11149 }
11150 
11151 // ---------------- Slices and Tables
11152 
11153 // wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
11154 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s,uint64_t up_to)11155 wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
11156   if (((uint64_t)(s.len)) > up_to) {
11157     s.len = ((size_t)up_to);
11158   }
11159   return s;
11160 }
11161 
11162 // wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
11163 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s,uint64_t up_to)11164 wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
11165   if (((uint64_t)(s.len)) > up_to) {
11166     s.ptr += ((uint64_t)(s.len)) - up_to;
11167     s.len = ((size_t)up_to);
11168   }
11169   return s;
11170 }
11171 
11172 // wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
11173 // where len is the minimum of dst.len and src.len.
11174 //
11175 // Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
11176 // slice) is valid and results in a no-op.
11177 static inline uint64_t  //
wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src)11178 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
11179                                       wuffs_base__slice_u8 src) {
11180   size_t len = dst.len < src.len ? dst.len : src.len;
11181   if (len > 0) {
11182     memmove(dst.ptr, src.ptr, len);
11183   }
11184   return len;
11185 }
11186 
11187 // --------
11188 
11189 static inline wuffs_base__slice_u8  //
wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t,uint32_t y)11190 wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) {
11191   if (y < t.height) {
11192     return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
11193   }
11194   return wuffs_base__make_slice_u8(NULL, 0);
11195 }
11196 
11197 // ---------------- Slices and Tables (Utility)
11198 
11199 #define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
11200 
11201 // ---------------- Ranges and Rects
11202 
11203 static inline uint32_t  //
wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32 * r)11204 wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) {
11205   return r->min_incl;
11206 }
11207 
11208 static inline uint32_t  //
wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32 * r)11209 wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) {
11210   return r->max_incl;
11211 }
11212 
11213 static inline uint32_t  //
wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32 * r)11214 wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) {
11215   return r->min_incl;
11216 }
11217 
11218 static inline uint32_t  //
wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32 * r)11219 wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) {
11220   return r->max_excl;
11221 }
11222 
11223 static inline uint64_t  //
wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64 * r)11224 wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) {
11225   return r->min_incl;
11226 }
11227 
11228 static inline uint64_t  //
wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64 * r)11229 wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) {
11230   return r->max_incl;
11231 }
11232 
11233 static inline uint64_t  //
wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64 * r)11234 wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) {
11235   return r->min_incl;
11236 }
11237 
11238 static inline uint64_t  //
wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64 * r)11239 wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) {
11240   return r->max_excl;
11241 }
11242 
11243 // ---------------- Ranges and Rects (Utility)
11244 
11245 #define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32
11246 #define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32
11247 #define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64
11248 #define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64
11249 #define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32
11250 #define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32
11251 #define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
11252 #define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
11253 #define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
11254 #define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
11255 #define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
11256 #define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
11257 
11258 // ---------------- I/O
11259 
11260 static inline uint64_t  //
wuffs_base__io__count_since(uint64_t mark,uint64_t index)11261 wuffs_base__io__count_since(uint64_t mark, uint64_t index) {
11262   if (index >= mark) {
11263     return index - mark;
11264   }
11265   return 0;
11266 }
11267 
11268 // TODO: drop the "const" in "const uint8_t* ptr". Some though required about
11269 // the base.io_reader.since method returning a mutable "slice base.u8".
11270 #if defined(__GNUC__)
11271 #pragma GCC diagnostic push
11272 #pragma GCC diagnostic ignored "-Wcast-qual"
11273 #endif
11274 static inline wuffs_base__slice_u8  //
wuffs_base__io__since(uint64_t mark,uint64_t index,const uint8_t * ptr)11275 wuffs_base__io__since(uint64_t mark, uint64_t index, const uint8_t* ptr) {
11276   if (index >= mark) {
11277     return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark,
11278                                      ((size_t)(index - mark)));
11279   }
11280   return wuffs_base__make_slice_u8(NULL, 0);
11281 }
11282 #if defined(__GNUC__)
11283 #pragma GCC diagnostic pop
11284 #endif
11285 
11286 // --------
11287 
11288 static inline void  //
wuffs_base__io_reader__limit(const uint8_t ** ptr_io2_r,const uint8_t * iop_r,uint64_t limit)11289 wuffs_base__io_reader__limit(const uint8_t** ptr_io2_r,
11290                              const uint8_t* iop_r,
11291                              uint64_t limit) {
11292   if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) {
11293     *ptr_io2_r = iop_r + limit;
11294   }
11295 }
11296 
11297 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)11298 wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r,
11299                                                  const uint8_t* io2_r,
11300                                                  uint32_t length,
11301                                                  wuffs_base__slice_u8 dst) {
11302   const uint8_t* iop_r = *ptr_iop_r;
11303   size_t n = dst.len;
11304   if (n > length) {
11305     n = length;
11306   }
11307   if (n > ((size_t)(io2_r - iop_r))) {
11308     n = (size_t)(io2_r - iop_r);
11309   }
11310   if (n > 0) {
11311     memmove(dst.ptr, iop_r, n);
11312     *ptr_iop_r += n;
11313   }
11314   return (uint32_t)(n);
11315 }
11316 
11317 // wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes
11318 // start with the given prefix (up to 7 bytes long). It is peek-like, not
11319 // read-like, in that there are no side-effects.
11320 //
11321 // The low 3 bits of a hold the prefix length, n.
11322 //
11323 // The high 56 bits of a hold the prefix itself, in little-endian order. The
11324 // first prefix byte is in bits 8..=15, the second prefix byte is in bits
11325 // 16..=23, etc. The high (8 * (7 - n)) bits are ignored.
11326 //
11327 // There are three possible return values:
11328 //  - 0 means success.
11329 //  - 1 means inconclusive, equivalent to "$short read".
11330 //  - 2 means failure.
11331 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)11332 wuffs_base__io_reader__match7(const uint8_t* iop_r,
11333                               const uint8_t* io2_r,
11334                               wuffs_base__io_buffer* r,
11335                               uint64_t a) {
11336   uint32_t n = a & 7;
11337   a >>= 8;
11338   if ((io2_r - iop_r) >= 8) {
11339     uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r);
11340     uint32_t shift = 8 * (8 - n);
11341     return ((a << shift) == (x << shift)) ? 0 : 2;
11342   }
11343   for (; n > 0; n--) {
11344     if (iop_r >= io2_r) {
11345       return (r && r->meta.closed) ? 2 : 1;
11346     } else if (*iop_r != ((uint8_t)(a))) {
11347       return 2;
11348     }
11349     iop_r++;
11350     a >>= 8;
11351   }
11352   return 0;
11353 }
11354 
11355 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)11356 wuffs_base__io_reader__set(wuffs_base__io_buffer* b,
11357                            const uint8_t** ptr_iop_r,
11358                            const uint8_t** ptr_io0_r,
11359                            const uint8_t** ptr_io1_r,
11360                            const uint8_t** ptr_io2_r,
11361                            wuffs_base__slice_u8 data,
11362                            uint64_t history_position) {
11363   b->data = data;
11364   b->meta.wi = data.len;
11365   b->meta.ri = 0;
11366   b->meta.pos = history_position;
11367   b->meta.closed = false;
11368 
11369   *ptr_iop_r = data.ptr;
11370   *ptr_io0_r = data.ptr;
11371   *ptr_io1_r = data.ptr;
11372   *ptr_io2_r = data.ptr + data.len;
11373 
11374   return b;
11375 }
11376 
11377 // --------
11378 
11379 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)11380 wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
11381                                        uint8_t* io2_w,
11382                                        wuffs_base__slice_u8 src) {
11383   uint8_t* iop_w = *ptr_iop_w;
11384   size_t n = src.len;
11385   if (n > ((size_t)(io2_w - iop_w))) {
11386     n = (size_t)(io2_w - iop_w);
11387   }
11388   if (n > 0) {
11389     memmove(iop_w, src.ptr, n);
11390     *ptr_iop_w += n;
11391   }
11392   return (uint64_t)(n);
11393 }
11394 
11395 static inline void  //
wuffs_base__io_writer__limit(uint8_t ** ptr_io2_w,uint8_t * iop_w,uint64_t limit)11396 wuffs_base__io_writer__limit(uint8_t** ptr_io2_w,
11397                              uint8_t* iop_w,
11398                              uint64_t limit) {
11399   if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) {
11400     *ptr_io2_w = iop_w + limit;
11401   }
11402 }
11403 
11404 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11405 wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w,
11406                                                      uint8_t* io0_w,
11407                                                      uint8_t* io2_w,
11408                                                      uint32_t length,
11409                                                      uint32_t distance) {
11410   if (!distance) {
11411     return 0;
11412   }
11413   uint8_t* p = *ptr_iop_w;
11414   if ((size_t)(p - io0_w) < (size_t)(distance)) {
11415     return 0;
11416   }
11417   uint8_t* q = p - distance;
11418   size_t n = (size_t)(io2_w - p);
11419   if ((size_t)(length) > n) {
11420     length = (uint32_t)(n);
11421   } else {
11422     n = (size_t)(length);
11423   }
11424   // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
11425   // is mostly because 3 is the minimum length for the deflate format. This
11426   // function implementation shouldn't overfit to that one format. Perhaps the
11427   // limited_copy_u32_from_history Wuffs method should also take an unroll hint
11428   // argument, and the cgen can look if that argument is the constant
11429   // expression '3'.
11430   //
11431   // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below.
11432   for (; n >= 3; n -= 3) {
11433     *p++ = *q++;
11434     *p++ = *q++;
11435     *p++ = *q++;
11436   }
11437   for (; n; n--) {
11438     *p++ = *q++;
11439   }
11440   *ptr_iop_w = p;
11441   return length;
11442 }
11443 
11444 // wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the
11445 // wuffs_base__io_writer__limited_copy_u32_from_history function above, but has
11446 // stronger pre-conditions.
11447 //
11448 // The caller needs to prove that:
11449 //  - length   <= (io2_w      - *ptr_iop_w)
11450 //  - distance >= 1
11451 //  - distance <= (*ptr_iop_w - io0_w)
11452 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11453 wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t** ptr_iop_w,
11454                                                           uint8_t* io0_w,
11455                                                           uint8_t* io2_w,
11456                                                           uint32_t length,
11457                                                           uint32_t distance) {
11458   uint8_t* p = *ptr_iop_w;
11459   uint8_t* q = p - distance;
11460   uint32_t n = length;
11461   for (; n >= 3; n -= 3) {
11462     *p++ = *q++;
11463     *p++ = *q++;
11464     *p++ = *q++;
11465   }
11466   for (; n; n--) {
11467     *p++ = *q++;
11468   }
11469   *ptr_iop_w = p;
11470   return length;
11471 }
11472 
11473 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast
11474 // copies the previous byte (the one immediately before *ptr_iop_w), copying 8
11475 // byte chunks at a time. Each chunk contains 8 repetitions of the same byte.
11476 //
11477 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
11478 // As a special case, a zero length rounds up to 8 (even though 0 is already a
11479 // multiple of 8), since there is always at least one 8 byte chunk copied.
11480 //
11481 // In terms of advancing *ptr_iop_w, length is not rounded up.
11482 //
11483 // The caller needs to prove that:
11484 //  - (length + 8) <= (io2_w      - *ptr_iop_w)
11485 //  - distance     == 1
11486 //  - distance     <= (*ptr_iop_w - io0_w)
11487 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11488 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
11489     uint8_t** ptr_iop_w,
11490     uint8_t* io0_w,
11491     uint8_t* io2_w,
11492     uint32_t length,
11493     uint32_t distance) {
11494   uint8_t* p = *ptr_iop_w;
11495   uint64_t x = p[-1];
11496   x |= x << 8;
11497   x |= x << 16;
11498   x |= x << 32;
11499   uint32_t n = length;
11500   while (1) {
11501     wuffs_base__poke_u64le__no_bounds_check(p, x);
11502     if (n <= 8) {
11503       p += n;
11504       break;
11505     }
11506     p += 8;
11507     n -= 8;
11508   }
11509   *ptr_iop_w = p;
11510   return length;
11511 }
11512 
11513 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast is
11514 // like the wuffs_base__io_writer__limited_copy_u32_from_history_fast function
11515 // above, but copies 8 byte chunks at a time.
11516 //
11517 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
11518 // As a special case, a zero length rounds up to 8 (even though 0 is already a
11519 // multiple of 8), since there is always at least one 8 byte chunk copied.
11520 //
11521 // In terms of advancing *ptr_iop_w, length is not rounded up.
11522 //
11523 // The caller needs to prove that:
11524 //  - (length + 8) <= (io2_w      - *ptr_iop_w)
11525 //  - distance     >= 8
11526 //  - distance     <= (*ptr_iop_w - io0_w)
11527 static inline uint32_t  //
wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11528 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
11529     uint8_t** ptr_iop_w,
11530     uint8_t* io0_w,
11531     uint8_t* io2_w,
11532     uint32_t length,
11533     uint32_t distance) {
11534   uint8_t* p = *ptr_iop_w;
11535   uint8_t* q = p - distance;
11536   uint32_t n = length;
11537   while (1) {
11538     memcpy(p, q, 8);
11539     if (n <= 8) {
11540       p += n;
11541       break;
11542     }
11543     p += 8;
11544     q += 8;
11545     n -= 8;
11546   }
11547   *ptr_iop_w = p;
11548   return length;
11549 }
11550 
11551 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)11552 wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t** ptr_iop_w,
11553                                                     uint8_t* io2_w,
11554                                                     uint32_t length,
11555                                                     const uint8_t** ptr_iop_r,
11556                                                     const uint8_t* io2_r) {
11557   uint8_t* iop_w = *ptr_iop_w;
11558   size_t n = length;
11559   if (n > ((size_t)(io2_w - iop_w))) {
11560     n = (size_t)(io2_w - iop_w);
11561   }
11562   const uint8_t* iop_r = *ptr_iop_r;
11563   if (n > ((size_t)(io2_r - iop_r))) {
11564     n = (size_t)(io2_r - iop_r);
11565   }
11566   if (n > 0) {
11567     memmove(iop_w, iop_r, n);
11568     *ptr_iop_w += n;
11569     *ptr_iop_r += n;
11570   }
11571   return (uint32_t)(n);
11572 }
11573 
11574 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)11575 wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t** ptr_iop_w,
11576                                                    uint8_t* io2_w,
11577                                                    uint32_t length,
11578                                                    wuffs_base__slice_u8 src) {
11579   uint8_t* iop_w = *ptr_iop_w;
11580   size_t n = src.len;
11581   if (n > length) {
11582     n = length;
11583   }
11584   if (n > ((size_t)(io2_w - iop_w))) {
11585     n = (size_t)(io2_w - iop_w);
11586   }
11587   if (n > 0) {
11588     memmove(iop_w, src.ptr, n);
11589     *ptr_iop_w += n;
11590   }
11591   return (uint32_t)(n);
11592 }
11593 
11594 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)11595 wuffs_base__io_writer__set(wuffs_base__io_buffer* b,
11596                            uint8_t** ptr_iop_w,
11597                            uint8_t** ptr_io0_w,
11598                            uint8_t** ptr_io1_w,
11599                            uint8_t** ptr_io2_w,
11600                            wuffs_base__slice_u8 data,
11601                            uint64_t history_position) {
11602   b->data = data;
11603   b->meta.wi = 0;
11604   b->meta.ri = 0;
11605   b->meta.pos = history_position;
11606   b->meta.closed = false;
11607 
11608   *ptr_iop_w = data.ptr;
11609   *ptr_io0_w = data.ptr;
11610   *ptr_io1_w = data.ptr;
11611   *ptr_io2_w = data.ptr + data.len;
11612 
11613   return b;
11614 }
11615 
11616 // ---------------- I/O (Utility)
11617 
11618 #define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader
11619 #define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer
11620 
11621 // ---------------- Tokens
11622 
11623 // ---------------- Tokens (Utility)
11624 
11625 // ---------------- Memory Allocation
11626 
11627 // ---------------- Images
11628 
11629 WUFFS_BASE__MAYBE_STATIC uint64_t  //
11630 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
11631     const wuffs_base__pixel_swizzler* p,
11632     uint32_t up_to_num_pixels,
11633     wuffs_base__slice_u8 dst,
11634     wuffs_base__slice_u8 dst_palette,
11635     const uint8_t** ptr_iop_r,
11636     const uint8_t* io2_r);
11637 
11638 WUFFS_BASE__MAYBE_STATIC uint64_t  //
11639 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
11640     const wuffs_base__pixel_swizzler* p,
11641     wuffs_base__slice_u8 dst,
11642     wuffs_base__slice_u8 dst_palette,
11643     const uint8_t** ptr_iop_r,
11644     const uint8_t* io2_r);
11645 
11646 WUFFS_BASE__MAYBE_STATIC uint64_t  //
11647 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
11648     const wuffs_base__pixel_swizzler* p,
11649     wuffs_base__slice_u8 dst,
11650     wuffs_base__slice_u8 dst_palette,
11651     uint64_t num_pixels);
11652 
11653 // ---------------- Images (Utility)
11654 
11655 #define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format
11656 
11657 // ---------------- String Conversions
11658 
11659 // ---------------- Unicode and UTF-8
11660 
11661 // ----------------
11662 
11663 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
11664     defined(WUFFS_CONFIG__MODULE__BASE__CORE)
11665 
11666 const uint8_t wuffs_base__low_bits_mask__u8[8] = {
11667     0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F,
11668 };
11669 
11670 const uint16_t wuffs_base__low_bits_mask__u16[16] = {
11671     0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F,
11672     0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
11673 };
11674 
11675 const uint32_t wuffs_base__low_bits_mask__u32[32] = {
11676     0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
11677     0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
11678     0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
11679     0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
11680     0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
11681     0x3FFFFFFF, 0x7FFFFFFF,
11682 };
11683 
11684 const uint64_t wuffs_base__low_bits_mask__u64[64] = {
11685     0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
11686     0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
11687     0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
11688     0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
11689     0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
11690     0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
11691     0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
11692     0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
11693     0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
11694     0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
11695     0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
11696     0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
11697     0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
11698     0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
11699     0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
11700     0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
11701     0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
11702     0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
11703     0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
11704     0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
11705     0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
11706     0x7FFFFFFFFFFFFFFF,
11707 };
11708 
11709 const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
11710     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
11711     0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
11712 };
11713 
11714 const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect";
11715 const char wuffs_base__note__end_of_data[] = "@base: end of data";
11716 const char wuffs_base__note__metadata_reported[] = "@base: metadata reported";
11717 const char wuffs_base__suspension__even_more_information[] = "$base: even more information";
11718 const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read";
11719 const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write";
11720 const char wuffs_base__suspension__short_read[] = "$base: short read";
11721 const char wuffs_base__suspension__short_write[] = "$base: short write";
11722 const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position";
11723 const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)";
11724 const char wuffs_base__error__bad_argument[] = "#base: bad argument";
11725 const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence";
11726 const char wuffs_base__error__bad_data[] = "#base: bad data";
11727 const char wuffs_base__error__bad_receiver[] = "#base: bad receiver";
11728 const char wuffs_base__error__bad_restart[] = "#base: bad restart";
11729 const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver";
11730 const char wuffs_base__error__bad_vtable[] = "#base: bad vtable";
11731 const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length";
11732 const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version";
11733 const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension";
11734 const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error";
11735 const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed";
11736 const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called";
11737 const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls";
11738 const char wuffs_base__error__no_more_information[] = "#base: no more information";
11739 const char wuffs_base__error__not_enough_data[] = "#base: not enough data";
11740 const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds";
11741 const char wuffs_base__error__unsupported_method[] = "#base: unsupported method";
11742 const char wuffs_base__error__unsupported_option[] = "#base: unsupported option";
11743 const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option";
11744 const char wuffs_base__error__too_much_data[] = "#base: too much data";
11745 
11746 const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32";
11747 const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder";
11748 const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer";
11749 const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder";
11750 
11751 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
11752         // defined(WUFFS_CONFIG__MODULE__BASE)  ||
11753         // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
11754 
11755 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
11756     defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
11757 
11758 // ---------------- Interface Definitions.
11759 
11760 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)11761 wuffs_base__hasher_u32__set_quirk_enabled(
11762     wuffs_base__hasher_u32* self,
11763     uint32_t a_quirk,
11764     bool a_enabled) {
11765   if (!self) {
11766     return wuffs_base__make_empty_struct();
11767   }
11768   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11769     return wuffs_base__make_empty_struct();
11770   }
11771 
11772   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11773   int i;
11774   for (i = 0; i < 63; i++) {
11775     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
11776       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
11777           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
11778       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
11779     } else if (v->vtable_name == NULL) {
11780       break;
11781     }
11782     v++;
11783   }
11784 
11785   return wuffs_base__make_empty_struct();
11786 }
11787 
11788 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__hasher_u32__update_u32(wuffs_base__hasher_u32 * self,wuffs_base__slice_u8 a_x)11789 wuffs_base__hasher_u32__update_u32(
11790     wuffs_base__hasher_u32* self,
11791     wuffs_base__slice_u8 a_x) {
11792   if (!self) {
11793     return 0;
11794   }
11795   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11796     return 0;
11797   }
11798 
11799   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11800   int i;
11801   for (i = 0; i < 63; i++) {
11802     if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
11803       const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
11804           (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
11805       return (*func_ptrs->update_u32)(self, a_x);
11806     } else if (v->vtable_name == NULL) {
11807       break;
11808     }
11809     v++;
11810   }
11811 
11812   return 0;
11813 }
11814 
11815 // --------
11816 
11817 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)11818 wuffs_base__image_decoder__decode_frame(
11819     wuffs_base__image_decoder* self,
11820     wuffs_base__pixel_buffer* a_dst,
11821     wuffs_base__io_buffer* a_src,
11822     wuffs_base__pixel_blend a_blend,
11823     wuffs_base__slice_u8 a_workbuf,
11824     wuffs_base__decode_frame_options* a_opts) {
11825   if (!self) {
11826     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11827   }
11828   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11829     return wuffs_base__make_status(
11830         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11831             ? wuffs_base__error__disabled_by_previous_error
11832             : wuffs_base__error__initialize_not_called);
11833   }
11834 
11835   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11836   int i;
11837   for (i = 0; i < 63; i++) {
11838     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11839       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11840           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11841       return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts);
11842     } else if (v->vtable_name == NULL) {
11843       break;
11844     }
11845     v++;
11846   }
11847 
11848   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11849 }
11850 
11851 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)11852 wuffs_base__image_decoder__decode_frame_config(
11853     wuffs_base__image_decoder* self,
11854     wuffs_base__frame_config* a_dst,
11855     wuffs_base__io_buffer* a_src) {
11856   if (!self) {
11857     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11858   }
11859   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11860     return wuffs_base__make_status(
11861         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11862             ? wuffs_base__error__disabled_by_previous_error
11863             : wuffs_base__error__initialize_not_called);
11864   }
11865 
11866   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11867   int i;
11868   for (i = 0; i < 63; i++) {
11869     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11870       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11871           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11872       return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
11873     } else if (v->vtable_name == NULL) {
11874       break;
11875     }
11876     v++;
11877   }
11878 
11879   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11880 }
11881 
11882 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)11883 wuffs_base__image_decoder__decode_image_config(
11884     wuffs_base__image_decoder* self,
11885     wuffs_base__image_config* a_dst,
11886     wuffs_base__io_buffer* a_src) {
11887   if (!self) {
11888     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11889   }
11890   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11891     return wuffs_base__make_status(
11892         (self->private_impl.magic == WUFFS_BASE__DISABLED)
11893             ? wuffs_base__error__disabled_by_previous_error
11894             : wuffs_base__error__initialize_not_called);
11895   }
11896 
11897   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11898   int i;
11899   for (i = 0; i < 63; i++) {
11900     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11901       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11902           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11903       return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
11904     } else if (v->vtable_name == NULL) {
11905       break;
11906     }
11907     v++;
11908   }
11909 
11910   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11911 }
11912 
11913 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_base__image_decoder__frame_dirty_rect(const wuffs_base__image_decoder * self)11914 wuffs_base__image_decoder__frame_dirty_rect(
11915     const wuffs_base__image_decoder* self) {
11916   if (!self) {
11917     return wuffs_base__utility__empty_rect_ie_u32();
11918   }
11919   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11920       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11921     return wuffs_base__utility__empty_rect_ie_u32();
11922   }
11923 
11924   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11925   int i;
11926   for (i = 0; i < 63; i++) {
11927     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11928       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11929           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11930       return (*func_ptrs->frame_dirty_rect)(self);
11931     } else if (v->vtable_name == NULL) {
11932       break;
11933     }
11934     v++;
11935   }
11936 
11937   return wuffs_base__utility__empty_rect_ie_u32();
11938 }
11939 
11940 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__image_decoder__num_animation_loops(const wuffs_base__image_decoder * self)11941 wuffs_base__image_decoder__num_animation_loops(
11942     const wuffs_base__image_decoder* self) {
11943   if (!self) {
11944     return 0;
11945   }
11946   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11947       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11948     return 0;
11949   }
11950 
11951   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11952   int i;
11953   for (i = 0; i < 63; i++) {
11954     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11955       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11956           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11957       return (*func_ptrs->num_animation_loops)(self);
11958     } else if (v->vtable_name == NULL) {
11959       break;
11960     }
11961     v++;
11962   }
11963 
11964   return 0;
11965 }
11966 
11967 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frame_configs(const wuffs_base__image_decoder * self)11968 wuffs_base__image_decoder__num_decoded_frame_configs(
11969     const wuffs_base__image_decoder* self) {
11970   if (!self) {
11971     return 0;
11972   }
11973   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11974       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11975     return 0;
11976   }
11977 
11978   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11979   int i;
11980   for (i = 0; i < 63; i++) {
11981     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11982       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11983           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11984       return (*func_ptrs->num_decoded_frame_configs)(self);
11985     } else if (v->vtable_name == NULL) {
11986       break;
11987     }
11988     v++;
11989   }
11990 
11991   return 0;
11992 }
11993 
11994 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frames(const wuffs_base__image_decoder * self)11995 wuffs_base__image_decoder__num_decoded_frames(
11996     const wuffs_base__image_decoder* self) {
11997   if (!self) {
11998     return 0;
11999   }
12000   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12001       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12002     return 0;
12003   }
12004 
12005   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12006   int i;
12007   for (i = 0; i < 63; i++) {
12008     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12009       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12010           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12011       return (*func_ptrs->num_decoded_frames)(self);
12012     } else if (v->vtable_name == NULL) {
12013       break;
12014     }
12015     v++;
12016   }
12017 
12018   return 0;
12019 }
12020 
12021 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)12022 wuffs_base__image_decoder__restart_frame(
12023     wuffs_base__image_decoder* self,
12024     uint64_t a_index,
12025     uint64_t a_io_position) {
12026   if (!self) {
12027     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12028   }
12029   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12030     return wuffs_base__make_status(
12031         (self->private_impl.magic == WUFFS_BASE__DISABLED)
12032             ? wuffs_base__error__disabled_by_previous_error
12033             : wuffs_base__error__initialize_not_called);
12034   }
12035 
12036   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12037   int i;
12038   for (i = 0; i < 63; i++) {
12039     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12040       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12041           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12042       return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
12043     } else if (v->vtable_name == NULL) {
12044       break;
12045     }
12046     v++;
12047   }
12048 
12049   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12050 }
12051 
12052 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)12053 wuffs_base__image_decoder__set_quirk_enabled(
12054     wuffs_base__image_decoder* self,
12055     uint32_t a_quirk,
12056     bool a_enabled) {
12057   if (!self) {
12058     return wuffs_base__make_empty_struct();
12059   }
12060   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12061     return wuffs_base__make_empty_struct();
12062   }
12063 
12064   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12065   int i;
12066   for (i = 0; i < 63; i++) {
12067     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12068       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12069           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12070       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
12071     } else if (v->vtable_name == NULL) {
12072       break;
12073     }
12074     v++;
12075   }
12076 
12077   return wuffs_base__make_empty_struct();
12078 }
12079 
12080 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)12081 wuffs_base__image_decoder__set_report_metadata(
12082     wuffs_base__image_decoder* self,
12083     uint32_t a_fourcc,
12084     bool a_report) {
12085   if (!self) {
12086     return wuffs_base__make_empty_struct();
12087   }
12088   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12089     return wuffs_base__make_empty_struct();
12090   }
12091 
12092   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12093   int i;
12094   for (i = 0; i < 63; i++) {
12095     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12096       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12097           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12098       return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
12099     } else if (v->vtable_name == NULL) {
12100       break;
12101     }
12102     v++;
12103   }
12104 
12105   return wuffs_base__make_empty_struct();
12106 }
12107 
12108 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)12109 wuffs_base__image_decoder__tell_me_more(
12110     wuffs_base__image_decoder* self,
12111     wuffs_base__io_buffer* a_dst,
12112     wuffs_base__more_information* a_minfo,
12113     wuffs_base__io_buffer* a_src) {
12114   if (!self) {
12115     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12116   }
12117   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12118     return wuffs_base__make_status(
12119         (self->private_impl.magic == WUFFS_BASE__DISABLED)
12120             ? wuffs_base__error__disabled_by_previous_error
12121             : wuffs_base__error__initialize_not_called);
12122   }
12123 
12124   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12125   int i;
12126   for (i = 0; i < 63; i++) {
12127     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12128       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12129           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12130       return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
12131     } else if (v->vtable_name == NULL) {
12132       break;
12133     }
12134     v++;
12135   }
12136 
12137   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12138 }
12139 
12140 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__image_decoder__workbuf_len(const wuffs_base__image_decoder * self)12141 wuffs_base__image_decoder__workbuf_len(
12142     const wuffs_base__image_decoder* self) {
12143   if (!self) {
12144     return wuffs_base__utility__empty_range_ii_u64();
12145   }
12146   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12147       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12148     return wuffs_base__utility__empty_range_ii_u64();
12149   }
12150 
12151   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12152   int i;
12153   for (i = 0; i < 63; i++) {
12154     if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12155       const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12156           (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12157       return (*func_ptrs->workbuf_len)(self);
12158     } else if (v->vtable_name == NULL) {
12159       break;
12160     }
12161     v++;
12162   }
12163 
12164   return wuffs_base__utility__empty_range_ii_u64();
12165 }
12166 
12167 // --------
12168 
12169 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)12170 wuffs_base__io_transformer__set_quirk_enabled(
12171     wuffs_base__io_transformer* self,
12172     uint32_t a_quirk,
12173     bool a_enabled) {
12174   if (!self) {
12175     return wuffs_base__make_empty_struct();
12176   }
12177   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12178     return wuffs_base__make_empty_struct();
12179   }
12180 
12181   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12182   int i;
12183   for (i = 0; i < 63; i++) {
12184     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
12185       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
12186           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
12187       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
12188     } else if (v->vtable_name == NULL) {
12189       break;
12190     }
12191     v++;
12192   }
12193 
12194   return wuffs_base__make_empty_struct();
12195 }
12196 
12197 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)12198 wuffs_base__io_transformer__transform_io(
12199     wuffs_base__io_transformer* self,
12200     wuffs_base__io_buffer* a_dst,
12201     wuffs_base__io_buffer* a_src,
12202     wuffs_base__slice_u8 a_workbuf) {
12203   if (!self) {
12204     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12205   }
12206   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12207     return wuffs_base__make_status(
12208         (self->private_impl.magic == WUFFS_BASE__DISABLED)
12209             ? wuffs_base__error__disabled_by_previous_error
12210             : wuffs_base__error__initialize_not_called);
12211   }
12212 
12213   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12214   int i;
12215   for (i = 0; i < 63; i++) {
12216     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
12217       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
12218           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
12219       return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
12220     } else if (v->vtable_name == NULL) {
12221       break;
12222     }
12223     v++;
12224   }
12225 
12226   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12227 }
12228 
12229 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__io_transformer__workbuf_len(const wuffs_base__io_transformer * self)12230 wuffs_base__io_transformer__workbuf_len(
12231     const wuffs_base__io_transformer* self) {
12232   if (!self) {
12233     return wuffs_base__utility__empty_range_ii_u64();
12234   }
12235   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12236       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12237     return wuffs_base__utility__empty_range_ii_u64();
12238   }
12239 
12240   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12241   int i;
12242   for (i = 0; i < 63; i++) {
12243     if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
12244       const wuffs_base__io_transformer__func_ptrs* func_ptrs =
12245           (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
12246       return (*func_ptrs->workbuf_len)(self);
12247     } else if (v->vtable_name == NULL) {
12248       break;
12249     }
12250     v++;
12251   }
12252 
12253   return wuffs_base__utility__empty_range_ii_u64();
12254 }
12255 
12256 // --------
12257 
12258 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)12259 wuffs_base__token_decoder__decode_tokens(
12260     wuffs_base__token_decoder* self,
12261     wuffs_base__token_buffer* a_dst,
12262     wuffs_base__io_buffer* a_src,
12263     wuffs_base__slice_u8 a_workbuf) {
12264   if (!self) {
12265     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12266   }
12267   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12268     return wuffs_base__make_status(
12269         (self->private_impl.magic == WUFFS_BASE__DISABLED)
12270             ? wuffs_base__error__disabled_by_previous_error
12271             : wuffs_base__error__initialize_not_called);
12272   }
12273 
12274   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12275   int i;
12276   for (i = 0; i < 63; i++) {
12277     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
12278       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
12279           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
12280       return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
12281     } else if (v->vtable_name == NULL) {
12282       break;
12283     }
12284     v++;
12285   }
12286 
12287   return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12288 }
12289 
12290 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)12291 wuffs_base__token_decoder__set_quirk_enabled(
12292     wuffs_base__token_decoder* self,
12293     uint32_t a_quirk,
12294     bool a_enabled) {
12295   if (!self) {
12296     return wuffs_base__make_empty_struct();
12297   }
12298   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12299     return wuffs_base__make_empty_struct();
12300   }
12301 
12302   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12303   int i;
12304   for (i = 0; i < 63; i++) {
12305     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
12306       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
12307           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
12308       return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
12309     } else if (v->vtable_name == NULL) {
12310       break;
12311     }
12312     v++;
12313   }
12314 
12315   return wuffs_base__make_empty_struct();
12316 }
12317 
12318 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__token_decoder__workbuf_len(const wuffs_base__token_decoder * self)12319 wuffs_base__token_decoder__workbuf_len(
12320     const wuffs_base__token_decoder* self) {
12321   if (!self) {
12322     return wuffs_base__utility__empty_range_ii_u64();
12323   }
12324   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12325       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12326     return wuffs_base__utility__empty_range_ii_u64();
12327   }
12328 
12329   const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12330   int i;
12331   for (i = 0; i < 63; i++) {
12332     if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
12333       const wuffs_base__token_decoder__func_ptrs* func_ptrs =
12334           (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
12335       return (*func_ptrs->workbuf_len)(self);
12336     } else if (v->vtable_name == NULL) {
12337       break;
12338     }
12339     v++;
12340   }
12341 
12342   return wuffs_base__utility__empty_range_ii_u64();
12343 }
12344 
12345 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
12346         // defined(WUFFS_CONFIG__MODULE__BASE) ||
12347         // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
12348 
12349 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
12350     defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
12351 
12352 // ---------------- IEEE 754 Floating Point
12353 
12354 // The etc__hpd_left_shift and etc__powers_of_5 tables were printed by
12355 // script/print-hpd-left-shift.go. That script has an optional -comments flag,
12356 // whose output is not copied here, which prints further detail.
12357 //
12358 // These tables are used in
12359 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits.
12360 
12361 // wuffs_base__private_implementation__hpd_left_shift[i] encodes the number of
12362 // new digits created after multiplying a positive integer by (1 << i): the
12363 // additional length in the decimal representation. For example, shifting "234"
12364 // by 3 (equivalent to multiplying by 8) will produce "1872". Going from a
12365 // 3-length string to a 4-length string means that 1 new digit was added (and
12366 // existing digits may have changed).
12367 //
12368 // Shifting by i can add either N or N-1 new digits, depending on whether the
12369 // original positive integer compares >= or < to the i'th power of 5 (as 10
12370 // equals 2 * 5). Comparison is lexicographic, not numerical.
12371 //
12372 // For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new
12373 // digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625":
12374 //  - ("1"      << 4) is "16",       which adds 1 new digit.
12375 //  - ("5678"   << 4) is "90848",    which adds 1 new digit.
12376 //  - ("624"    << 4) is "9984",     which adds 1 new digit.
12377 //  - ("62498"  << 4) is "999968",   which adds 1 new digit.
12378 //  - ("625"    << 4) is "10000",    which adds 2 new digits.
12379 //  - ("625001" << 4) is "10000016", which adds 2 new digits.
12380 //  - ("7008"   << 4) is "112128",   which adds 2 new digits.
12381 //  - ("99"     << 4) is "1584",     which adds 2 new digits.
12382 //
12383 // Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift
12384 // array encodes this as:
12385 //  - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006.
12386 //  - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009.
12387 // where the ? isn't relevant for i == 4.
12388 //
12389 // The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two
12390 // possible number of new digits. The low 11 bits are an offset into the
12391 // etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i
12392 // is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9]
12393 // is the string "\x06\x02\x05", so the relevant power of 5 is "625".
12394 //
12395 // Thanks to Ken Thompson for the original idea.
12396 static const uint16_t wuffs_base__private_implementation__hpd_left_shift[65] = {
12397     0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
12398     0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
12399     0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
12400     0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
12401     0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
12402     0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
12403     0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
12404     0x051C, 0x051C,
12405 };
12406 
12407 // wuffs_base__private_implementation__powers_of_5 contains the powers of 5,
12408 // concatenated together: "5", "25", "125", "625", "3125", etc.
12409 static const uint8_t wuffs_base__private_implementation__powers_of_5[0x051C] = {
12410     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,
12411     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,
12412     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,
12413     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,
12414     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,
12415     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,
12416     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,
12417     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,
12418     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,
12419     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,
12420     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,
12421     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,
12422     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,
12423     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,
12424     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,
12425     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,
12426     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,
12427     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,
12428     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,
12429     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,
12430     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,
12431     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,
12432     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,
12433     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,
12434     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,
12435     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,
12436     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,
12437     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,
12438     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,
12439     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,
12440     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,
12441     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,
12442     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,
12443     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,
12444     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,
12445     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,
12446     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,
12447     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,
12448     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,
12449     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,
12450     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,
12451     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,
12452     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,
12453     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,
12454     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,
12455     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,
12456     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,
12457     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,
12458     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,
12459     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,
12460     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,
12461     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,
12462     6, 9, 1, 4, 0, 6, 2, 5,
12463 };
12464 
12465 // --------
12466 
12467 // wuffs_base__private_implementation__powers_of_10 contains truncated
12468 // approximations to the powers of 10, ranging from 1e-307 to 1e+288 inclusive,
12469 // as 596 pairs of uint64_t values (a 128-bit mantissa).
12470 //
12471 // There's also an implicit third column (implied by a linear formula involving
12472 // the base-10 exponent) that is the base-2 exponent, biased by a magic
12473 // constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias
12474 // for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and
12475 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire works with
12476 // multiples-of-64-bit mantissas.
12477 //
12478 // For example, the third row holds the approximation to 1e-305:
12479 //   0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE))
12480 //
12481 // Similarly, 1e+4 is approximated by:
12482 //   0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE))
12483 //
12484 // Similarly, 1e+68 is approximated by:
12485 //   0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE))
12486 //
12487 // This table was generated by by script/print-mpb-powers-of-10.go
12488 static const uint64_t wuffs_base__private_implementation__powers_of_10[596][2] =
12489     {
12490         {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB},  // 1e-307
12491         {0x8F48A4899877186C, 0xB3C4F1BA87BC8696},  // 1e-306
12492         {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C},  // 1e-305
12493         {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925},  // 1e-304
12494         {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F},  // 1e-303
12495         {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A},  // 1e-302
12496         {0xBE311C083A225CD2, 0x892731AC9FAF056E},  // 1e-301
12497         {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA},  // 1e-300
12498         {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D},  // 1e-299
12499         {0x25BBF56008C58EA5, 0x85F0468293F0EB4E},  // 1e-298
12500         {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621},  // 1e-297
12501         {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA},  // 1e-296
12502         {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA},  // 1e-295
12503         {0xE50FF107BAB528A0, 0xA37FCE126597973C},  // 1e-294
12504         {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C},  // 1e-293
12505         {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F},  // 1e-292
12506         {0x77B191618C54E9AC, 0x9FAACF3DF73609B1},  // 1e-291
12507         {0xD59DF5B9EF6A2417, 0xC795830D75038C1D},  // 1e-290
12508         {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25},  // 1e-289
12509         {0x4EE367F9430AEC32, 0x9BECCE62836AC577},  // 1e-288
12510         {0x229C41F793CDA73F, 0xC2E801FB244576D5},  // 1e-287
12511         {0x6B43527578C1110F, 0xF3A20279ED56D48A},  // 1e-286
12512         {0x830A13896B78AAA9, 0x9845418C345644D6},  // 1e-285
12513         {0x23CC986BC656D553, 0xBE5691EF416BD60C},  // 1e-284
12514         {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F},  // 1e-283
12515         {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39},  // 1e-282
12516         {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07},  // 1e-281
12517         {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9},  // 1e-280
12518         {0x23100809B9C21FA1, 0x91376C36D99995BE},  // 1e-279
12519         {0xABD40A0C2832A78A, 0xB58547448FFFFB2D},  // 1e-278
12520         {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9},  // 1e-277
12521         {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B},  // 1e-276
12522         {0x99CD11CFDF41779C, 0xB1442798F49FFB4A},  // 1e-275
12523         {0x40405643D711D583, 0xDD95317F31C7FA1D},  // 1e-274
12524         {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52},  // 1e-273
12525         {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66},  // 1e-272
12526         {0x90BED43E40076A82, 0xD863B256369D4A40},  // 1e-271
12527         {0x5A7744A6E804A291, 0x873E4F75E2224E68},  // 1e-270
12528         {0x711515D0A205CB36, 0xA90DE3535AAAE202},  // 1e-269
12529         {0x0D5A5B44CA873E03, 0xD3515C2831559A83},  // 1e-268
12530         {0xE858790AFE9486C2, 0x8412D9991ED58091},  // 1e-267
12531         {0x626E974DBE39A872, 0xA5178FFF668AE0B6},  // 1e-266
12532         {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3},  // 1e-265
12533         {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E},  // 1e-264
12534         {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72},  // 1e-263
12535         {0xA327FFB266B56220, 0xC987434744AC874E},  // 1e-262
12536         {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922},  // 1e-261
12537         {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5},  // 1e-260
12538         {0xCB550FB4384D21D3, 0xC4CE17B399107C22},  // 1e-259
12539         {0x7E2A53A146606A48, 0xF6019DA07F549B2B},  // 1e-258
12540         {0x2EDA7444CBFC426D, 0x99C102844F94E0FB},  // 1e-257
12541         {0xFA911155FEFB5308, 0xC0314325637A1939},  // 1e-256
12542         {0x793555AB7EBA27CA, 0xF03D93EEBC589F88},  // 1e-255
12543         {0x4BC1558B2F3458DE, 0x96267C7535B763B5},  // 1e-254
12544         {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2},  // 1e-253
12545         {0x465E15A979C1CADC, 0xEA9C227723EE8BCB},  // 1e-252
12546         {0x0BFACD89EC191EC9, 0x92A1958A7675175F},  // 1e-251
12547         {0xCEF980EC671F667B, 0xB749FAED14125D36},  // 1e-250
12548         {0x82B7E12780E7401A, 0xE51C79A85916F484},  // 1e-249
12549         {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2},  // 1e-248
12550         {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07},  // 1e-247
12551         {0x67A791E093E1D49A, 0xDFBDCECE67006AC9},  // 1e-246
12552         {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD},  // 1e-245
12553         {0x58FAE9F773886E18, 0xAECC49914078536D},  // 1e-244
12554         {0xAF39A475506A899E, 0xDA7F5BF590966848},  // 1e-243
12555         {0x6D8406C952429603, 0x888F99797A5E012D},  // 1e-242
12556         {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178},  // 1e-241
12557         {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6},  // 1e-240
12558         {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26},  // 1e-239
12559         {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F},  // 1e-238
12560         {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B},  // 1e-237
12561         {0x76C53D08D6B70858, 0x823C12795DB6CE57},  // 1e-236
12562         {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED},  // 1e-235
12563         {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268},  // 1e-234
12564         {0xD3F93B35435D7C4C, 0xFE5D54150B090B02},  // 1e-233
12565         {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1},  // 1e-232
12566         {0x359AB6419CA1091B, 0xC6B8E9B0709F109A},  // 1e-231
12567         {0xC30163D203C94B62, 0xF867241C8CC6D4C0},  // 1e-230
12568         {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8},  // 1e-229
12569         {0x985915FC12F542E4, 0xC21094364DFB5636},  // 1e-228
12570         {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4},  // 1e-227
12571         {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A},  // 1e-226
12572         {0x50C6FF782A838353, 0xBD8430BD08277231},  // 1e-225
12573         {0xA4F8BF5635246428, 0xECE53CEC4A314EBD},  // 1e-224
12574         {0x871B7795E136BE99, 0x940F4613AE5ED136},  // 1e-223
12575         {0x28E2557B59846E3F, 0xB913179899F68584},  // 1e-222
12576         {0x331AEADA2FE589CF, 0xE757DD7EC07426E5},  // 1e-221
12577         {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F},  // 1e-220
12578         {0x0FED077A756B53A9, 0xB4BCA50B065ABE63},  // 1e-219
12579         {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB},  // 1e-218
12580         {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD},  // 1e-217
12581         {0xBD8D794D96AACFB3, 0xB080392CC4349DEC},  // 1e-216
12582         {0xECF0D7A0FC5583A0, 0xDCA04777F541C567},  // 1e-215
12583         {0xF41686C49DB57244, 0x89E42CAAF9491B60},  // 1e-214
12584         {0x311C2875C522CED5, 0xAC5D37D5B79B6239},  // 1e-213
12585         {0x7D633293366B828B, 0xD77485CB25823AC7},  // 1e-212
12586         {0xAE5DFF9C02033197, 0x86A8D39EF77164BC},  // 1e-211
12587         {0xD9F57F830283FDFC, 0xA8530886B54DBDEB},  // 1e-210
12588         {0xD072DF63C324FD7B, 0xD267CAA862A12D66},  // 1e-209
12589         {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60},  // 1e-208
12590         {0x52D9BE85F074E608, 0xA46116538D0DEB78},  // 1e-207
12591         {0x67902E276C921F8B, 0xCD795BE870516656},  // 1e-206
12592         {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6},  // 1e-205
12593         {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3},  // 1e-204
12594         {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0},  // 1e-203
12595         {0x796B805720085F81, 0xFAD2A4B13D1B5D6C},  // 1e-202
12596         {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63},  // 1e-201
12597         {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC},  // 1e-200
12598         {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B},  // 1e-199
12599         {0x751BDD152D4D1C4A, 0x991711052D8BF3C5},  // 1e-198
12600         {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6},  // 1e-197
12601         {0x86FB897116C87C34, 0xEF340A98172AACE4},  // 1e-196
12602         {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E},  // 1e-195
12603         {0x8974836059CCA109, 0xBAE0A846D2195712},  // 1e-194
12604         {0x2BD1A438703FC94B, 0xE998D258869FACD7},  // 1e-193
12605         {0x7B6306A34627DDCF, 0x91FF83775423CC06},  // 1e-192
12606         {0x1A3BC84C17B1D542, 0xB67F6455292CBF08},  // 1e-191
12607         {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA},  // 1e-190
12608         {0x547EB47B7282EE9C, 0x8E938662882AF53E},  // 1e-189
12609         {0xE99E619A4F23AA43, 0xB23867FB2A35B28D},  // 1e-188
12610         {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31},  // 1e-187
12611         {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E},  // 1e-186
12612         {0x9624AB50B148D445, 0xAE0B158B4738705E},  // 1e-185
12613         {0x3BADD624DD9B0957, 0xD98DDAEE19068C76},  // 1e-184
12614         {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9},  // 1e-183
12615         {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC},  // 1e-182
12616         {0x7647C3200069671F, 0xD47487CC8470652B},  // 1e-181
12617         {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B},  // 1e-180
12618         {0xF468107100525890, 0xA5FB0A17C777CF09},  // 1e-179
12619         {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC},  // 1e-178
12620         {0xC6F14CD848405530, 0x81AC1FE293D599BF},  // 1e-177
12621         {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F},  // 1e-176
12622         {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B},  // 1e-175
12623         {0x908F4A166D1DA663, 0xFD442E4688BD304A},  // 1e-174
12624         {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E},  // 1e-173
12625         {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA},  // 1e-172
12626         {0xD12BEE59E68EF47C, 0xF7549530E188C128},  // 1e-171
12627         {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9},  // 1e-170
12628         {0xE36A52363C1FAF01, 0xC13A148E3032D6E7},  // 1e-169
12629         {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1},  // 1e-168
12630         {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5},  // 1e-167
12631         {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE},  // 1e-166
12632         {0x111B495B3464AD21, 0xEBDF661791D60F56},  // 1e-165
12633         {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995},  // 1e-164
12634         {0x3D5D514F40EEA742, 0xB84687C269EF3BFB},  // 1e-163
12635         {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA},  // 1e-162
12636         {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC},  // 1e-161
12637         {0x59ED216765690F56, 0xB3F4E093DB73A093},  // 1e-160
12638         {0x306869C13EC3532C, 0xE0F218B8D25088B8},  // 1e-159
12639         {0x1E414218C73A13FB, 0x8C974F7383725573},  // 1e-158
12640         {0xE5D1929EF90898FA, 0xAFBD2350644EEACF},  // 1e-157
12641         {0xDF45F746B74ABF39, 0xDBAC6C247D62A583},  // 1e-156
12642         {0x6B8BBA8C328EB783, 0x894BC396CE5DA772},  // 1e-155
12643         {0x066EA92F3F326564, 0xAB9EB47C81F5114F},  // 1e-154
12644         {0xC80A537B0EFEFEBD, 0xD686619BA27255A2},  // 1e-153
12645         {0xBD06742CE95F5F36, 0x8613FD0145877585},  // 1e-152
12646         {0x2C48113823B73704, 0xA798FC4196E952E7},  // 1e-151
12647         {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0},  // 1e-150
12648         {0x9A984D73DBE722FB, 0x82EF85133DE648C4},  // 1e-149
12649         {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5},  // 1e-148
12650         {0x318DF905079926A8, 0xCC963FEE10B7D1B3},  // 1e-147
12651         {0xFDF17746497F7052, 0xFFBBCFE994E5C61F},  // 1e-146
12652         {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3},  // 1e-145
12653         {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8},  // 1e-144
12654         {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B},  // 1e-143
12655         {0x06BEA10CA65C084E, 0x9C1661A651213E2D},  // 1e-142
12656         {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8},  // 1e-141
12657         {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126},  // 1e-140
12658         {0xF89629465A75E01C, 0x986DDB5C6B3A76B7},  // 1e-139
12659         {0xF6BBB397F1135823, 0xBE89523386091465},  // 1e-138
12660         {0x746AA07DED582E2C, 0xEE2BA6C0678B597F},  // 1e-137
12661         {0xA8C2A44EB4571CDC, 0x94DB483840B717EF},  // 1e-136
12662         {0x92F34D62616CE413, 0xBA121A4650E4DDEB},  // 1e-135
12663         {0x77B020BAF9C81D17, 0xE896A0D7E51E1566},  // 1e-134
12664         {0x0ACE1474DC1D122E, 0x915E2486EF32CD60},  // 1e-133
12665         {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8},  // 1e-132
12666         {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6},  // 1e-131
12667         {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F},  // 1e-130
12668         {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3},  // 1e-129
12669         {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0},  // 1e-128
12670         {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4},  // 1e-127
12671         {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D},  // 1e-126
12672         {0xE871C7BF077BA8B7, 0xD89D64D57A607744},  // 1e-125
12673         {0x11471CD764AD4972, 0x87625F056C7C4A8B},  // 1e-124
12674         {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D},  // 1e-123
12675         {0x4AFF1D108D4EC2C3, 0xD389B47879823479},  // 1e-122
12676         {0xCEDF722A585139BA, 0x843610CB4BF160CB},  // 1e-121
12677         {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE},  // 1e-120
12678         {0x733D226229FEEA32, 0xCE947A3DA6A9273E},  // 1e-119
12679         {0x0806357D5A3F525F, 0x811CCC668829B887},  // 1e-118
12680         {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8},  // 1e-117
12681         {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052},  // 1e-116
12682         {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67},  // 1e-115
12683         {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0},  // 1e-114
12684         {0x0A9E795E65D4DF11, 0xC5029163F384A931},  // 1e-113
12685         {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D},  // 1e-112
12686         {0x504BCED1BF8E4E45, 0x99EA0196163FA42E},  // 1e-111
12687         {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39},  // 1e-110
12688         {0x5D767327BB4E5A4C, 0xF07DA27A82C37088},  // 1e-109
12689         {0x3A6A07F8D510F86F, 0x964E858C91BA2655},  // 1e-108
12690         {0x890489F70A55368B, 0xBBE226EFB628AFEA},  // 1e-107
12691         {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5},  // 1e-106
12692         {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F},  // 1e-105
12693         {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB},  // 1e-104
12694         {0xCC420A6A101D0515, 0xE55990879DDCAABD},  // 1e-103
12695         {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6},  // 1e-102
12696         {0x47939822DC96ABF9, 0xB32DF8E9F3546564},  // 1e-101
12697         {0x59787E2B93BC56F7, 0xDFF9772470297EBD},  // 1e-100
12698         {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36},  // 1e-99
12699         {0xEDE622920B6B23F1, 0xAEFAE51477A06B03},  // 1e-98
12700         {0xE95FAB368E45ECED, 0xDAB99E59958885C4},  // 1e-97
12701         {0x11DBCB0218EBB414, 0x88B402F7FD75539B},  // 1e-96
12702         {0xD652BDC29F26A119, 0xAAE103B5FCD2A881},  // 1e-95
12703         {0x4BE76D3346F0495F, 0xD59944A37C0752A2},  // 1e-94
12704         {0x6F70A4400C562DDB, 0x857FCAE62D8493A5},  // 1e-93
12705         {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E},  // 1e-92
12706         {0x7E2000A41346A7A7, 0xD097AD07A71F26B2},  // 1e-91
12707         {0x8ED400668C0C28C8, 0x825ECC24C873782F},  // 1e-90
12708         {0x728900802F0F32FA, 0xA2F67F2DFA90563B},  // 1e-89
12709         {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA},  // 1e-88
12710         {0xE2F610C84987BFA8, 0xFEA126B7D78186BC},  // 1e-87
12711         {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436},  // 1e-86
12712         {0x91503D1C79720DBB, 0xC6EDE63FA05D3143},  // 1e-85
12713         {0x75A44C6397CE912A, 0xF8A95FCF88747D94},  // 1e-84
12714         {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C},  // 1e-83
12715         {0xFBE85BADCE996168, 0xC24452DA229B021B},  // 1e-82
12716         {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2},  // 1e-81
12717         {0xDCCD879FC967D41A, 0x97C560BA6B0919A5},  // 1e-80
12718         {0x5400E987BBC1C920, 0xBDB6B8E905CB600F},  // 1e-79
12719         {0x290123E9AAB23B68, 0xED246723473E3813},  // 1e-78
12720         {0xF9A0B6720AAF6521, 0x9436C0760C86E30B},  // 1e-77
12721         {0xF808E40E8D5B3E69, 0xB94470938FA89BCE},  // 1e-76
12722         {0xB60B1D1230B20E04, 0xE7958CB87392C2C2},  // 1e-75
12723         {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9},  // 1e-74
12724         {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828},  // 1e-73
12725         {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232},  // 1e-72
12726         {0x579C487E5A38AD0E, 0x8D590723948A535F},  // 1e-71
12727         {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837},  // 1e-70
12728         {0xF8E431456CF88E65, 0xDCDB1B2798182244},  // 1e-69
12729         {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B},  // 1e-68
12730         {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5},  // 1e-67
12731         {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177},  // 1e-66
12732         {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA},  // 1e-65
12733         {0x3F2398D747B36224, 0xA87FEA27A539E9A5},  // 1e-64
12734         {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E},  // 1e-63
12735         {0x1953CF68300424AC, 0x83A3EEEEF9153E89},  // 1e-62
12736         {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B},  // 1e-61
12737         {0x3792F412CB06794D, 0xCDB02555653131B6},  // 1e-60
12738         {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11},  // 1e-59
12739         {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6},  // 1e-58
12740         {0xF245825A5A445275, 0xC8DE047564D20A8B},  // 1e-57
12741         {0xEED6E2F0F0D56712, 0xFB158592BE068D2E},  // 1e-56
12742         {0x55464DD69685606B, 0x9CED737BB6C4183D},  // 1e-55
12743         {0xAA97E14C3C26B886, 0xC428D05AA4751E4C},  // 1e-54
12744         {0xD53DD99F4B3066A8, 0xF53304714D9265DF},  // 1e-53
12745         {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB},  // 1e-52
12746         {0xDE98520472BDD033, 0xBF8FDB78849A5F96},  // 1e-51
12747         {0x963E66858F6D4440, 0xEF73D256A5C0F77C},  // 1e-50
12748         {0xDDE7001379A44AA8, 0x95A8637627989AAD},  // 1e-49
12749         {0x5560C018580D5D52, 0xBB127C53B17EC159},  // 1e-48
12750         {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF},  // 1e-47
12751         {0xCAB3961304CA70E8, 0x9226712162AB070D},  // 1e-46
12752         {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1},  // 1e-45
12753         {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05},  // 1e-44
12754         {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3},  // 1e-43
12755         {0x55F038B237591ED3, 0xB267ED1940F1C61C},  // 1e-42
12756         {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3},  // 1e-41
12757         {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6},  // 1e-40
12758         {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77},  // 1e-39
12759         {0x96E7BD358C904A21, 0xD9C7DCED53C72255},  // 1e-38
12760         {0x7E50D64177DA2E54, 0x881CEA14545C7575},  // 1e-37
12761         {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2},  // 1e-36
12762         {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787},  // 1e-35
12763         {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4},  // 1e-34
12764         {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61},  // 1e-33
12765         {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA},  // 1e-32
12766         {0x80EACF948770CED7, 0x81CEB32C4B43FCF4},  // 1e-31
12767         {0xA1258379A94D028D, 0xA2425FF75E14FC31},  // 1e-30
12768         {0x096EE45813A04330, 0xCAD2F7F5359A3B3E},  // 1e-29
12769         {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D},  // 1e-28
12770         {0x775EA264CF55347D, 0x9E74D1B791E07E48},  // 1e-27
12771         {0x95364AFE032A819D, 0xC612062576589DDA},  // 1e-26
12772         {0x3A83DDBD83F52204, 0xF79687AED3EEC551},  // 1e-25
12773         {0xC4926A9672793542, 0x9ABE14CD44753B52},  // 1e-24
12774         {0x75B7053C0F178293, 0xC16D9A0095928A27},  // 1e-23
12775         {0x5324C68B12DD6338, 0xF1C90080BAF72CB1},  // 1e-22
12776         {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE},  // 1e-21
12777         {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA},  // 1e-20
12778         {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5},  // 1e-19
12779         {0x3AFF322E62439FCF, 0x9392EE8E921D5D07},  // 1e-18
12780         {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449},  // 1e-17
12781         {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B},  // 1e-16
12782         {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9},  // 1e-15
12783         {0x538484C19EF38C94, 0xB424DC35095CD80F},  // 1e-14
12784         {0x2865A5F206B06FB9, 0xE12E13424BB40E13},  // 1e-13
12785         {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB},  // 1e-12
12786         {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE},  // 1e-11
12787         {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE},  // 1e-10
12788         {0x31680A88F8953030, 0x89705F4136B4A597},  // 1e-9
12789         {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC},  // 1e-8
12790         {0x3D32907604691B4C, 0xD6BF94D5E57A42BC},  // 1e-7
12791         {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5},  // 1e-6
12792         {0x0FCF80DC33721D53, 0xA7C5AC471B478423},  // 1e-5
12793         {0xD3C36113404EA4A8, 0xD1B71758E219652B},  // 1e-4
12794         {0x645A1CAC083126E9, 0x83126E978D4FDF3B},  // 1e-3
12795         {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A},  // 1e-2
12796         {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC},  // 1e-1
12797         {0x0000000000000000, 0x8000000000000000},  // 1e0
12798         {0x0000000000000000, 0xA000000000000000},  // 1e1
12799         {0x0000000000000000, 0xC800000000000000},  // 1e2
12800         {0x0000000000000000, 0xFA00000000000000},  // 1e3
12801         {0x0000000000000000, 0x9C40000000000000},  // 1e4
12802         {0x0000000000000000, 0xC350000000000000},  // 1e5
12803         {0x0000000000000000, 0xF424000000000000},  // 1e6
12804         {0x0000000000000000, 0x9896800000000000},  // 1e7
12805         {0x0000000000000000, 0xBEBC200000000000},  // 1e8
12806         {0x0000000000000000, 0xEE6B280000000000},  // 1e9
12807         {0x0000000000000000, 0x9502F90000000000},  // 1e10
12808         {0x0000000000000000, 0xBA43B74000000000},  // 1e11
12809         {0x0000000000000000, 0xE8D4A51000000000},  // 1e12
12810         {0x0000000000000000, 0x9184E72A00000000},  // 1e13
12811         {0x0000000000000000, 0xB5E620F480000000},  // 1e14
12812         {0x0000000000000000, 0xE35FA931A0000000},  // 1e15
12813         {0x0000000000000000, 0x8E1BC9BF04000000},  // 1e16
12814         {0x0000000000000000, 0xB1A2BC2EC5000000},  // 1e17
12815         {0x0000000000000000, 0xDE0B6B3A76400000},  // 1e18
12816         {0x0000000000000000, 0x8AC7230489E80000},  // 1e19
12817         {0x0000000000000000, 0xAD78EBC5AC620000},  // 1e20
12818         {0x0000000000000000, 0xD8D726B7177A8000},  // 1e21
12819         {0x0000000000000000, 0x878678326EAC9000},  // 1e22
12820         {0x0000000000000000, 0xA968163F0A57B400},  // 1e23
12821         {0x0000000000000000, 0xD3C21BCECCEDA100},  // 1e24
12822         {0x0000000000000000, 0x84595161401484A0},  // 1e25
12823         {0x0000000000000000, 0xA56FA5B99019A5C8},  // 1e26
12824         {0x0000000000000000, 0xCECB8F27F4200F3A},  // 1e27
12825         {0x4000000000000000, 0x813F3978F8940984},  // 1e28
12826         {0x5000000000000000, 0xA18F07D736B90BE5},  // 1e29
12827         {0xA400000000000000, 0xC9F2C9CD04674EDE},  // 1e30
12828         {0x4D00000000000000, 0xFC6F7C4045812296},  // 1e31
12829         {0xF020000000000000, 0x9DC5ADA82B70B59D},  // 1e32
12830         {0x6C28000000000000, 0xC5371912364CE305},  // 1e33
12831         {0xC732000000000000, 0xF684DF56C3E01BC6},  // 1e34
12832         {0x3C7F400000000000, 0x9A130B963A6C115C},  // 1e35
12833         {0x4B9F100000000000, 0xC097CE7BC90715B3},  // 1e36
12834         {0x1E86D40000000000, 0xF0BDC21ABB48DB20},  // 1e37
12835         {0x1314448000000000, 0x96769950B50D88F4},  // 1e38
12836         {0x17D955A000000000, 0xBC143FA4E250EB31},  // 1e39
12837         {0x5DCFAB0800000000, 0xEB194F8E1AE525FD},  // 1e40
12838         {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE},  // 1e41
12839         {0xF14A3D9E40000000, 0xB7ABC627050305AD},  // 1e42
12840         {0x6D9CCD05D0000000, 0xE596B7B0C643C719},  // 1e43
12841         {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F},  // 1e44
12842         {0xDDA2802C8A800000, 0xB35DBF821AE4F38B},  // 1e45
12843         {0xD50B2037AD200000, 0xE0352F62A19E306E},  // 1e46
12844         {0x4526F422CC340000, 0x8C213D9DA502DE45},  // 1e47
12845         {0x9670B12B7F410000, 0xAF298D050E4395D6},  // 1e48
12846         {0x3C0CDD765F114000, 0xDAF3F04651D47B4C},  // 1e49
12847         {0xA5880A69FB6AC800, 0x88D8762BF324CD0F},  // 1e50
12848         {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053},  // 1e51
12849         {0x72A4904598D6D880, 0xD5D238A4ABE98068},  // 1e52
12850         {0x47A6DA2B7F864750, 0x85A36366EB71F041},  // 1e53
12851         {0x999090B65F67D924, 0xA70C3C40A64E6C51},  // 1e54
12852         {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765},  // 1e55
12853         {0xBFF8F10E7A8921A4, 0x82818F1281ED449F},  // 1e56
12854         {0xAFF72D52192B6A0D, 0xA321F2D7226895C7},  // 1e57
12855         {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39},  // 1e58
12856         {0x02F236D04753D5B4, 0xFEE50B7025C36A08},  // 1e59
12857         {0x01D762422C946590, 0x9F4F2726179A2245},  // 1e60
12858         {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6},  // 1e61
12859         {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B},  // 1e62
12860         {0x63CC55F49F88EB2F, 0x9B934C3B330C8577},  // 1e63
12861         {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5},  // 1e64
12862         {0x8BEF464E3945EF7A, 0xF316271C7FC3908A},  // 1e65
12863         {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56},  // 1e66
12864         {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC},  // 1e67
12865         {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27},  // 1e68
12866         {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8},  // 1e69
12867         {0xB3E2FD538E122B44, 0xB975D6B6EE39E436},  // 1e70
12868         {0x60DBBCA87196B616, 0xE7D34C64A9C85D44},  // 1e71
12869         {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A},  // 1e72
12870         {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD},  // 1e73
12871         {0xC696963C7EED2DD1, 0xE264589A4DCDAB14},  // 1e74
12872         {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC},  // 1e75
12873         {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8},  // 1e76
12874         {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912},  // 1e77
12875         {0x6E3569326C784337, 0x8A2DBF142DFCC7AB},  // 1e78
12876         {0x49C2C37F07965404, 0xACB92ED9397BF996},  // 1e79
12877         {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB},  // 1e80
12878         {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD},  // 1e81
12879         {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC},  // 1e82
12880         {0xF50A3FA490C30190, 0xD2D80DB02AABD62B},  // 1e83
12881         {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB},  // 1e84
12882         {0x577001B891185938, 0xA4B8CAB1A1563F52},  // 1e85
12883         {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26},  // 1e86
12884         {0x544F8158315B05B4, 0x80B05E5AC60B6178},  // 1e87
12885         {0x696361AE3DB1C721, 0xA0DC75F1778E39D6},  // 1e88
12886         {0x03BC3A19CD1E38E9, 0xC913936DD571C84C},  // 1e89
12887         {0x04AB48A04065C723, 0xFB5878494ACE3A5F},  // 1e90
12888         {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B},  // 1e91
12889         {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A},  // 1e92
12890         {0xCA8F44EC7EE36479, 0xF5746577930D6500},  // 1e93
12891         {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20},  // 1e94
12892         {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8},  // 1e95
12893         {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2},  // 1e96
12894         {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5},  // 1e97
12895         {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F},  // 1e98
12896         {0xF52D09D71A3293BD, 0xEA1575143CF97226},  // 1e99
12897         {0x593C2626705F9C56, 0x924D692CA61BE758},  // 1e100
12898         {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E},  // 1e101
12899         {0x0B6DFB9C0F956447, 0xE498F455C38B997A},  // 1e102
12900         {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC},  // 1e103
12901         {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7},  // 1e104
12902         {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1},  // 1e105
12903         {0xBD79E0D20082EE74, 0x8B865B215899F46C},  // 1e106
12904         {0xECD8590680A3AA11, 0xAE67F1E9AEC07187},  // 1e107
12905         {0xE80E6F4820CC9495, 0xDA01EE641A708DE9},  // 1e108
12906         {0x3109058D147FDCDD, 0x884134FE908658B2},  // 1e109
12907         {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE},  // 1e110
12908         {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96},  // 1e111
12909         {0x03E2CF6BC604DDB0, 0x850FADC09923329E},  // 1e112
12910         {0x84DB8346B786151C, 0xA6539930BF6BFF45},  // 1e113
12911         {0xE612641865679A63, 0xCFE87F7CEF46FF16},  // 1e114
12912         {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E},  // 1e115
12913         {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749},  // 1e116
12914         {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C},  // 1e117
12915         {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63},  // 1e118
12916         {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E},  // 1e119
12917         {0xB281E1FD541501B8, 0xC646D63501A1511D},  // 1e120
12918         {0x1F225A7CA91A4226, 0xF7D88BC24209A565},  // 1e121
12919         {0x3375788DE9B06958, 0x9AE757596946075F},  // 1e122
12920         {0x0052D6B1641C83AE, 0xC1A12D2FC3978937},  // 1e123
12921         {0xC0678C5DBD23A49A, 0xF209787BB47D6B84},  // 1e124
12922         {0xF840B7BA963646E0, 0x9745EB4D50CE6332},  // 1e125
12923         {0xB650E5A93BC3D898, 0xBD176620A501FBFF},  // 1e126
12924         {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF},  // 1e127
12925         {0xC66F336C36B10137, 0x93BA47C980E98CDF},  // 1e128
12926         {0xB80B0047445D4184, 0xB8A8D9BBE123F017},  // 1e129
12927         {0xA60DC059157491E5, 0xE6D3102AD96CEC1D},  // 1e130
12928         {0x87C89837AD68DB2F, 0x9043EA1AC7E41392},  // 1e131
12929         {0x29BABE4598C311FB, 0xB454E4A179DD1877},  // 1e132
12930         {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94},  // 1e133
12931         {0x1899E4A65F58660C, 0x8CE2529E2734BB1D},  // 1e134
12932         {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4},  // 1e135
12933         {0x76707543F4FA1F73, 0xDC21A1171D42645D},  // 1e136
12934         {0x6A06494A791C53A8, 0x899504AE72497EBA},  // 1e137
12935         {0x0487DB9D17636892, 0xABFA45DA0EDBDE69},  // 1e138
12936         {0x45A9D2845D3C42B6, 0xD6F8D7509292D603},  // 1e139
12937         {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2},  // 1e140
12938         {0x8E6CAC7768D7141E, 0xA7F26836F282B732},  // 1e141
12939         {0x3207D795430CD926, 0xD1EF0244AF2364FF},  // 1e142
12940         {0x7F44E6BD49E807B8, 0x8335616AED761F1F},  // 1e143
12941         {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7},  // 1e144
12942         {0x36DBA887C37A8C0F, 0xCD036837130890A1},  // 1e145
12943         {0xC2494954DA2C9789, 0x802221226BE55A64},  // 1e146
12944         {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD},  // 1e147
12945         {0x6F92829494E5ACC7, 0xC83553C5C8965D3D},  // 1e148
12946         {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C},  // 1e149
12947         {0xFF2A760414536EFB, 0x9C69A97284B578D7},  // 1e150
12948         {0xFEF5138519684ABA, 0xC38413CF25E2D70D},  // 1e151
12949         {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1},  // 1e152
12950         {0xEF2F773FFBD97A61, 0x98BF2F79D5993802},  // 1e153
12951         {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603},  // 1e154
12952         {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784},  // 1e155
12953         {0xDD945A747BF26183, 0x952AB45CFA97A0B2},  // 1e156
12954         {0x94F971119AEEF9E4, 0xBA756174393D88DF},  // 1e157
12955         {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17},  // 1e158
12956         {0xAC62E055C10AB33A, 0x91ABB422CCB812EE},  // 1e159
12957         {0x577B986B314D6009, 0xB616A12B7FE617AA},  // 1e160
12958         {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94},  // 1e161
12959         {0x14588F13BE847307, 0x8E41ADE9FBEBC27D},  // 1e162
12960         {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C},  // 1e163
12961         {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3},  // 1e164
12962         {0x25DE7BB9480D5854, 0x8AEC23D680043BEE},  // 1e165
12963         {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9},  // 1e166
12964         {0x1B2BA1518094DA04, 0xD910F7FF28069DA4},  // 1e167
12965         {0x90FB44D2F05D0842, 0x87AA9AFF79042286},  // 1e168
12966         {0x353A1607AC744A53, 0xA99541BF57452B28},  // 1e169
12967         {0x42889B8997915CE8, 0xD3FA922F2D1675F2},  // 1e170
12968         {0x69956135FEBADA11, 0x847C9B5D7C2E09B7},  // 1e171
12969         {0x43FAB9837E699095, 0xA59BC234DB398C25},  // 1e172
12970         {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E},  // 1e173
12971         {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D},  // 1e174
12972         {0x6462D92A69731732, 0xA1BA1BA79E1632DC},  // 1e175
12973         {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93},  // 1e176
12974         {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78},  // 1e177
12975         {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB},  // 1e178
12976         {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916},  // 1e179
12977         {0x8AAD549E57273D45, 0xF6C69A72A3989F5B},  // 1e180
12978         {0x36AC54E2F678864B, 0x9A3C2087A63F6399},  // 1e181
12979         {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F},  // 1e182
12980         {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F},  // 1e183
12981         {0x9F644AE5A4B1B325, 0x969EB7C47859E743},  // 1e184
12982         {0x873D5D9F0DDE1FEE, 0xBC4665B596706114},  // 1e185
12983         {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959},  // 1e186
12984         {0x09A7F12442D588F2, 0x9316FF75DD87CBD8},  // 1e187
12985         {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE},  // 1e188
12986         {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81},  // 1e189
12987         {0xF96E017D694487BC, 0x8FA475791A569D10},  // 1e190
12988         {0x37C981DCC395A9AC, 0xB38D92D760EC4455},  // 1e191
12989         {0x85BBE253F47B1417, 0xE070F78D3927556A},  // 1e192
12990         {0x93956D7478CCEC8E, 0x8C469AB843B89562},  // 1e193
12991         {0x387AC8D1970027B2, 0xAF58416654A6BABB},  // 1e194
12992         {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A},  // 1e195
12993         {0x441FECE3BDF81F03, 0x88FCF317F22241E2},  // 1e196
12994         {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A},  // 1e197
12995         {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1},  // 1e198
12996         {0xF6872D5667844E49, 0x85C7056562757456},  // 1e199
12997         {0xB428F8AC016561DB, 0xA738C6BEBB12D16C},  // 1e200
12998         {0xE13336D701BEBA52, 0xD106F86E69D785C7},  // 1e201
12999         {0xECC0024661173473, 0x82A45B450226B39C},  // 1e202
13000         {0x27F002D7F95D0190, 0xA34D721642B06084},  // 1e203
13001         {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5},  // 1e204
13002         {0x7E67047175A15271, 0xFF290242C83396CE},  // 1e205
13003         {0x0F0062C6E984D386, 0x9F79A169BD203E41},  // 1e206
13004         {0x52C07B78A3E60868, 0xC75809C42C684DD1},  // 1e207
13005         {0xA7709A56CCDF8A82, 0xF92E0C3537826145},  // 1e208
13006         {0x88A66076400BB691, 0x9BBCC7A142B17CCB},  // 1e209
13007         {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE},  // 1e210
13008         {0x0583F6B8C4124D43, 0xF356F7EBF83552FE},  // 1e211
13009         {0xC3727A337A8B704A, 0x98165AF37B2153DE},  // 1e212
13010         {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6},  // 1e213
13011         {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C},  // 1e214
13012         {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7},  // 1e215
13013         {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1},  // 1e216
13014         {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99},  // 1e217
13015         {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0},  // 1e218
13016         {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8},  // 1e219
13017         {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A},  // 1e220
13018         {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24},  // 1e221
13019         {0x7425A83E872C5F47, 0xB10D8E1456105DAD},  // 1e222
13020         {0xD12F124E28F77719, 0xDD50F1996B947518},  // 1e223
13021         {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F},  // 1e224
13022         {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B},  // 1e225
13023         {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A},  // 1e226
13024         {0x65ACFAEC34810A71, 0x8714A775E3E95C78},  // 1e227
13025         {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396},  // 1e228
13026         {0x1EDE48111209A050, 0xD31045A8341CA07C},  // 1e229
13027         {0x934AED0AAB460432, 0x83EA2B892091E44D},  // 1e230
13028         {0xF81DA84D5617853F, 0xA4E4B66B68B65D60},  // 1e231
13029         {0x36251260AB9D668E, 0xCE1DE40642E3F4B9},  // 1e232
13030         {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3},  // 1e233
13031         {0xB24CF65B8612F81F, 0xA1075A24E4421730},  // 1e234
13032         {0xDEE033F26797B627, 0xC94930AE1D529CFC},  // 1e235
13033         {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C},  // 1e236
13034         {0x8E1F289560EE864E, 0x9D412E0806E88AA5},  // 1e237
13035         {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E},  // 1e238
13036         {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2},  // 1e239
13037         {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765},  // 1e240
13038         {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F},  // 1e241
13039         {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E},  // 1e242
13040         {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9},  // 1e243
13041         {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F},  // 1e244
13042         {0x84C86189216DC5ED, 0xEA53DF5FD18D5513},  // 1e245
13043         {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C},  // 1e246
13044         {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77},  // 1e247
13045         {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515},  // 1e248
13046         {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D},  // 1e249
13047         {0x743E20E9EF511012, 0xB2C71D5BCA9023F8},  // 1e250
13048         {0x914DA9246B255416, 0xDF78E4B2BD342CF6},  // 1e251
13049         {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A},  // 1e252
13050         {0xA184AC2473B529B1, 0xAE9672ABA3D0C320},  // 1e253
13051         {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8},  // 1e254
13052         {0x7E2FA67C7A658892, 0x8865899617FB1871},  // 1e255
13053         {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D},  // 1e256
13054         {0x552A74227F3EA565, 0xD51EA6FA85785631},  // 1e257
13055         {0xD53A88958F87275F, 0x8533285C936B35DE},  // 1e258
13056         {0x8A892ABAF368F137, 0xA67FF273B8460356},  // 1e259
13057         {0x2D2B7569B0432D85, 0xD01FEF10A657842C},  // 1e260
13058         {0x9C3B29620E29FC73, 0x8213F56A67F6B29B},  // 1e261
13059         {0x8349F3BA91B47B8F, 0xA298F2C501F45F42},  // 1e262
13060         {0x241C70A936219A73, 0xCB3F2F7642717713},  // 1e263
13061         {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7},  // 1e264
13062         {0xF4363804324A40AA, 0x9EC95D1463E8A506},  // 1e265
13063         {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48},  // 1e266
13064         {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA},  // 1e267
13065         {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128},  // 1e268
13066         {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72},  // 1e269
13067         {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF},  // 1e270
13068         {0xD5BE0503E085D813, 0x976E41088617CA01},  // 1e271
13069         {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82},  // 1e272
13070         {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2},  // 1e273
13071         {0xCABB90E5C942B503, 0x93E1AB8252F33B45},  // 1e274
13072         {0x3D6A751F3B936243, 0xB8DA1662E7B00A17},  // 1e275
13073         {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D},  // 1e276
13074         {0x27FB2B80668B24C5, 0x906A617D450187E2},  // 1e277
13075         {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA},  // 1e278
13076         {0x5E7873F8A0396973, 0xE1A63853BBD26451},  // 1e279
13077         {0xDB0B487B6423E1E8, 0x8D07E33455637EB2},  // 1e280
13078         {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F},  // 1e281
13079         {0x7641A140CC7810FB, 0xDC5C5301C56B75F7},  // 1e282
13080         {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA},  // 1e283
13081         {0x546345FA9FBDCD44, 0xAC2820D9623BF429},  // 1e284
13082         {0xA97C177947AD4095, 0xD732290FBACAF133},  // 1e285
13083         {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0},  // 1e286
13084         {0x5C68F256BFFF5A74, 0xA81F301449EE8C70},  // 1e287
13085         {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C},  // 1e288
13086 };
13087 
13088 // wuffs_base__private_implementation__f64_powers_of_10 holds powers of 10 that
13089 // can be exactly represented by a float64 (what C calls a double).
13090 static const double wuffs_base__private_implementation__f64_powers_of_10[23] = {
13091     1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8,  1e9,  1e10, 1e11,
13092     1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
13093 };
13094 
13095 // ---------------- IEEE 754 Floating Point
13096 
13097 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f)13098 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) {
13099   uint64_t u = 0;
13100   if (sizeof(uint64_t) == sizeof(double)) {
13101     memcpy(&u, &f, sizeof(uint64_t));
13102   }
13103   uint16_t neg = ((uint16_t)((u >> 63) << 15));
13104   u &= 0x7FFFFFFFFFFFFFFF;
13105   uint64_t exp = u >> 52;
13106   uint64_t man = u & 0x000FFFFFFFFFFFFF;
13107 
13108   if (exp == 0x7FF) {
13109     if (man == 0) {  // Infinity.
13110       wuffs_base__lossy_value_u16 ret;
13111       ret.value = neg | 0x7C00;
13112       ret.lossy = false;
13113       return ret;
13114     }
13115     // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most
13116     // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9
13117     // bits of ret.value so that the 10-bit mantissa is non-zero.
13118     wuffs_base__lossy_value_u16 ret;
13119     ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42));
13120     ret.lossy = false;
13121     return ret;
13122 
13123   } else if (exp > 0x40E) {  // Truncate to the largest finite f16.
13124     wuffs_base__lossy_value_u16 ret;
13125     ret.value = neg | 0x7BFF;
13126     ret.lossy = true;
13127     return ret;
13128 
13129   } else if (exp <= 0x3E6) {  // Truncate to zero.
13130     wuffs_base__lossy_value_u16 ret;
13131     ret.value = neg;
13132     ret.lossy = (u != 0);
13133     return ret;
13134 
13135   } else if (exp <= 0x3F0) {  // Normal f64, subnormal f16.
13136     // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
13137     // 10-bit mantissa and then adjust for the exponent.
13138     man |= 0x0010000000000000;
13139     uint32_t shift = ((uint32_t)(1051 - exp));  // 1051 = 0x3F0 + 53 - 10.
13140     uint64_t shifted_man = man >> shift;
13141     wuffs_base__lossy_value_u16 ret;
13142     ret.value = neg | ((uint16_t)shifted_man);
13143     ret.lossy = (shifted_man << shift) != man;
13144     return ret;
13145   }
13146 
13147   // Normal f64, normal f16.
13148 
13149   // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits.
13150   exp = (exp - 1008) << 10;  // 1008 = 1023 - 15 = 0x3FF - 0xF.
13151 
13152   // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit
13153   // mantissa (again excluding the implicit bit). We lose some information if
13154   // any of the bottom 42 bits are non-zero.
13155   wuffs_base__lossy_value_u16 ret;
13156   ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42));
13157   ret.lossy = (man << 22) != 0;
13158   return ret;
13159 }
13160 
13161 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32  //
wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f)13162 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) {
13163   uint64_t u = 0;
13164   if (sizeof(uint64_t) == sizeof(double)) {
13165     memcpy(&u, &f, sizeof(uint64_t));
13166   }
13167   uint32_t neg = ((uint32_t)(u >> 63)) << 31;
13168   u &= 0x7FFFFFFFFFFFFFFF;
13169   uint64_t exp = u >> 52;
13170   uint64_t man = u & 0x000FFFFFFFFFFFFF;
13171 
13172   if (exp == 0x7FF) {
13173     if (man == 0) {  // Infinity.
13174       wuffs_base__lossy_value_u32 ret;
13175       ret.value = neg | 0x7F800000;
13176       ret.lossy = false;
13177       return ret;
13178     }
13179     // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most
13180     // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22
13181     // bits of ret.value so that the 23-bit mantissa is non-zero.
13182     wuffs_base__lossy_value_u32 ret;
13183     ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29));
13184     ret.lossy = false;
13185     return ret;
13186 
13187   } else if (exp > 0x47E) {  // Truncate to the largest finite f32.
13188     wuffs_base__lossy_value_u32 ret;
13189     ret.value = neg | 0x7F7FFFFF;
13190     ret.lossy = true;
13191     return ret;
13192 
13193   } else if (exp <= 0x369) {  // Truncate to zero.
13194     wuffs_base__lossy_value_u32 ret;
13195     ret.value = neg;
13196     ret.lossy = (u != 0);
13197     return ret;
13198 
13199   } else if (exp <= 0x380) {  // Normal f64, subnormal f32.
13200     // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
13201     // 23-bit mantissa and then adjust for the exponent.
13202     man |= 0x0010000000000000;
13203     uint32_t shift = ((uint32_t)(926 - exp));  // 926 = 0x380 + 53 - 23.
13204     uint64_t shifted_man = man >> shift;
13205     wuffs_base__lossy_value_u32 ret;
13206     ret.value = neg | ((uint32_t)shifted_man);
13207     ret.lossy = (shifted_man << shift) != man;
13208     return ret;
13209   }
13210 
13211   // Normal f64, normal f32.
13212 
13213   // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits.
13214   exp = (exp - 896) << 23;  // 896 = 1023 - 127 = 0x3FF - 0x7F.
13215 
13216   // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit
13217   // mantissa (again excluding the implicit bit). We lose some information if
13218   // any of the bottom 29 bits are non-zero.
13219   wuffs_base__lossy_value_u32 ret;
13220   ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29));
13221   ret.lossy = (man << 35) != 0;
13222   return ret;
13223 }
13224 
13225 // --------
13226 
13227 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE 2047
13228 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION 800
13229 
13230 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL is the largest N
13231 // such that ((10 << N) < (1 << 64)).
13232 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL 60
13233 
13234 // wuffs_base__private_implementation__high_prec_dec (abbreviated as HPD) is a
13235 // fixed precision floating point decimal number, augmented with ±infinity
13236 // values, but it cannot represent NaN (Not a Number).
13237 //
13238 // "High precision" means that the mantissa holds 800 decimal digits. 800 is
13239 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION.
13240 //
13241 // An HPD isn't for general purpose arithmetic, only for conversions to and
13242 // from IEEE 754 double-precision floating point, where the largest and
13243 // smallest positive, finite values are approximately 1.8e+308 and 4.9e-324.
13244 // HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047
13245 // bounds are further away from zero than ±(324 + 800), where 800 and 2047 is
13246 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION and
13247 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13248 //
13249 // digits[.. num_digits] are the number's digits in big-endian order. The
13250 // uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7'
13251 // is the ASCII value 0x37.
13252 //
13253 // decimal_point is the index (within digits) of the decimal point. It may be
13254 // negative or be larger than num_digits, in which case the explicit digits are
13255 // padded with implicit zeroes.
13256 //
13257 // For example, if num_digits is 3 and digits is "\x07\x08\x09":
13258 //  - A decimal_point of -2 means ".00789"
13259 //  - A decimal_point of -1 means ".0789"
13260 //  - A decimal_point of +0 means ".789"
13261 //  - A decimal_point of +1 means "7.89"
13262 //  - A decimal_point of +2 means "78.9"
13263 //  - A decimal_point of +3 means "789."
13264 //  - A decimal_point of +4 means "7890."
13265 //  - A decimal_point of +5 means "78900."
13266 //
13267 // As above, a decimal_point higher than +2047 means that the overall value is
13268 // infinity, lower than -2047 means zero.
13269 //
13270 // negative is a sign bit. An HPD can distinguish positive and negative zero.
13271 //
13272 // truncated is whether there are more than
13273 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION digits, and at
13274 // least one of those extra digits are non-zero. The existence of long-tail
13275 // digits can affect rounding.
13276 //
13277 // The "all fields are zero" value is valid, and represents the number +0.
13278 typedef struct wuffs_base__private_implementation__high_prec_dec__struct {
13279   uint32_t num_digits;
13280   int32_t decimal_point;
13281   bool negative;
13282   bool truncated;
13283   uint8_t digits[WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION];
13284 } wuffs_base__private_implementation__high_prec_dec;
13285 
13286 // wuffs_base__private_implementation__high_prec_dec__trim trims trailing
13287 // zeroes from the h->digits[.. h->num_digits] slice. They have no benefit,
13288 // since we explicitly track h->decimal_point.
13289 //
13290 // Preconditions:
13291 //  - h is non-NULL.
13292 static inline void  //
wuffs_base__private_implementation__high_prec_dec__trim(wuffs_base__private_implementation__high_prec_dec * h)13293 wuffs_base__private_implementation__high_prec_dec__trim(
13294     wuffs_base__private_implementation__high_prec_dec* h) {
13295   while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) {
13296     h->num_digits--;
13297   }
13298 }
13299 
13300 // wuffs_base__private_implementation__high_prec_dec__assign sets h to
13301 // represent the number x.
13302 //
13303 // Preconditions:
13304 //  - h is non-NULL.
13305 static void  //
wuffs_base__private_implementation__high_prec_dec__assign(wuffs_base__private_implementation__high_prec_dec * h,uint64_t x,bool negative)13306 wuffs_base__private_implementation__high_prec_dec__assign(
13307     wuffs_base__private_implementation__high_prec_dec* h,
13308     uint64_t x,
13309     bool negative) {
13310   uint32_t n = 0;
13311 
13312   // Set h->digits.
13313   if (x > 0) {
13314     // Calculate the digits, working right-to-left. After we determine n (how
13315     // many digits there are), copy from buf to h->digits.
13316     //
13317     // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to
13318     // copy a constant number of bytes than a variable number (20 instead of
13319     // n). Make buf large enough (and start writing to it from the middle) so
13320     // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)].
13321     uint8_t buf[40] = {0};
13322     uint8_t* ptr = &buf[20];
13323     do {
13324       uint64_t remaining = x / 10;
13325       x -= remaining * 10;
13326       ptr--;
13327       *ptr = (uint8_t)x;
13328       n++;
13329       x = remaining;
13330     } while (x > 0);
13331     memcpy(h->digits, ptr, 20);
13332   }
13333 
13334   // Set h's other fields.
13335   h->num_digits = n;
13336   h->decimal_point = (int32_t)n;
13337   h->negative = negative;
13338   h->truncated = false;
13339   wuffs_base__private_implementation__high_prec_dec__trim(h);
13340 }
13341 
13342 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)13343 wuffs_base__private_implementation__high_prec_dec__parse(
13344     wuffs_base__private_implementation__high_prec_dec* h,
13345     wuffs_base__slice_u8 s,
13346     uint32_t options) {
13347   if (!h) {
13348     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
13349   }
13350   h->num_digits = 0;
13351   h->decimal_point = 0;
13352   h->negative = false;
13353   h->truncated = false;
13354 
13355   uint8_t* p = s.ptr;
13356   uint8_t* q = s.ptr + s.len;
13357 
13358   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13359     for (;; p++) {
13360       if (p >= q) {
13361         return wuffs_base__make_status(wuffs_base__error__bad_argument);
13362       } else if (*p != '_') {
13363         break;
13364       }
13365     }
13366   }
13367 
13368   // Parse sign.
13369   do {
13370     if (*p == '+') {
13371       p++;
13372     } else if (*p == '-') {
13373       h->negative = true;
13374       p++;
13375     } else {
13376       break;
13377     }
13378     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13379       for (;; p++) {
13380         if (p >= q) {
13381           return wuffs_base__make_status(wuffs_base__error__bad_argument);
13382         } else if (*p != '_') {
13383           break;
13384         }
13385       }
13386     }
13387   } while (0);
13388 
13389   // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each
13390   // limb in this if-else chain:
13391   //  - "0.789"
13392   //  - "1002.789"
13393   //  - ".789"
13394   //  - Other (invalid input).
13395   uint32_t nd = 0;
13396   int32_t dp = 0;
13397   bool no_digits_before_separator = false;
13398   if (('0' == *p) &&
13399       !(options &
13400         WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) {
13401     p++;
13402     for (;; p++) {
13403       if (p >= q) {
13404         goto after_all;
13405       } else if (*p ==
13406                  ((options &
13407                    WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13408                       ? ','
13409                       : '.')) {
13410         p++;
13411         goto after_sep;
13412       } else if ((*p == 'E') || (*p == 'e')) {
13413         p++;
13414         goto after_exp;
13415       } else if ((*p != '_') ||
13416                  !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13417         return wuffs_base__make_status(wuffs_base__error__bad_argument);
13418       }
13419     }
13420 
13421   } else if (('0' <= *p) && (*p <= '9')) {
13422     if (*p == '0') {
13423       for (; (p < q) && (*p == '0'); p++) {
13424       }
13425     } else {
13426       h->digits[nd++] = (uint8_t)(*p - '0');
13427       dp = (int32_t)nd;
13428       p++;
13429     }
13430 
13431     for (;; p++) {
13432       if (p >= q) {
13433         goto after_all;
13434       } else if (('0' <= *p) && (*p <= '9')) {
13435         if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13436           h->digits[nd++] = (uint8_t)(*p - '0');
13437           dp = (int32_t)nd;
13438         } else if ('0' != *p) {
13439           // Long-tail non-zeroes set the truncated bit.
13440           h->truncated = true;
13441         }
13442       } else if (*p ==
13443                  ((options &
13444                    WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13445                       ? ','
13446                       : '.')) {
13447         p++;
13448         goto after_sep;
13449       } else if ((*p == 'E') || (*p == 'e')) {
13450         p++;
13451         goto after_exp;
13452       } else if ((*p != '_') ||
13453                  !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13454         return wuffs_base__make_status(wuffs_base__error__bad_argument);
13455       }
13456     }
13457 
13458   } else if (*p == ((options &
13459                      WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13460                         ? ','
13461                         : '.')) {
13462     p++;
13463     no_digits_before_separator = true;
13464 
13465   } else {
13466     return wuffs_base__make_status(wuffs_base__error__bad_argument);
13467   }
13468 
13469 after_sep:
13470   for (;; p++) {
13471     if (p >= q) {
13472       goto after_all;
13473     } else if ('0' == *p) {
13474       if (nd == 0) {
13475         // Track leading zeroes implicitly.
13476         dp--;
13477       } else if (nd <
13478                  WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13479         h->digits[nd++] = (uint8_t)(*p - '0');
13480       }
13481     } else if (('0' < *p) && (*p <= '9')) {
13482       if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13483         h->digits[nd++] = (uint8_t)(*p - '0');
13484       } else {
13485         // Long-tail non-zeroes set the truncated bit.
13486         h->truncated = true;
13487       }
13488     } else if ((*p == 'E') || (*p == 'e')) {
13489       p++;
13490       goto after_exp;
13491     } else if ((*p != '_') ||
13492                !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13493       return wuffs_base__make_status(wuffs_base__error__bad_argument);
13494     }
13495   }
13496 
13497 after_exp:
13498   do {
13499     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13500       for (;; p++) {
13501         if (p >= q) {
13502           return wuffs_base__make_status(wuffs_base__error__bad_argument);
13503         } else if (*p != '_') {
13504           break;
13505         }
13506       }
13507     }
13508 
13509     int32_t exp_sign = +1;
13510     if (*p == '+') {
13511       p++;
13512     } else if (*p == '-') {
13513       exp_sign = -1;
13514       p++;
13515     }
13516 
13517     int32_t exp = 0;
13518     const int32_t exp_large =
13519         WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE +
13520         WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
13521     bool saw_exp_digits = false;
13522     for (; p < q; p++) {
13523       if ((*p == '_') &&
13524           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13525         // No-op.
13526       } else if (('0' <= *p) && (*p <= '9')) {
13527         saw_exp_digits = true;
13528         if (exp < exp_large) {
13529           exp = (10 * exp) + ((int32_t)(*p - '0'));
13530         }
13531       } else {
13532         break;
13533       }
13534     }
13535     if (!saw_exp_digits) {
13536       return wuffs_base__make_status(wuffs_base__error__bad_argument);
13537     }
13538     dp += exp_sign * exp;
13539   } while (0);
13540 
13541 after_all:
13542   if (p != q) {
13543     return wuffs_base__make_status(wuffs_base__error__bad_argument);
13544   }
13545   h->num_digits = nd;
13546   if (nd == 0) {
13547     if (no_digits_before_separator) {
13548       return wuffs_base__make_status(wuffs_base__error__bad_argument);
13549     }
13550     h->decimal_point = 0;
13551   } else if (dp <
13552              -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13553     h->decimal_point =
13554         -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE - 1;
13555   } else if (dp >
13556              +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13557     h->decimal_point =
13558         +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + 1;
13559   } else {
13560     h->decimal_point = dp;
13561   }
13562   wuffs_base__private_implementation__high_prec_dec__trim(h);
13563   return wuffs_base__make_status(NULL);
13564 }
13565 
13566 // --------
13567 
13568 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
13569 // returns the number of additional decimal digits when left-shifting by shift.
13570 //
13571 // See below for preconditions.
13572 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)13573 wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
13574     wuffs_base__private_implementation__high_prec_dec* h,
13575     uint32_t shift) {
13576   // Masking with 0x3F should be unnecessary (assuming the preconditions) but
13577   // it's cheap and ensures that we don't overflow the
13578   // wuffs_base__private_implementation__hpd_left_shift array.
13579   shift &= 63;
13580 
13581   uint32_t x_a = wuffs_base__private_implementation__hpd_left_shift[shift];
13582   uint32_t x_b = wuffs_base__private_implementation__hpd_left_shift[shift + 1];
13583   uint32_t num_new_digits = x_a >> 11;
13584   uint32_t pow5_a = 0x7FF & x_a;
13585   uint32_t pow5_b = 0x7FF & x_b;
13586 
13587   const uint8_t* pow5 =
13588       &wuffs_base__private_implementation__powers_of_5[pow5_a];
13589   uint32_t i = 0;
13590   uint32_t n = pow5_b - pow5_a;
13591   for (; i < n; i++) {
13592     if (i >= h->num_digits) {
13593       return num_new_digits - 1;
13594     } else if (h->digits[i] == pow5[i]) {
13595       continue;
13596     } else if (h->digits[i] < pow5[i]) {
13597       return num_new_digits - 1;
13598     } else {
13599       return num_new_digits;
13600     }
13601   }
13602   return num_new_digits;
13603 }
13604 
13605 // --------
13606 
13607 // wuffs_base__private_implementation__high_prec_dec__rounded_integer returns
13608 // the integral (non-fractional) part of h, provided that it is 18 or fewer
13609 // decimal digits. For 19 or more digits, it returns UINT64_MAX. Note that:
13610 //  - (1 << 53) is    9007199254740992, which has 16 decimal digits.
13611 //  - (1 << 56) is   72057594037927936, which has 17 decimal digits.
13612 //  - (1 << 59) is  576460752303423488, which has 18 decimal digits.
13613 //  - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
13614 // and that IEEE 754 double precision has 52 mantissa bits.
13615 //
13616 // That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8.
13617 //
13618 // h's negative bit is ignored: rounding -8.6 returns 9.
13619 //
13620 // See below for preconditions.
13621 static uint64_t  //
wuffs_base__private_implementation__high_prec_dec__rounded_integer(wuffs_base__private_implementation__high_prec_dec * h)13622 wuffs_base__private_implementation__high_prec_dec__rounded_integer(
13623     wuffs_base__private_implementation__high_prec_dec* h) {
13624   if ((h->num_digits == 0) || (h->decimal_point < 0)) {
13625     return 0;
13626   } else if (h->decimal_point > 18) {
13627     return UINT64_MAX;
13628   }
13629 
13630   uint32_t dp = (uint32_t)(h->decimal_point);
13631   uint64_t n = 0;
13632   uint32_t i = 0;
13633   for (; i < dp; i++) {
13634     n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);
13635   }
13636 
13637   bool round_up = false;
13638   if (dp < h->num_digits) {
13639     round_up = h->digits[dp] >= 5;
13640     if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {
13641       // We are exactly halfway. If we're truncated, round up, otherwise round
13642       // to even.
13643       round_up = h->truncated ||  //
13644                  ((dp > 0) && (1 & h->digits[dp - 1]));
13645     }
13646   }
13647   if (round_up) {
13648     n++;
13649   }
13650 
13651   return n;
13652 }
13653 
13654 // wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's
13655 // number (where 'x' is 'l' or 'r' for left or right) by a small shift value.
13656 //
13657 // Preconditions:
13658 //  - h is non-NULL.
13659 //  - h->decimal_point is "not extreme".
13660 //  - shift is non-zero.
13661 //  - shift is "a small shift".
13662 //
13663 // "Not extreme" means within
13664 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13665 //
13666 // "A small shift" means not more than
13667 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
13668 //
13669 // wuffs_base__private_implementation__high_prec_dec__rounded_integer and
13670 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
13671 // have the same preconditions.
13672 //
13673 // wuffs_base__private_implementation__high_prec_dec__lshift keeps the first
13674 // two preconditions but not the last two. Its shift argument is signed and
13675 // does not need to be "small": zero is a no-op, positive means left shift and
13676 // negative means right shift.
13677 
13678 static void  //
wuffs_base__private_implementation__high_prec_dec__small_lshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)13679 wuffs_base__private_implementation__high_prec_dec__small_lshift(
13680     wuffs_base__private_implementation__high_prec_dec* h,
13681     uint32_t shift) {
13682   if (h->num_digits == 0) {
13683     return;
13684   }
13685   uint32_t num_new_digits =
13686       wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
13687           h, shift);
13688   uint32_t rx = h->num_digits - 1;                   // Read  index.
13689   uint32_t wx = h->num_digits - 1 + num_new_digits;  // Write index.
13690   uint64_t n = 0;
13691 
13692   // Repeat: pick up a digit, put down a digit, right to left.
13693   while (((int32_t)rx) >= 0) {
13694     n += ((uint64_t)(h->digits[rx])) << shift;
13695     uint64_t quo = n / 10;
13696     uint64_t rem = n - (10 * quo);
13697     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13698       h->digits[wx] = (uint8_t)rem;
13699     } else if (rem > 0) {
13700       h->truncated = true;
13701     }
13702     n = quo;
13703     wx--;
13704     rx--;
13705   }
13706 
13707   // Put down leading digits, right to left.
13708   while (n > 0) {
13709     uint64_t quo = n / 10;
13710     uint64_t rem = n - (10 * quo);
13711     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13712       h->digits[wx] = (uint8_t)rem;
13713     } else if (rem > 0) {
13714       h->truncated = true;
13715     }
13716     n = quo;
13717     wx--;
13718   }
13719 
13720   // Finish.
13721   h->num_digits += num_new_digits;
13722   if (h->num_digits >
13723       WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13724     h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
13725   }
13726   h->decimal_point += (int32_t)num_new_digits;
13727   wuffs_base__private_implementation__high_prec_dec__trim(h);
13728 }
13729 
13730 static void  //
wuffs_base__private_implementation__high_prec_dec__small_rshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)13731 wuffs_base__private_implementation__high_prec_dec__small_rshift(
13732     wuffs_base__private_implementation__high_prec_dec* h,
13733     uint32_t shift) {
13734   uint32_t rx = 0;  // Read  index.
13735   uint32_t wx = 0;  // Write index.
13736   uint64_t n = 0;
13737 
13738   // Pick up enough leading digits to cover the first shift.
13739   while ((n >> shift) == 0) {
13740     if (rx < h->num_digits) {
13741       // Read a digit.
13742       n = (10 * n) + h->digits[rx++];
13743     } else if (n == 0) {
13744       // h's number used to be zero and remains zero.
13745       return;
13746     } else {
13747       // Read sufficient implicit trailing zeroes.
13748       while ((n >> shift) == 0) {
13749         n = 10 * n;
13750         rx++;
13751       }
13752       break;
13753     }
13754   }
13755   h->decimal_point -= ((int32_t)(rx - 1));
13756   if (h->decimal_point <
13757       -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13758     // After the shift, h's number is effectively zero.
13759     h->num_digits = 0;
13760     h->decimal_point = 0;
13761     h->truncated = false;
13762     return;
13763   }
13764 
13765   // Repeat: pick up a digit, put down a digit, left to right.
13766   uint64_t mask = (((uint64_t)(1)) << shift) - 1;
13767   while (rx < h->num_digits) {
13768     uint8_t new_digit = ((uint8_t)(n >> shift));
13769     n = (10 * (n & mask)) + h->digits[rx++];
13770     h->digits[wx++] = new_digit;
13771   }
13772 
13773   // Put down trailing digits, left to right.
13774   while (n > 0) {
13775     uint8_t new_digit = ((uint8_t)(n >> shift));
13776     n = 10 * (n & mask);
13777     if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13778       h->digits[wx++] = new_digit;
13779     } else if (new_digit > 0) {
13780       h->truncated = true;
13781     }
13782   }
13783 
13784   // Finish.
13785   h->num_digits = wx;
13786   wuffs_base__private_implementation__high_prec_dec__trim(h);
13787 }
13788 
13789 static void  //
wuffs_base__private_implementation__high_prec_dec__lshift(wuffs_base__private_implementation__high_prec_dec * h,int32_t shift)13790 wuffs_base__private_implementation__high_prec_dec__lshift(
13791     wuffs_base__private_implementation__high_prec_dec* h,
13792     int32_t shift) {
13793   if (shift > 0) {
13794     while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
13795       wuffs_base__private_implementation__high_prec_dec__small_lshift(
13796           h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
13797       shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
13798     }
13799     wuffs_base__private_implementation__high_prec_dec__small_lshift(
13800         h, ((uint32_t)(+shift)));
13801   } else if (shift < 0) {
13802     while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
13803       wuffs_base__private_implementation__high_prec_dec__small_rshift(
13804           h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
13805       shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
13806     }
13807     wuffs_base__private_implementation__high_prec_dec__small_rshift(
13808         h, ((uint32_t)(-shift)));
13809   }
13810 }
13811 
13812 // --------
13813 
13814 // wuffs_base__private_implementation__high_prec_dec__round_etc rounds h's
13815 // number. For those functions that take an n argument, rounding produces at
13816 // most n digits (which is not necessarily at most n decimal places). Negative
13817 // n values are ignored, as well as any n greater than or equal to h's number
13818 // of digits. The etc__round_just_enough function implicitly chooses an n to
13819 // implement WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION.
13820 //
13821 // Preconditions:
13822 //  - h is non-NULL.
13823 //  - h->decimal_point is "not extreme".
13824 //
13825 // "Not extreme" means within
13826 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13827 
13828 static void  //
wuffs_base__private_implementation__high_prec_dec__round_down(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13829 wuffs_base__private_implementation__high_prec_dec__round_down(
13830     wuffs_base__private_implementation__high_prec_dec* h,
13831     int32_t n) {
13832   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13833     return;
13834   }
13835   h->num_digits = (uint32_t)(n);
13836   wuffs_base__private_implementation__high_prec_dec__trim(h);
13837 }
13838 
13839 static void  //
wuffs_base__private_implementation__high_prec_dec__round_up(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13840 wuffs_base__private_implementation__high_prec_dec__round_up(
13841     wuffs_base__private_implementation__high_prec_dec* h,
13842     int32_t n) {
13843   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13844     return;
13845   }
13846 
13847   for (n--; n >= 0; n--) {
13848     if (h->digits[n] < 9) {
13849       h->digits[n]++;
13850       h->num_digits = (uint32_t)(n + 1);
13851       return;
13852     }
13853   }
13854 
13855   // The number is all 9s. Change to a single 1 and adjust the decimal point.
13856   h->digits[0] = 1;
13857   h->num_digits = 1;
13858   h->decimal_point++;
13859 }
13860 
13861 static void  //
wuffs_base__private_implementation__high_prec_dec__round_nearest(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13862 wuffs_base__private_implementation__high_prec_dec__round_nearest(
13863     wuffs_base__private_implementation__high_prec_dec* h,
13864     int32_t n) {
13865   if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13866     return;
13867   }
13868   bool up = h->digits[n] >= 5;
13869   if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) {
13870     up = h->truncated ||  //
13871          ((n > 0) && ((h->digits[n - 1] & 1) != 0));
13872   }
13873 
13874   if (up) {
13875     wuffs_base__private_implementation__high_prec_dec__round_up(h, n);
13876   } else {
13877     wuffs_base__private_implementation__high_prec_dec__round_down(h, n);
13878   }
13879 }
13880 
13881 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)13882 wuffs_base__private_implementation__high_prec_dec__round_just_enough(
13883     wuffs_base__private_implementation__high_prec_dec* h,
13884     int32_t exp2,
13885     uint64_t mantissa) {
13886   // The magic numbers 52 and 53 in this function are because IEEE 754 double
13887   // precision has 52 mantissa bits.
13888   //
13889   // Let f be the floating point number represented by exp2 and mantissa (and
13890   // also the number in h): the number (mantissa * (2 ** (exp2 - 52))).
13891   //
13892   // If f is zero or a small integer, we can return early.
13893   if ((mantissa == 0) ||
13894       ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) {
13895     return;
13896   }
13897 
13898   // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52).
13899   // Subnormal numbers have the same exp2 but a smaller mantissa.
13900   static const int32_t min_incl_normal_exp2 = -1022;
13901   static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul;
13902 
13903   // Compute lower and upper bounds such that any number between them (possibly
13904   // inclusive) will round to f. First, the lower bound. Our number f is:
13905   //   ((mantissa + 0)         * (2 ** (  exp2 - 52)))
13906   //
13907   // The next lowest floating point number is:
13908   //   ((mantissa - 1)         * (2 ** (  exp2 - 52)))
13909   // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the
13910   // min_incl_normal_exp2. Either way, call it:
13911   //   ((l_mantissa)           * (2 ** (l_exp2 - 52)))
13912   //
13913   // The lower bound is halfway between them (noting that 52 became 53):
13914   //   (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53)))
13915   int32_t l_exp2 = exp2;
13916   uint64_t l_mantissa = mantissa - 1;
13917   if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) {
13918     l_exp2 = exp2 - 1;
13919     l_mantissa = (2 * mantissa) - 1;
13920   }
13921   wuffs_base__private_implementation__high_prec_dec lower;
13922   wuffs_base__private_implementation__high_prec_dec__assign(
13923       &lower, (2 * l_mantissa) + 1, false);
13924   wuffs_base__private_implementation__high_prec_dec__lshift(&lower,
13925                                                             l_exp2 - 53);
13926 
13927   // Next, the upper bound. Our number f is:
13928   //   ((mantissa + 0)       * (2 ** (exp2 - 52)))
13929   //
13930   // The next highest floating point number is:
13931   //   ((mantissa + 1)       * (2 ** (exp2 - 52)))
13932   //
13933   // The upper bound is halfway between them (noting that 52 became 53):
13934   //   (((2 * mantissa) + 1) * (2 ** (exp2 - 53)))
13935   wuffs_base__private_implementation__high_prec_dec upper;
13936   wuffs_base__private_implementation__high_prec_dec__assign(
13937       &upper, (2 * mantissa) + 1, false);
13938   wuffs_base__private_implementation__high_prec_dec__lshift(&upper, exp2 - 53);
13939 
13940   // The lower and upper bounds are possible outputs only if the original
13941   // mantissa is even, so that IEEE round-to-even would round to the original
13942   // mantissa and not its neighbors.
13943   bool inclusive = (mantissa & 1) == 0;
13944 
13945   // As we walk the digits, we want to know whether rounding up would fall
13946   // within the upper bound. This is tracked by upper_delta:
13947   //  - When -1, the digits of h and upper are the same so far.
13948   //  - When +0, we saw a difference of 1 between h and upper on a previous
13949   //    digit and subsequently only 9s for h and 0s for upper. Thus, rounding
13950   //    up may fall outside of the bound if !inclusive.
13951   //  - When +1, the difference is greater than 1 and we know that rounding up
13952   //    falls within the bound.
13953   //
13954   // This is a state machine with three states. The numerical value for each
13955   // state (-1, +0 or +1) isn't important, other than their order.
13956   int upper_delta = -1;
13957 
13958   // We can now figure out the shortest number of digits required. Walk the
13959   // digits until h has distinguished itself from lower or upper.
13960   //
13961   // The zi and zd variables are indexes and digits, for z in l (lower), h (the
13962   // number) and u (upper).
13963   //
13964   // The lower, h and upper numbers may have their decimal points at different
13965   // places. In this case, upper is the longest, so we iterate ui starting from
13966   // 0 and iterate li and hi starting from either 0 or -1.
13967   int32_t ui = 0;
13968   for (;; ui++) {
13969     // Calculate hd, the middle number's digit.
13970     int32_t hi = ui - upper.decimal_point + h->decimal_point;
13971     if (hi >= ((int32_t)(h->num_digits))) {
13972       break;
13973     }
13974     uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0;
13975 
13976     // Calculate ld, the lower bound's digit.
13977     int32_t li = ui - upper.decimal_point + lower.decimal_point;
13978     uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0;
13979 
13980     // We can round down (truncate) if lower has a different digit than h or if
13981     // lower is inclusive and is exactly the result of rounding down (i.e. we
13982     // have reached the final digit of lower).
13983     bool can_round_down =
13984         (ld != hd) ||  //
13985         (inclusive && ((li + 1) == ((int32_t)(lower.num_digits))));
13986 
13987     // Calculate ud, the upper bound's digit, and update upper_delta.
13988     uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0;
13989     if (upper_delta < 0) {
13990       if ((hd + 1) < ud) {
13991         // For example:
13992         // h     = 12345???
13993         // upper = 12347???
13994         upper_delta = +1;
13995       } else if (hd != ud) {
13996         // For example:
13997         // h     = 12345???
13998         // upper = 12346???
13999         upper_delta = +0;
14000       }
14001     } else if (upper_delta == 0) {
14002       if ((hd != 9) || (ud != 0)) {
14003         // For example:
14004         // h     = 1234598?
14005         // upper = 1234600?
14006         upper_delta = +1;
14007       }
14008     }
14009 
14010     // We can round up if upper has a different digit than h and either upper
14011     // is inclusive or upper is bigger than the result of rounding up.
14012     bool can_round_up =
14013         (upper_delta > 0) ||    //
14014         ((upper_delta == 0) &&  //
14015          (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits)))));
14016 
14017     // If we can round either way, round to nearest. If we can round only one
14018     // way, do it. If we can't round, continue the loop.
14019     if (can_round_down) {
14020       if (can_round_up) {
14021         wuffs_base__private_implementation__high_prec_dec__round_nearest(
14022             h, hi + 1);
14023         return;
14024       } else {
14025         wuffs_base__private_implementation__high_prec_dec__round_down(h,
14026                                                                       hi + 1);
14027         return;
14028       }
14029     } else {
14030       if (can_round_up) {
14031         wuffs_base__private_implementation__high_prec_dec__round_up(h, hi + 1);
14032         return;
14033       }
14034     }
14035   }
14036 }
14037 
14038 // --------
14039 
14040 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire produces
14041 // the IEEE 754 double-precision value for an exact mantissa and base-10
14042 // exponent. For example:
14043 //  - when parsing "12345.678e+02", man is 12345678 and exp10 is -1.
14044 //  - when parsing "-12", man is 12 and exp10 is 0. Processing the leading
14045 //    minus sign is the responsibility of the caller, not this function.
14046 //
14047 // On success, it returns a non-negative int64_t such that the low 63 bits hold
14048 // the 11-bit exponent and 52-bit mantissa.
14049 //
14050 // On failure, it returns a negative value.
14051 //
14052 // The algorithm is based on an original idea by Michael Eisel that was refined
14053 // by Daniel Lemire. See
14054 // https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/
14055 // and
14056 // https://nigeltao.github.io/blog/2020/eisel-lemire.html
14057 //
14058 // Preconditions:
14059 //  - man is non-zero.
14060 //  - exp10 is in the range [-307 ..= 288], the same range of the
14061 //    wuffs_base__private_implementation__powers_of_10 array.
14062 //
14063 // The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX],
14064 // approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the
14065 // range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal
14066 // (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are
14067 // approximately 2.23e–308 and 1.80e+308.
14068 static int64_t  //
wuffs_base__private_implementation__parse_number_f64_eisel_lemire(uint64_t man,int32_t exp10)14069 wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14070     uint64_t man,
14071     int32_t exp10) {
14072   // Look up the (possibly truncated) base-2 representation of (10 ** exp10).
14073   // The look-up table was constructed so that it is already normalized: the
14074   // table entry's mantissa's MSB (most significant bit) is on.
14075   const uint64_t* po10 =
14076       &wuffs_base__private_implementation__powers_of_10[exp10 + 307][0];
14077 
14078   // Normalize the man argument. The (man != 0) precondition means that a
14079   // non-zero bit exists.
14080   uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
14081   man <<= clz;
14082 
14083   // Calculate the return value's base-2 exponent. We might tweak it by ±1
14084   // later, but its initial value comes from a linear scaling of exp10,
14085   // converting from power-of-10 to power-of-2, and adjusting by clz.
14086   //
14087   // The magic constants are:
14088   //  - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because
14089   //    the look-up table uses 64-bit mantissas.
14090   //  - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough
14091   //    (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928.
14092   //  - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift.
14093   //
14094   // Equality of the linearly-scaled value and the actual power-of-2, over the
14095   // range of exp10 arguments that this function accepts, is confirmed by
14096   // script/print-mpb-powers-of-10.go
14097   uint64_t ret_exp2 =
14098       ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz);
14099 
14100   // Multiply the two mantissas. Normalization means that both mantissas are at
14101   // least (1<<63), so the 128-bit product must be at least (1<<126). The high
14102   // 64 bits of the product, x_hi, must therefore be at least (1<<62).
14103   //
14104   // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi
14105   // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore
14106   // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on.
14107   wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]);
14108   uint64_t x_hi = x.hi;
14109   uint64_t x_lo = x.lo;
14110 
14111   // Before we shift right by at least 9 bits, recall that the look-up table
14112   // entry was possibly truncated. We have so far only calculated a lower bound
14113   // for the product (man * e), where e is (10 ** exp10). The upper bound would
14114   // add a further (man * 1) to the 128-bit product, which overflows the lower
14115   // 64-bit limb if ((x_lo + man) < man).
14116   //
14117   // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right
14118   // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit
14119   // limb's low 9 bits are all on.
14120   //
14121   // For example, parsing "9999999999999999999" will take the if-true branch
14122   // here, since:
14123   //  - x_hi = 0x4563918244F3FFFF
14124   //  - x_lo = 0x8000000000000000
14125   //  - man  = 0x8AC7230489E7FFFF
14126   if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) {
14127     // Refine our calculation of (man * e). Before, our approximation of e used
14128     // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit
14129     // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e).
14130     // Now calculate y = (man * bits_64_to_127_incl_of_e).
14131     wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]);
14132     uint64_t y_hi = y.hi;
14133     uint64_t y_lo = y.lo;
14134 
14135     // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to
14136     // calculate the 192-bit product of the 64-bit man by the 128-bit e.
14137     // As we exit this if-block, we only care about the high 128 bits
14138     // (merged_hi and merged_lo) of that 192-bit product.
14139     //
14140     // For example, parsing "1.234e-45" will take the if-true branch here,
14141     // since:
14142     //  - x_hi = 0x70B7E3696DB29FFF
14143     //  - x_lo = 0xE040000000000000
14144     //  - y_hi = 0x33718BBEAB0E0D7A
14145     //  - y_lo = 0xA880000000000000
14146     uint64_t merged_hi = x_hi;
14147     uint64_t merged_lo = x_lo + y_hi;
14148     if (merged_lo < x_lo) {
14149       merged_hi++;  // Carry the overflow bit.
14150     }
14151 
14152     // The "high resolution" approximation of e is still a lower bound. Once
14153     // again, see if the upper bound is large enough to produce a different
14154     // result. This time, if it does, give up instead of reaching for an even
14155     // more precise approximation to e.
14156     //
14157     // This three-part check is similar to the two-part check that guarded the
14158     // if block that we're now in, but it has an extra term for the middle 64
14159     // bits (checking that adding 1 to merged_lo would overflow).
14160     //
14161     // For example, parsing "5.9604644775390625e-8" will take the if-true
14162     // branch here, since:
14163     //  - merged_hi = 0x7FFFFFFFFFFFFFFF
14164     //  - merged_lo = 0xFFFFFFFFFFFFFFFF
14165     //  - y_lo      = 0x4DB3FFC120988200
14166     //  - man       = 0xD3C21BCECCEDA100
14167     if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) &&
14168         (y_lo + man < man)) {
14169       return -1;
14170     }
14171 
14172     // Replace the 128-bit x with merged.
14173     x_hi = merged_hi;
14174     x_lo = merged_lo;
14175   }
14176 
14177   // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave
14178   // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the
14179   // MSB (before shifting) was on, adjust ret_exp2 for the larger shift.
14180   //
14181   // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit
14182   // number.
14183   uint64_t msb = x_hi >> 63;
14184   uint64_t ret_mantissa = x_hi >> (msb + 9);
14185   ret_exp2 -= 1 ^ msb;
14186 
14187   // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can
14188   // be tricky. If we're half-way between two exactly representable numbers
14189   // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give
14190   // up instead of trying to pick the winner.
14191   //
14192   // Technically, we could tighten the condition by changing "73" to "73 or 74,
14193   // depending on msb", but a flat "73" is simpler.
14194   //
14195   // For example, parsing "1e+23" will take the if-true branch here, since:
14196   //  - x_hi          = 0x54B40B1F852BDA00
14197   //  - ret_mantissa  = 0x002A5A058FC295ED
14198   if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) {
14199     return -1;
14200   }
14201 
14202   // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit
14203   // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether
14204   // it was on or off, shifting right by one then produces a 53-bit number. If
14205   // carrying up overflowed, shift again.
14206   ret_mantissa += ret_mantissa & 1;
14207   ret_mantissa >>= 1;
14208   // This if block is equivalent to (but benchmarks slightly faster than) the
14209   // following branchless form:
14210   //    uint64_t overflow_adjustment = ret_mantissa >> 53;
14211   //    ret_mantissa >>= overflow_adjustment;
14212   //    ret_exp2 += overflow_adjustment;
14213   //
14214   // For example, parsing "7.2057594037927933e+16" will take the if-true
14215   // branch here, since:
14216   //  - x_hi          = 0x7FFFFFFFFFFFFE80
14217   //  - ret_mantissa  = 0x0020000000000000
14218   if ((ret_mantissa >> 53) > 0) {
14219     ret_mantissa >>= 1;
14220     ret_exp2++;
14221   }
14222 
14223   // Starting with a 53-bit number, IEEE 754 double-precision normal numbers
14224   // have an implicit mantissa bit. Mask that away and keep the low 52 bits.
14225   ret_mantissa &= 0x000FFFFFFFFFFFFF;
14226 
14227   // Pack the bits and return.
14228   return ((int64_t)(ret_mantissa | (ret_exp2 << 52)));
14229 }
14230 
14231 // --------
14232 
14233 static wuffs_base__result_f64  //
wuffs_base__private_implementation__parse_number_f64_special(wuffs_base__slice_u8 s,uint32_t options)14234 wuffs_base__private_implementation__parse_number_f64_special(
14235     wuffs_base__slice_u8 s,
14236     uint32_t options) {
14237   do {
14238     if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
14239       goto fail;
14240     }
14241 
14242     uint8_t* p = s.ptr;
14243     uint8_t* q = s.ptr + s.len;
14244 
14245     for (; (p < q) && (*p == '_'); p++) {
14246     }
14247     if (p >= q) {
14248       goto fail;
14249     }
14250 
14251     // Parse sign.
14252     bool negative = false;
14253     do {
14254       if (*p == '+') {
14255         p++;
14256       } else if (*p == '-') {
14257         negative = true;
14258         p++;
14259       } else {
14260         break;
14261       }
14262       for (; (p < q) && (*p == '_'); p++) {
14263       }
14264     } while (0);
14265     if (p >= q) {
14266       goto fail;
14267     }
14268 
14269     bool nan = false;
14270     switch (p[0]) {
14271       case 'I':
14272       case 'i':
14273         if (((q - p) < 3) ||                     //
14274             ((p[1] != 'N') && (p[1] != 'n')) ||  //
14275             ((p[2] != 'F') && (p[2] != 'f'))) {
14276           goto fail;
14277         }
14278         p += 3;
14279 
14280         if ((p >= q) || (*p == '_')) {
14281           break;
14282         } else if (((q - p) < 5) ||                     //
14283                    ((p[0] != 'I') && (p[0] != 'i')) ||  //
14284                    ((p[1] != 'N') && (p[1] != 'n')) ||  //
14285                    ((p[2] != 'I') && (p[2] != 'i')) ||  //
14286                    ((p[3] != 'T') && (p[3] != 't')) ||  //
14287                    ((p[4] != 'Y') && (p[4] != 'y'))) {
14288           goto fail;
14289         }
14290         p += 5;
14291 
14292         if ((p >= q) || (*p == '_')) {
14293           break;
14294         }
14295         goto fail;
14296 
14297       case 'N':
14298       case 'n':
14299         if (((q - p) < 3) ||                     //
14300             ((p[1] != 'A') && (p[1] != 'a')) ||  //
14301             ((p[2] != 'N') && (p[2] != 'n'))) {
14302           goto fail;
14303         }
14304         p += 3;
14305 
14306         if ((p >= q) || (*p == '_')) {
14307           nan = true;
14308           break;
14309         }
14310         goto fail;
14311 
14312       default:
14313         goto fail;
14314     }
14315 
14316     // Finish.
14317     for (; (p < q) && (*p == '_'); p++) {
14318     }
14319     if (p != q) {
14320       goto fail;
14321     }
14322     wuffs_base__result_f64 ret;
14323     ret.status.repr = NULL;
14324     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14325         (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |
14326         (negative ? 0x8000000000000000 : 0));
14327     return ret;
14328   } while (0);
14329 
14330 fail:
14331   do {
14332     wuffs_base__result_f64 ret;
14333     ret.status.repr = wuffs_base__error__bad_argument;
14334     ret.value = 0;
14335     return ret;
14336   } while (0);
14337 }
14338 
14339 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)14340 wuffs_base__private_implementation__high_prec_dec__to_f64(
14341     wuffs_base__private_implementation__high_prec_dec* h,
14342     uint32_t options) {
14343   do {
14344     // powers converts decimal powers of 10 to binary powers of 2. For example,
14345     // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
14346     // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
14347     static const uint32_t num_powers = 19;
14348     static const uint8_t powers[19] = {
14349         0,  3,  6,  9,  13, 16, 19, 23, 26, 29,  //
14350         33, 36, 39, 43, 46, 49, 53, 56, 59,      //
14351     };
14352 
14353     // Handle zero and obvious extremes. The largest and smallest positive
14354     // finite f64 values are approximately 1.8e+308 and 4.9e-324.
14355     if ((h->num_digits == 0) || (h->decimal_point < -326)) {
14356       goto zero;
14357     } else if (h->decimal_point > 310) {
14358       goto infinity;
14359     }
14360 
14361     // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10)
14362     // pair from the high_prec_dec h is more correct but slower than the
14363     // approach taken in wuffs_base__parse_number_f64. The latter is optimized
14364     // for the common cases (e.g. assuming no underscores or a leading '+'
14365     // sign) rather than the full set of cases allowed by the Wuffs API.
14366     if (h->num_digits <= 19) {
14367       uint64_t man = 0;
14368       uint32_t i;
14369       for (i = 0; i < h->num_digits; i++) {
14370         man = (10 * man) + h->digits[i];
14371       }
14372       int32_t exp10 = h->decimal_point - ((int32_t)(h->num_digits));
14373       if ((man != 0) && (-307 <= exp10) && (exp10 <= 288)) {
14374         int64_t r =
14375             wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14376                 man, exp10);
14377         if (r >= 0) {
14378           wuffs_base__result_f64 ret;
14379           ret.status.repr = NULL;
14380           ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14381               ((uint64_t)r) | (((uint64_t)(h->negative)) << 63));
14382           return ret;
14383         }
14384       }
14385     }
14386 
14387     // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
14388     // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
14389     //
14390     // Scale by powers of 2 until we're in the range [½ .. 1], which gives us
14391     // our exponent (in base-2). First we shift right, possibly a little too
14392     // far, ending with a value certainly below 1 and possibly below ½...
14393     const int32_t f64_bias = -1023;
14394     int32_t exp2 = 0;
14395     while (h->decimal_point > 0) {
14396       uint32_t n = (uint32_t)(+h->decimal_point);
14397       uint32_t shift =
14398           (n < num_powers)
14399               ? powers[n]
14400               : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14401 
14402       wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
14403       if (h->decimal_point <
14404           -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
14405         goto zero;
14406       }
14407       exp2 += (int32_t)shift;
14408     }
14409     // ...then we shift left, putting us in [½ .. 1].
14410     while (h->decimal_point <= 0) {
14411       uint32_t shift;
14412       if (h->decimal_point == 0) {
14413         if (h->digits[0] >= 5) {
14414           break;
14415         }
14416         shift = (h->digits[0] < 2) ? 2 : 1;
14417       } else {
14418         uint32_t n = (uint32_t)(-h->decimal_point);
14419         shift = (n < num_powers)
14420                     ? powers[n]
14421                     : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14422       }
14423 
14424       wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
14425       if (h->decimal_point >
14426           +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
14427         goto infinity;
14428       }
14429       exp2 -= (int32_t)shift;
14430     }
14431 
14432     // We're in the range [½ .. 1] but f64 uses [1 .. 2].
14433     exp2--;
14434 
14435     // The minimum normal exponent is (f64_bias + 1).
14436     while ((f64_bias + 1) > exp2) {
14437       uint32_t n = (uint32_t)((f64_bias + 1) - exp2);
14438       if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
14439         n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14440       }
14441       wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
14442       exp2 += (int32_t)n;
14443     }
14444 
14445     // Check for overflow.
14446     if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.
14447       goto infinity;
14448     }
14449 
14450     // Extract 53 bits for the mantissa (in base-2).
14451     wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);
14452     uint64_t man2 =
14453         wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
14454 
14455     // Rounding might have added one bit. If so, shift and re-check overflow.
14456     if ((man2 >> 53) != 0) {
14457       man2 >>= 1;
14458       exp2++;
14459       if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.
14460         goto infinity;
14461       }
14462     }
14463 
14464     // Handle subnormal numbers.
14465     if ((man2 >> 52) == 0) {
14466       exp2 = f64_bias;
14467     }
14468 
14469     // Pack the bits and return.
14470     uint64_t exp2_bits =
14471         (uint64_t)((exp2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.
14472     uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.
14473                     (exp2_bits << 52) |                      //
14474                     (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).
14475 
14476     wuffs_base__result_f64 ret;
14477     ret.status.repr = NULL;
14478     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14479     return ret;
14480   } while (0);
14481 
14482 zero:
14483   do {
14484     uint64_t bits = h->negative ? 0x8000000000000000 : 0;
14485 
14486     wuffs_base__result_f64 ret;
14487     ret.status.repr = NULL;
14488     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14489     return ret;
14490   } while (0);
14491 
14492 infinity:
14493   do {
14494     if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
14495       wuffs_base__result_f64 ret;
14496       ret.status.repr = wuffs_base__error__bad_argument;
14497       ret.value = 0;
14498       return ret;
14499     }
14500 
14501     uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
14502 
14503     wuffs_base__result_f64 ret;
14504     ret.status.repr = NULL;
14505     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14506     return ret;
14507   } while (0);
14508 }
14509 
14510 static inline bool  //
wuffs_base__private_implementation__is_decimal_digit(uint8_t c)14511 wuffs_base__private_implementation__is_decimal_digit(uint8_t c) {
14512   return ('0' <= c) && (c <= '9');
14513 }
14514 
14515 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //
wuffs_base__parse_number_f64(wuffs_base__slice_u8 s,uint32_t options)14516 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {
14517   // In practice, almost all "dd.ddddE±xxx" numbers can be represented
14518   // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10
14519   // exponent, adjusting "xxx" for the position (if present) of the decimal
14520   // separator '.' or ','.
14521   //
14522   // This (u64 man, i32 exp10) data structure is superficially similar to the
14523   // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent
14524   // here is base-10, not base-2.
14525   //
14526   // If s's number fits in a (man, exp10), parse that pair with the
14527   // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with
14528   // the fallback algorithm is slower but comprehensive.
14529   //
14530   // † "Printing Floating-Point Numbers Quickly and Accurately with Integers"
14531   // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).
14532   // Florian Loitsch is also the primary contributor to
14533   // https://github.com/google/double-conversion
14534   do {
14535     // Calculating that (man, exp10) pair needs to stay within s's bounds.
14536     // Provided that s isn't extremely long, work on a NUL-terminated copy of
14537     // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx".
14538     //
14539     // As the pointer p walks the contents, it's faster to repeatedly check "is
14540     // *p a valid digit" than "is p within bounds and *p a valid digit".
14541     if (s.len >= 256) {
14542       goto fallback;
14543     }
14544     uint8_t z[256];
14545     memcpy(&z[0], s.ptr, s.len);
14546     z[s.len] = 0;
14547     const uint8_t* p = &z[0];
14548 
14549     // Look for a leading minus sign. Technically, we could also look for an
14550     // optional plus sign, but the "script/process-json-numbers.c with -p"
14551     // benchmark is noticably slower if we do. It's optional and, in practice,
14552     // usually absent. Let the fallback catch it.
14553     bool negative = (*p == '-');
14554     if (negative) {
14555       p++;
14556     }
14557 
14558     // After walking "dd.dddd", comparing p later with p now will produce the
14559     // number of "d"s and "."s.
14560     const uint8_t* const start_of_digits_ptr = p;
14561 
14562     // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0',
14563     // it must be a single '0'. If it starts with a non-zero decimal digit, it
14564     // can be a sequence of decimal digits.
14565     //
14566     // Update the man variable during the walk. It's OK if man overflows now.
14567     // We'll detect that later.
14568     uint64_t man;
14569     if (*p == '0') {
14570       man = 0;
14571       p++;
14572       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14573         goto fallback;
14574       }
14575     } else if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14576       man = ((uint8_t)(*p - '0'));
14577       p++;
14578       for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
14579         man = (10 * man) + ((uint8_t)(*p - '0'));
14580       }
14581     } else {
14582       goto fallback;
14583     }
14584 
14585     // Walk the "d"s after the optional decimal separator ('.' or ','),
14586     // updating the man and exp10 variables.
14587     int32_t exp10 = 0;
14588     if (*p ==
14589         ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14590              ? ','
14591              : '.')) {
14592       p++;
14593       const uint8_t* first_after_separator_ptr = p;
14594       if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
14595         goto fallback;
14596       }
14597       man = (10 * man) + ((uint8_t)(*p - '0'));
14598       p++;
14599       for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
14600         man = (10 * man) + ((uint8_t)(*p - '0'));
14601       }
14602       exp10 = ((int32_t)(first_after_separator_ptr - p));
14603     }
14604 
14605     // Count the number of digits:
14606     //  - for an input of "314159",  digit_count is 6.
14607     //  - for an input of "3.14159", digit_count is 7.
14608     //
14609     // This is off-by-one if there is a decimal separator. That's OK for now.
14610     // We'll correct for that later. The "script/process-json-numbers.c with
14611     // -p" benchmark is noticably slower if we try to correct for that now.
14612     uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);
14613 
14614     // Update exp10 for the optional exponent, starting with 'E' or 'e'.
14615     if ((*p | 0x20) == 'e') {
14616       p++;
14617       int32_t exp_sign = +1;
14618       if (*p == '-') {
14619         p++;
14620         exp_sign = -1;
14621       } else if (*p == '+') {
14622         p++;
14623       }
14624       if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
14625         goto fallback;
14626       }
14627       int32_t exp_num = ((uint8_t)(*p - '0'));
14628       p++;
14629       // The rest of the exp_num walking has a peculiar control flow but, once
14630       // again, the "script/process-json-numbers.c with -p" benchmark is
14631       // sensitive to alternative formulations.
14632       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14633         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14634         p++;
14635       }
14636       if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14637         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14638         p++;
14639       }
14640       while (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14641         if (exp_num > 0x1000000) {
14642           goto fallback;
14643         }
14644         exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14645         p++;
14646       }
14647       exp10 += exp_sign * exp_num;
14648     }
14649 
14650     // The Wuffs API is that the original slice has no trailing data. It also
14651     // allows underscores, which we don't catch here but the fallback should.
14652     if (p != &z[s.len]) {
14653       goto fallback;
14654     }
14655 
14656     // Check that the uint64_t typed man variable has not overflowed, based on
14657     // digit_count.
14658     //
14659     // For reference:
14660     //   - (1 << 63) is  9223372036854775808, which has 19 decimal digits.
14661     //   - (1 << 64) is 18446744073709551616, which has 20 decimal digits.
14662     //   - 19 nines,  9999999999999999999, is  0x8AC7230489E7FFFF, which has 64
14663     //     bits and 16 hexadecimal digits.
14664     //   - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67
14665     //     bits and 17 hexadecimal digits.
14666     if (digit_count > 19) {
14667       // Even if we have more than 19 pseudo-digits, it's not yet definitely an
14668       // overflow. Recall that digit_count might be off-by-one (too large) if
14669       // there's a decimal separator. It will also over-report the number of
14670       // meaningful digits if the input looks something like "0.000dddExxx".
14671       //
14672       // We adjust by the number of leading '0's and '.'s and re-compare to 19.
14673       // Once again, technically, we could skip ','s too, but that perturbs the
14674       // "script/process-json-numbers.c with -p" benchmark.
14675       const uint8_t* q = start_of_digits_ptr;
14676       for (; (*q == '0') || (*q == '.'); q++) {
14677       }
14678       digit_count -= (uint32_t)(q - start_of_digits_ptr);
14679       if (digit_count > 19) {
14680         goto fallback;
14681       }
14682     }
14683 
14684     // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
14685     // preconditions include that exp10 is in the range [-307 ..= 288].
14686     if ((exp10 < -307) || (288 < exp10)) {
14687       goto fallback;
14688     }
14689 
14690     // If both man and (10 ** exp10) are exactly representable by a double, we
14691     // don't need to run the Eisel-Lemire algorithm.
14692     if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {
14693       double d = (double)man;
14694       if (exp10 >= 0) {
14695         d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10];
14696       } else {
14697         d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];
14698       }
14699       wuffs_base__result_f64 ret;
14700       ret.status.repr = NULL;
14701       ret.value = negative ? -d : +d;
14702       return ret;
14703     }
14704 
14705     // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
14706     // preconditions include that man is non-zero. Parsing "0" should be caught
14707     // by the "If both man and (10 ** exp10)" above, but "0e99" might not.
14708     if (man == 0) {
14709       goto fallback;
14710     }
14711 
14712     // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.
14713     int64_t r =
14714         wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14715             man, exp10);
14716     if (r < 0) {
14717       goto fallback;
14718     }
14719     wuffs_base__result_f64 ret;
14720     ret.status.repr = NULL;
14721     ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14722         ((uint64_t)r) | (((uint64_t)negative) << 63));
14723     return ret;
14724   } while (0);
14725 
14726 fallback:
14727   do {
14728     wuffs_base__private_implementation__high_prec_dec h;
14729     wuffs_base__status status =
14730         wuffs_base__private_implementation__high_prec_dec__parse(&h, s,
14731                                                                  options);
14732     if (status.repr) {
14733       return wuffs_base__private_implementation__parse_number_f64_special(
14734           s, options);
14735     }
14736     return wuffs_base__private_implementation__high_prec_dec__to_f64(&h,
14737                                                                      options);
14738   } while (0);
14739 }
14740 
14741 // --------
14742 
14743 static inline size_t  //
wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,bool neg,uint32_t options)14744 wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,
14745                                                bool neg,
14746                                                uint32_t options) {
14747   if (neg) {
14748     if (dst.len < 4) {
14749       return 0;
14750     }
14751     wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D);  // '-Inf'le.
14752     return 4;
14753   }
14754 
14755   if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14756     if (dst.len < 4) {
14757       return 0;
14758     }
14759     wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B);  // '+Inf'le.
14760     return 4;
14761   }
14762 
14763   if (dst.len < 3) {
14764     return 0;
14765   }
14766   wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49);  // 'Inf'le.
14767   return 3;
14768 }
14769 
14770 static inline size_t  //
wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst)14771 wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) {
14772   if (dst.len < 3) {
14773     return 0;
14774   }
14775   wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E);  // 'NaN'le.
14776   return 3;
14777 }
14778 
14779 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)14780 wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
14781     wuffs_base__slice_u8 dst,
14782     wuffs_base__private_implementation__high_prec_dec* h,
14783     uint32_t precision,
14784     uint32_t options) {
14785   size_t n = (h->negative ||
14786               (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
14787                  ? 1
14788                  : 0;
14789   if (h->decimal_point <= 0) {
14790     n += 1;
14791   } else {
14792     n += (size_t)(h->decimal_point);
14793   }
14794   if (precision > 0) {
14795     n += precision + 1;  // +1 for the '.'.
14796   }
14797 
14798   // Don't modify dst if the formatted number won't fit.
14799   if (n > dst.len) {
14800     return 0;
14801   }
14802 
14803   // Align-left or align-right.
14804   uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
14805                      ? &dst.ptr[dst.len - n]
14806                      : &dst.ptr[0];
14807 
14808   // Leading "±".
14809   if (h->negative) {
14810     *ptr++ = '-';
14811   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14812     *ptr++ = '+';
14813   }
14814 
14815   // Integral digits.
14816   if (h->decimal_point <= 0) {
14817     *ptr++ = '0';
14818   } else {
14819     uint32_t m =
14820         wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point));
14821     uint32_t i = 0;
14822     for (; i < m; i++) {
14823       *ptr++ = (uint8_t)('0' | h->digits[i]);
14824     }
14825     for (; i < (uint32_t)(h->decimal_point); i++) {
14826       *ptr++ = '0';
14827     }
14828   }
14829 
14830   // Separator and then fractional digits.
14831   if (precision > 0) {
14832     *ptr++ =
14833         (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14834             ? ','
14835             : '.';
14836     uint32_t i = 0;
14837     for (; i < precision; i++) {
14838       uint32_t j = ((uint32_t)(h->decimal_point)) + i;
14839       *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0));
14840     }
14841   }
14842 
14843   return n;
14844 }
14845 
14846 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)14847 wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
14848     wuffs_base__slice_u8 dst,
14849     wuffs_base__private_implementation__high_prec_dec* h,
14850     uint32_t precision,
14851     uint32_t options) {
14852   int32_t exp = 0;
14853   if (h->num_digits > 0) {
14854     exp = h->decimal_point - 1;
14855   }
14856   bool negative_exp = exp < 0;
14857   if (negative_exp) {
14858     exp = -exp;
14859   }
14860 
14861   size_t n = (h->negative ||
14862               (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
14863                  ? 4
14864                  : 3;  // Mininum 3 bytes: first digit and then "e±".
14865   if (precision > 0) {
14866     n += precision + 1;  // +1 for the '.'.
14867   }
14868   n += (exp < 100) ? 2 : 3;
14869 
14870   // Don't modify dst if the formatted number won't fit.
14871   if (n > dst.len) {
14872     return 0;
14873   }
14874 
14875   // Align-left or align-right.
14876   uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
14877                      ? &dst.ptr[dst.len - n]
14878                      : &dst.ptr[0];
14879 
14880   // Leading "±".
14881   if (h->negative) {
14882     *ptr++ = '-';
14883   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14884     *ptr++ = '+';
14885   }
14886 
14887   // Integral digit.
14888   if (h->num_digits > 0) {
14889     *ptr++ = (uint8_t)('0' | h->digits[0]);
14890   } else {
14891     *ptr++ = '0';
14892   }
14893 
14894   // Separator and then fractional digits.
14895   if (precision > 0) {
14896     *ptr++ =
14897         (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14898             ? ','
14899             : '.';
14900     uint32_t i = 1;
14901     uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1);
14902     for (; i < j; i++) {
14903       *ptr++ = (uint8_t)('0' | h->digits[i]);
14904     }
14905     for (; i <= precision; i++) {
14906       *ptr++ = '0';
14907     }
14908   }
14909 
14910   // Exponent: "e±" and then 2 or 3 digits.
14911   *ptr++ = 'e';
14912   *ptr++ = negative_exp ? '-' : '+';
14913   if (exp < 10) {
14914     *ptr++ = '0';
14915     *ptr++ = (uint8_t)('0' | exp);
14916   } else if (exp < 100) {
14917     *ptr++ = (uint8_t)('0' | (exp / 10));
14918     *ptr++ = (uint8_t)('0' | (exp % 10));
14919   } else {
14920     int32_t e = exp / 100;
14921     exp -= e * 100;
14922     *ptr++ = (uint8_t)('0' | e);
14923     *ptr++ = (uint8_t)('0' | (exp / 10));
14924     *ptr++ = (uint8_t)('0' | (exp % 10));
14925   }
14926 
14927   return n;
14928 }
14929 
14930 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,double x,uint32_t precision,uint32_t options)14931 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
14932                               double x,
14933                               uint32_t precision,
14934                               uint32_t options) {
14935   // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits
14936   // with a -1023 bias) and mantissa (52 bits).
14937   uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x);
14938   bool neg = (bits >> 63) != 0;
14939   int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF;
14940   uint64_t man = bits & 0x000FFFFFFFFFFFFFul;
14941 
14942   // Apply the exponent bias and set the implicit top bit of the mantissa,
14943   // unless x is subnormal. Also take care of Inf and NaN.
14944   if (exp2 == 0x7FF) {
14945     if (man != 0) {
14946       return wuffs_base__private_implementation__render_nan(dst);
14947     }
14948     return wuffs_base__private_implementation__render_inf(dst, neg, options);
14949   } else if (exp2 == 0) {
14950     exp2 = -1022;
14951   } else {
14952     exp2 -= 1023;
14953     man |= 0x0010000000000000ul;
14954   }
14955 
14956   // Ensure that precision isn't too large.
14957   if (precision > 4095) {
14958     precision = 4095;
14959   }
14960 
14961   // Convert from the (neg, exp2, man) tuple to an HPD.
14962   wuffs_base__private_implementation__high_prec_dec h;
14963   wuffs_base__private_implementation__high_prec_dec__assign(&h, man, neg);
14964   if (h.num_digits > 0) {
14965     wuffs_base__private_implementation__high_prec_dec__lshift(
14966         &h, exp2 - 52);  // 52 mantissa bits.
14967   }
14968 
14969   // Handle the "%e" and "%f" formats.
14970   switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT |
14971                      WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) {
14972     case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT:  // The "%"f" format.
14973       if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
14974         wuffs_base__private_implementation__high_prec_dec__round_just_enough(
14975             &h, exp2, man);
14976         int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point;
14977         precision = ((uint32_t)(wuffs_base__i32__max(0, p)));
14978       } else {
14979         wuffs_base__private_implementation__high_prec_dec__round_nearest(
14980             &h, ((int32_t)precision) + h.decimal_point);
14981       }
14982       return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
14983           dst, &h, precision, options);
14984 
14985     case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT:  // The "%e" format.
14986       if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
14987         wuffs_base__private_implementation__high_prec_dec__round_just_enough(
14988             &h, exp2, man);
14989         precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0;
14990       } else {
14991         wuffs_base__private_implementation__high_prec_dec__round_nearest(
14992             &h, ((int32_t)precision) + 1);
14993       }
14994       return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
14995           dst, &h, precision, options);
14996   }
14997 
14998   // We have the "%g" format and so precision means the number of significant
14999   // digits, not the number of digits after the decimal separator. Perform
15000   // rounding and determine whether to use "%e" or "%f".
15001   int32_t e_threshold = 0;
15002   if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
15003     wuffs_base__private_implementation__high_prec_dec__round_just_enough(
15004         &h, exp2, man);
15005     precision = h.num_digits;
15006     e_threshold = 6;
15007   } else {
15008     if (precision == 0) {
15009       precision = 1;
15010     }
15011     wuffs_base__private_implementation__high_prec_dec__round_nearest(
15012         &h, ((int32_t)precision));
15013     e_threshold = ((int32_t)precision);
15014     int32_t nd = ((int32_t)(h.num_digits));
15015     if ((e_threshold > nd) && (nd >= h.decimal_point)) {
15016       e_threshold = nd;
15017     }
15018   }
15019 
15020   // Use the "%e" format if the exponent is large.
15021   int32_t e = h.decimal_point - 1;
15022   if ((e < -4) || (e_threshold <= e)) {
15023     uint32_t p = wuffs_base__u32__min(precision, h.num_digits);
15024     return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
15025         dst, &h, (p > 0) ? (p - 1) : 0, options);
15026   }
15027 
15028   // Use the "%f" format otherwise.
15029   int32_t p = ((int32_t)precision);
15030   if (p > h.decimal_point) {
15031     p = ((int32_t)(h.num_digits));
15032   }
15033   precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point)));
15034   return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
15035       dst, &h, precision, options);
15036 }
15037 
15038 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
15039         // defined(WUFFS_CONFIG__MODULE__BASE) ||
15040         // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
15041 
15042 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
15043     defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
15044 
15045 // ---------------- Integer
15046 
15047 // wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits,
15048 // and (0x80 | v) for valid digits, where v is the 4 bit value.
15049 
15050 static const uint8_t wuffs_base__parse_number__decimal_digits[256] = {
15051     // 0     1     2     3     4     5     6     7
15052     // 8     9     A     B     C     D     E     F
15053     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
15054     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
15055     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
15056     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
15057     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
15058     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
15059     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // 0x30 ..= 0x37. '0'-'7'.
15060     0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F. '8'-'9'.
15061 
15062     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x40 ..= 0x47.
15063     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
15064     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
15065     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
15066     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x60 ..= 0x67.
15067     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
15068     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
15069     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
15070 
15071     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x80 ..= 0x87.
15072     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x88 ..= 0x8F.
15073     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x90 ..= 0x97.
15074     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x98 ..= 0x9F.
15075     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA0 ..= 0xA7.
15076     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA8 ..= 0xAF.
15077     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB0 ..= 0xB7.
15078     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB8 ..= 0xBF.
15079 
15080     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC0 ..= 0xC7.
15081     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC8 ..= 0xCF.
15082     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD0 ..= 0xD7.
15083     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD8 ..= 0xDF.
15084     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE0 ..= 0xE7.
15085     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE8 ..= 0xEF.
15086     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF0 ..= 0xF7.
15087     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF8 ..= 0xFF.
15088     // 0     1     2     3     4     5     6     7
15089     // 8     9     A     B     C     D     E     F
15090 };
15091 
15092 static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = {
15093     // 0     1     2     3     4     5     6     7
15094     // 8     9     A     B     C     D     E     F
15095     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
15096     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
15097     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
15098     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
15099     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
15100     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
15101     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,  // 0x30 ..= 0x37. '0'-'7'.
15102     0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F. '8'-'9'.
15103 
15104     0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00,  // 0x40 ..= 0x47. 'A'-'F'.
15105     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
15106     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
15107     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
15108     0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00,  // 0x60 ..= 0x67. 'a'-'f'.
15109     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
15110     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
15111     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
15112 
15113     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x80 ..= 0x87.
15114     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x88 ..= 0x8F.
15115     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x90 ..= 0x97.
15116     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x98 ..= 0x9F.
15117     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA0 ..= 0xA7.
15118     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xA8 ..= 0xAF.
15119     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB0 ..= 0xB7.
15120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xB8 ..= 0xBF.
15121 
15122     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC0 ..= 0xC7.
15123     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xC8 ..= 0xCF.
15124     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD0 ..= 0xD7.
15125     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xD8 ..= 0xDF.
15126     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE0 ..= 0xE7.
15127     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xE8 ..= 0xEF.
15128     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF0 ..= 0xF7.
15129     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0xF8 ..= 0xFF.
15130     // 0     1     2     3     4     5     6     7
15131     // 8     9     A     B     C     D     E     F
15132 };
15133 
15134 static const uint8_t wuffs_base__private_implementation__encode_base16[16] = {
15135     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  // 0x00 ..= 0x07.
15136     0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,  // 0x08 ..= 0x0F.
15137 };
15138 
15139 // --------
15140 
15141 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64  //
wuffs_base__parse_number_i64(wuffs_base__slice_u8 s,uint32_t options)15142 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) {
15143   uint8_t* p = s.ptr;
15144   uint8_t* q = s.ptr + s.len;
15145 
15146   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15147     for (; (p < q) && (*p == '_'); p++) {
15148     }
15149   }
15150 
15151   bool negative = false;
15152   if (p >= q) {
15153     goto fail_bad_argument;
15154   } else if (*p == '-') {
15155     p++;
15156     negative = true;
15157   } else if (*p == '+') {
15158     p++;
15159   }
15160 
15161   do {
15162     wuffs_base__result_u64 r = wuffs_base__parse_number_u64(
15163         wuffs_base__make_slice_u8(p, (size_t)(q - p)), options);
15164     if (r.status.repr != NULL) {
15165       wuffs_base__result_i64 ret;
15166       ret.status.repr = r.status.repr;
15167       ret.value = 0;
15168       return ret;
15169     } else if (negative) {
15170       if (r.value < 0x8000000000000000) {
15171         wuffs_base__result_i64 ret;
15172         ret.status.repr = NULL;
15173         ret.value = -(int64_t)(r.value);
15174         return ret;
15175       } else if (r.value == 0x8000000000000000) {
15176         wuffs_base__result_i64 ret;
15177         ret.status.repr = NULL;
15178         ret.value = INT64_MIN;
15179         return ret;
15180       }
15181       goto fail_out_of_bounds;
15182     } else if (r.value > 0x7FFFFFFFFFFFFFFF) {
15183       goto fail_out_of_bounds;
15184     } else {
15185       wuffs_base__result_i64 ret;
15186       ret.status.repr = NULL;
15187       ret.value = +(int64_t)(r.value);
15188       return ret;
15189     }
15190   } while (0);
15191 
15192 fail_bad_argument:
15193   do {
15194     wuffs_base__result_i64 ret;
15195     ret.status.repr = wuffs_base__error__bad_argument;
15196     ret.value = 0;
15197     return ret;
15198   } while (0);
15199 
15200 fail_out_of_bounds:
15201   do {
15202     wuffs_base__result_i64 ret;
15203     ret.status.repr = wuffs_base__error__out_of_bounds;
15204     ret.value = 0;
15205     return ret;
15206   } while (0);
15207 }
15208 
15209 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64  //
wuffs_base__parse_number_u64(wuffs_base__slice_u8 s,uint32_t options)15210 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) {
15211   uint8_t* p = s.ptr;
15212   uint8_t* q = s.ptr + s.len;
15213 
15214   if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15215     for (; (p < q) && (*p == '_'); p++) {
15216     }
15217   }
15218 
15219   if (p >= q) {
15220     goto fail_bad_argument;
15221 
15222   } else if (*p == '0') {
15223     p++;
15224     if (p >= q) {
15225       goto ok_zero;
15226     }
15227     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15228       if (*p == '_') {
15229         p++;
15230         for (; p < q; p++) {
15231           if (*p != '_') {
15232             if (options &
15233                 WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
15234               goto decimal;
15235             }
15236             goto fail_bad_argument;
15237           }
15238         }
15239         goto ok_zero;
15240       }
15241     }
15242 
15243     if ((*p == 'x') || (*p == 'X')) {
15244       p++;
15245       if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15246         for (; (p < q) && (*p == '_'); p++) {
15247         }
15248       }
15249       if (p < q) {
15250         goto hexadecimal;
15251       }
15252 
15253     } else if ((*p == 'd') || (*p == 'D')) {
15254       p++;
15255       if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15256         for (; (p < q) && (*p == '_'); p++) {
15257         }
15258       }
15259       if (p < q) {
15260         goto decimal;
15261       }
15262     }
15263 
15264     if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
15265       goto decimal;
15266     }
15267     goto fail_bad_argument;
15268   }
15269 
15270 decimal:
15271   do {
15272     uint64_t v = wuffs_base__parse_number__decimal_digits[*p++];
15273     if (v == 0) {
15274       goto fail_bad_argument;
15275     }
15276     v &= 0x0F;
15277 
15278     // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1).
15279     const uint64_t max10 = 1844674407370955161u;
15280     const uint8_t max1 = 5;
15281 
15282     for (; p < q; p++) {
15283       if ((*p == '_') &&
15284           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
15285         continue;
15286       }
15287       uint8_t digit = wuffs_base__parse_number__decimal_digits[*p];
15288       if (digit == 0) {
15289         goto fail_bad_argument;
15290       }
15291       digit &= 0x0F;
15292       if ((v > max10) || ((v == max10) && (digit > max1))) {
15293         goto fail_out_of_bounds;
15294       }
15295       v = (10 * v) + ((uint64_t)(digit));
15296     }
15297 
15298     wuffs_base__result_u64 ret;
15299     ret.status.repr = NULL;
15300     ret.value = v;
15301     return ret;
15302   } while (0);
15303 
15304 hexadecimal:
15305   do {
15306     uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++];
15307     if (v == 0) {
15308       goto fail_bad_argument;
15309     }
15310     v &= 0x0F;
15311 
15312     for (; p < q; p++) {
15313       if ((*p == '_') &&
15314           (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
15315         continue;
15316       }
15317       uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p];
15318       if (digit == 0) {
15319         goto fail_bad_argument;
15320       }
15321       digit &= 0x0F;
15322       if ((v >> 60) != 0) {
15323         goto fail_out_of_bounds;
15324       }
15325       v = (v << 4) | ((uint64_t)(digit));
15326     }
15327 
15328     wuffs_base__result_u64 ret;
15329     ret.status.repr = NULL;
15330     ret.value = v;
15331     return ret;
15332   } while (0);
15333 
15334 ok_zero:
15335   do {
15336     wuffs_base__result_u64 ret;
15337     ret.status.repr = NULL;
15338     ret.value = 0;
15339     return ret;
15340   } while (0);
15341 
15342 fail_bad_argument:
15343   do {
15344     wuffs_base__result_u64 ret;
15345     ret.status.repr = wuffs_base__error__bad_argument;
15346     ret.value = 0;
15347     return ret;
15348   } while (0);
15349 
15350 fail_out_of_bounds:
15351   do {
15352     wuffs_base__result_u64 ret;
15353     ret.status.repr = wuffs_base__error__out_of_bounds;
15354     ret.value = 0;
15355     return ret;
15356   } while (0);
15357 }
15358 
15359 // --------
15360 
15361 // wuffs_base__render_number__first_hundred contains the decimal encodings of
15362 // the first one hundred numbers [0 ..= 99].
15363 static const uint8_t wuffs_base__render_number__first_hundred[200] = {
15364     '0', '0', '0', '1', '0', '2', '0', '3', '0', '4',  //
15365     '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',  //
15366     '1', '0', '1', '1', '1', '2', '1', '3', '1', '4',  //
15367     '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',  //
15368     '2', '0', '2', '1', '2', '2', '2', '3', '2', '4',  //
15369     '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',  //
15370     '3', '0', '3', '1', '3', '2', '3', '3', '3', '4',  //
15371     '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',  //
15372     '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',  //
15373     '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',  //
15374     '5', '0', '5', '1', '5', '2', '5', '3', '5', '4',  //
15375     '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',  //
15376     '6', '0', '6', '1', '6', '2', '6', '3', '6', '4',  //
15377     '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',  //
15378     '7', '0', '7', '1', '7', '2', '7', '3', '7', '4',  //
15379     '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',  //
15380     '8', '0', '8', '1', '8', '2', '8', '3', '8', '4',  //
15381     '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',  //
15382     '9', '0', '9', '1', '9', '2', '9', '3', '9', '4',  //
15383     '9', '5', '9', '6', '9', '7', '9', '8', '9', '9',  //
15384 };
15385 
15386 static size_t  //
wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options,bool neg)15387 wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,
15388                                                       uint64_t x,
15389                                                       uint32_t options,
15390                                                       bool neg) {
15391   uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL];
15392   uint8_t* ptr = &buf[0] + sizeof(buf);
15393 
15394   while (x >= 100) {
15395     size_t index = ((size_t)((x % 100) * 2));
15396     x /= 100;
15397     uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
15398     uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
15399     ptr -= 2;
15400     ptr[0] = s0;
15401     ptr[1] = s1;
15402   }
15403 
15404   if (x < 10) {
15405     ptr -= 1;
15406     ptr[0] = (uint8_t)('0' + x);
15407   } else {
15408     size_t index = ((size_t)(x * 2));
15409     uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
15410     uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
15411     ptr -= 2;
15412     ptr[0] = s0;
15413     ptr[1] = s1;
15414   }
15415 
15416   if (neg) {
15417     ptr -= 1;
15418     ptr[0] = '-';
15419   } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
15420     ptr -= 1;
15421     ptr[0] = '+';
15422   }
15423 
15424   size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0]));
15425   if (n > dst.len) {
15426     return 0;
15427   }
15428   memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
15429                         ? (dst.len - n)
15430                         : 0),
15431          ptr, n);
15432   return n;
15433 }
15434 
15435 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,int64_t x,uint32_t options)15436 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
15437                               int64_t x,
15438                               uint32_t options) {
15439   uint64_t u = (uint64_t)x;
15440   bool neg = x < 0;
15441   if (neg) {
15442     u = 1 + ~u;
15443   }
15444   return wuffs_base__private_implementation__render_number_u64(dst, u, options,
15445                                                                neg);
15446 }
15447 
15448 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options)15449 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
15450                               uint64_t x,
15451                               uint32_t options) {
15452   return wuffs_base__private_implementation__render_number_u64(dst, x, options,
15453                                                                false);
15454 }
15455 
15456 // ---------------- Base-16
15457 
15458 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)15459 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
15460                              wuffs_base__slice_u8 src,
15461                              bool src_closed,
15462                              uint32_t options) {
15463   wuffs_base__transform__output o;
15464   size_t src_len2 = src.len / 2;
15465   size_t len;
15466   if (dst.len < src_len2) {
15467     len = dst.len;
15468     o.status.repr = wuffs_base__suspension__short_write;
15469   } else {
15470     len = src_len2;
15471     if (!src_closed) {
15472       o.status.repr = wuffs_base__suspension__short_read;
15473     } else if (src.len & 1) {
15474       o.status.repr = wuffs_base__error__bad_data;
15475     } else {
15476       o.status.repr = NULL;
15477     }
15478   }
15479 
15480   uint8_t* d = dst.ptr;
15481   uint8_t* s = src.ptr;
15482   size_t n = len;
15483 
15484   while (n--) {
15485     *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
15486                    (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F));
15487     d += 1;
15488     s += 2;
15489   }
15490 
15491   o.num_dst = len;
15492   o.num_src = len * 2;
15493   return o;
15494 }
15495 
15496 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)15497 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
15498                              wuffs_base__slice_u8 src,
15499                              bool src_closed,
15500                              uint32_t options) {
15501   wuffs_base__transform__output o;
15502   size_t src_len4 = src.len / 4;
15503   size_t len = dst.len < src_len4 ? dst.len : src_len4;
15504   if (dst.len < src_len4) {
15505     len = dst.len;
15506     o.status.repr = wuffs_base__suspension__short_write;
15507   } else {
15508     len = src_len4;
15509     if (!src_closed) {
15510       o.status.repr = wuffs_base__suspension__short_read;
15511     } else if (src.len & 1) {
15512       o.status.repr = wuffs_base__error__bad_data;
15513     } else {
15514       o.status.repr = NULL;
15515     }
15516   }
15517 
15518   uint8_t* d = dst.ptr;
15519   uint8_t* s = src.ptr;
15520   size_t n = len;
15521 
15522   while (n--) {
15523     *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
15524                    (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F));
15525     d += 1;
15526     s += 4;
15527   }
15528 
15529   o.num_dst = len;
15530   o.num_src = len * 4;
15531   return o;
15532 }
15533 
15534 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)15535 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
15536                              wuffs_base__slice_u8 src,
15537                              bool src_closed,
15538                              uint32_t options) {
15539   wuffs_base__transform__output o;
15540   size_t dst_len2 = dst.len / 2;
15541   size_t len;
15542   if (dst_len2 < src.len) {
15543     len = dst_len2;
15544     o.status.repr = wuffs_base__suspension__short_write;
15545   } else {
15546     len = src.len;
15547     if (!src_closed) {
15548       o.status.repr = wuffs_base__suspension__short_read;
15549     } else {
15550       o.status.repr = NULL;
15551     }
15552   }
15553 
15554   uint8_t* d = dst.ptr;
15555   uint8_t* s = src.ptr;
15556   size_t n = len;
15557 
15558   while (n--) {
15559     uint8_t c = *s;
15560     d[0] = wuffs_base__private_implementation__encode_base16[c >> 4];
15561     d[1] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
15562     d += 2;
15563     s += 1;
15564   }
15565 
15566   o.num_dst = len * 2;
15567   o.num_src = len;
15568   return o;
15569 }
15570 
15571 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)15572 wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
15573                              wuffs_base__slice_u8 src,
15574                              bool src_closed,
15575                              uint32_t options) {
15576   wuffs_base__transform__output o;
15577   size_t dst_len4 = dst.len / 4;
15578   size_t len;
15579   if (dst_len4 < src.len) {
15580     len = dst_len4;
15581     o.status.repr = wuffs_base__suspension__short_write;
15582   } else {
15583     len = src.len;
15584     if (!src_closed) {
15585       o.status.repr = wuffs_base__suspension__short_read;
15586     } else {
15587       o.status.repr = NULL;
15588     }
15589   }
15590 
15591   uint8_t* d = dst.ptr;
15592   uint8_t* s = src.ptr;
15593   size_t n = len;
15594 
15595   while (n--) {
15596     uint8_t c = *s;
15597     d[0] = '\\';
15598     d[1] = 'x';
15599     d[2] = wuffs_base__private_implementation__encode_base16[c >> 4];
15600     d[3] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
15601     d += 4;
15602     s += 1;
15603   }
15604 
15605   o.num_dst = len * 4;
15606   o.num_src = len;
15607   return o;
15608 }
15609 
15610 // ---------------- Base-64
15611 
15612 // The two base-64 alphabets, std and url, differ only in the last two codes.
15613 //  - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
15614 //  - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
15615 
15616 static const uint8_t wuffs_base__base_64__decode_std[256] = {
15617     // 0     1     2     3     4     5     6     7
15618     // 8     9     A     B     C     D     E     F
15619     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x00 ..= 0x07.
15620     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x08 ..= 0x0F.
15621     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x10 ..= 0x17.
15622     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x18 ..= 0x1F.
15623     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x20 ..= 0x27.
15624     0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F,  // 0x28 ..= 0x2F.
15625     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  // 0x30 ..= 0x37.
15626     0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x38 ..= 0x3F.
15627 
15628     0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // 0x40 ..= 0x47.
15629     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  // 0x48 ..= 0x4F.
15630     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  // 0x50 ..= 0x57.
15631     0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x58 ..= 0x5F.
15632     0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  // 0x60 ..= 0x67.
15633     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,  // 0x68 ..= 0x6F.
15634     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,  // 0x70 ..= 0x77.
15635     0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x78 ..= 0x7F.
15636 
15637     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x80 ..= 0x87.
15638     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x88 ..= 0x8F.
15639     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x90 ..= 0x97.
15640     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x98 ..= 0x9F.
15641     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA0 ..= 0xA7.
15642     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA8 ..= 0xAF.
15643     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB0 ..= 0xB7.
15644     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB8 ..= 0xBF.
15645 
15646     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC0 ..= 0xC7.
15647     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC8 ..= 0xCF.
15648     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD0 ..= 0xD7.
15649     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD8 ..= 0xDF.
15650     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE0 ..= 0xE7.
15651     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE8 ..= 0xEF.
15652     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
15653     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
15654     // 0     1     2     3     4     5     6     7
15655     // 8     9     A     B     C     D     E     F
15656 };
15657 
15658 static const uint8_t wuffs_base__base_64__decode_url[256] = {
15659     // 0     1     2     3     4     5     6     7
15660     // 8     9     A     B     C     D     E     F
15661     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x00 ..= 0x07.
15662     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x08 ..= 0x0F.
15663     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x10 ..= 0x17.
15664     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x18 ..= 0x1F.
15665     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x20 ..= 0x27.
15666     0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80,  // 0x28 ..= 0x2F.
15667     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,  // 0x30 ..= 0x37.
15668     0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x38 ..= 0x3F.
15669 
15670     0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,  // 0x40 ..= 0x47.
15671     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  // 0x48 ..= 0x4F.
15672     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,  // 0x50 ..= 0x57.
15673     0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F,  // 0x58 ..= 0x5F.
15674     0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  // 0x60 ..= 0x67.
15675     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,  // 0x68 ..= 0x6F.
15676     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,  // 0x70 ..= 0x77.
15677     0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x78 ..= 0x7F.
15678 
15679     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x80 ..= 0x87.
15680     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x88 ..= 0x8F.
15681     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x90 ..= 0x97.
15682     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0x98 ..= 0x9F.
15683     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA0 ..= 0xA7.
15684     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xA8 ..= 0xAF.
15685     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB0 ..= 0xB7.
15686     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xB8 ..= 0xBF.
15687 
15688     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC0 ..= 0xC7.
15689     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xC8 ..= 0xCF.
15690     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD0 ..= 0xD7.
15691     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xD8 ..= 0xDF.
15692     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE0 ..= 0xE7.
15693     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xE8 ..= 0xEF.
15694     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
15695     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
15696     // 0     1     2     3     4     5     6     7
15697     // 8     9     A     B     C     D     E     F
15698 };
15699 
15700 static const uint8_t wuffs_base__base_64__encode_std[64] = {
15701     // 0     1     2     3     4     5     6     7
15702     // 8     9     A     B     C     D     E     F
15703     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  // 0x00 ..= 0x07.
15704     0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,  // 0x08 ..= 0x0F.
15705     0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  // 0x10 ..= 0x17.
15706     0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,  // 0x18 ..= 0x1F.
15707     0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,  // 0x20 ..= 0x27.
15708     0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,  // 0x28 ..= 0x2F.
15709     0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,  // 0x30 ..= 0x37.
15710     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F,  // 0x38 ..= 0x3F.
15711 };
15712 
15713 static const uint8_t wuffs_base__base_64__encode_url[64] = {
15714     // 0     1     2     3     4     5     6     7
15715     // 8     9     A     B     C     D     E     F
15716     0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,  // 0x00 ..= 0x07.
15717     0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,  // 0x08 ..= 0x0F.
15718     0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  // 0x10 ..= 0x17.
15719     0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,  // 0x18 ..= 0x1F.
15720     0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,  // 0x20 ..= 0x27.
15721     0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,  // 0x28 ..= 0x2F.
15722     0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,  // 0x30 ..= 0x37.
15723     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F,  // 0x38 ..= 0x3F.
15724 };
15725 
15726 // --------
15727 
15728 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)15729 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
15730                             wuffs_base__slice_u8 src,
15731                             bool src_closed,
15732                             uint32_t options) {
15733   const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
15734                                 ? wuffs_base__base_64__decode_url
15735                                 : wuffs_base__base_64__decode_std;
15736   wuffs_base__transform__output o;
15737   uint8_t* d_ptr = dst.ptr;
15738   size_t d_len = dst.len;
15739   const uint8_t* s_ptr = src.ptr;
15740   size_t s_len = src.len;
15741   bool pad = false;
15742 
15743   while (s_len >= 4) {
15744     uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
15745     uint32_t s0 = alphabet[0xFF & (s >> 0)];
15746     uint32_t s1 = alphabet[0xFF & (s >> 8)];
15747     uint32_t s2 = alphabet[0xFF & (s >> 16)];
15748     uint32_t s3 = alphabet[0xFF & (s >> 24)];
15749 
15750     if (((s0 | s1 | s2 | s3) & 0xC0) != 0) {
15751       if (s_len > 4) {
15752         o.status.repr = wuffs_base__error__bad_data;
15753         goto done;
15754       } else if (!src_closed) {
15755         o.status.repr = wuffs_base__suspension__short_read;
15756         goto done;
15757       } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) &&
15758                  (s_ptr[3] == '=')) {
15759         pad = true;
15760         if (s_ptr[2] == '=') {
15761           goto src2;
15762         }
15763         goto src3;
15764       }
15765       o.status.repr = wuffs_base__error__bad_data;
15766       goto done;
15767     }
15768 
15769     if (d_len < 3) {
15770       o.status.repr = wuffs_base__suspension__short_write;
15771       goto done;
15772     }
15773 
15774     s_ptr += 4;
15775     s_len -= 4;
15776     s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0);
15777     *d_ptr++ = (uint8_t)(s >> 16);
15778     *d_ptr++ = (uint8_t)(s >> 8);
15779     *d_ptr++ = (uint8_t)(s >> 0);
15780     d_len -= 3;
15781   }
15782 
15783   if (!src_closed) {
15784     o.status.repr = wuffs_base__suspension__short_read;
15785     goto done;
15786   }
15787 
15788   if (s_len == 0) {
15789     o.status.repr = NULL;
15790     goto done;
15791   } else if (s_len == 1) {
15792     o.status.repr = wuffs_base__error__bad_data;
15793     goto done;
15794   } else if (s_len == 2) {
15795     goto src2;
15796   }
15797 
15798 src3:
15799   do {
15800     uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
15801     uint32_t s0 = alphabet[0xFF & (s >> 0)];
15802     uint32_t s1 = alphabet[0xFF & (s >> 8)];
15803     uint32_t s2 = alphabet[0xFF & (s >> 16)];
15804     if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) {
15805       o.status.repr = wuffs_base__error__bad_data;
15806       goto done;
15807     }
15808     if (d_len < 2) {
15809       o.status.repr = wuffs_base__suspension__short_write;
15810       goto done;
15811     }
15812     s_ptr += pad ? 4 : 3;
15813     s = (s0 << 18) | (s1 << 12) | (s2 << 6);
15814     *d_ptr++ = (uint8_t)(s >> 16);
15815     *d_ptr++ = (uint8_t)(s >> 8);
15816     o.status.repr = NULL;
15817     goto done;
15818   } while (0);
15819 
15820 src2:
15821   do {
15822     uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
15823     uint32_t s0 = alphabet[0xFF & (s >> 0)];
15824     uint32_t s1 = alphabet[0xFF & (s >> 8)];
15825     if ((s0 & 0xC0) || (s1 & 0xCF)) {
15826       o.status.repr = wuffs_base__error__bad_data;
15827       goto done;
15828     }
15829     if (d_len < 1) {
15830       o.status.repr = wuffs_base__suspension__short_write;
15831       goto done;
15832     }
15833     s_ptr += pad ? 4 : 2;
15834     s = (s0 << 18) | (s1 << 12);
15835     *d_ptr++ = (uint8_t)(s >> 16);
15836     o.status.repr = NULL;
15837     goto done;
15838   } while (0);
15839 
15840 done:
15841   o.num_dst = (size_t)(d_ptr - dst.ptr);
15842   o.num_src = (size_t)(s_ptr - src.ptr);
15843   return o;
15844 }
15845 
15846 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)15847 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
15848                             wuffs_base__slice_u8 src,
15849                             bool src_closed,
15850                             uint32_t options) {
15851   const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
15852                                 ? wuffs_base__base_64__encode_url
15853                                 : wuffs_base__base_64__encode_std;
15854   wuffs_base__transform__output o;
15855   uint8_t* d_ptr = dst.ptr;
15856   size_t d_len = dst.len;
15857   const uint8_t* s_ptr = src.ptr;
15858   size_t s_len = src.len;
15859 
15860   do {
15861     while (s_len >= 3) {
15862       if (d_len < 4) {
15863         o.status.repr = wuffs_base__suspension__short_write;
15864         goto done;
15865       }
15866       uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr);
15867       s_ptr += 3;
15868       s_len -= 3;
15869       *d_ptr++ = alphabet[0x3F & (s >> 18)];
15870       *d_ptr++ = alphabet[0x3F & (s >> 12)];
15871       *d_ptr++ = alphabet[0x3F & (s >> 6)];
15872       *d_ptr++ = alphabet[0x3F & (s >> 0)];
15873       d_len -= 4;
15874     }
15875 
15876     if (!src_closed) {
15877       o.status.repr = wuffs_base__suspension__short_read;
15878       goto done;
15879     }
15880 
15881     if (s_len == 2) {
15882       if (d_len <
15883           ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) {
15884         o.status.repr = wuffs_base__suspension__short_write;
15885         goto done;
15886       }
15887       uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr)))
15888                    << 8;
15889       s_ptr += 2;
15890       *d_ptr++ = alphabet[0x3F & (s >> 18)];
15891       *d_ptr++ = alphabet[0x3F & (s >> 12)];
15892       *d_ptr++ = alphabet[0x3F & (s >> 6)];
15893       if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
15894         *d_ptr++ = '=';
15895       }
15896       o.status.repr = NULL;
15897       goto done;
15898 
15899     } else if (s_len == 1) {
15900       if (d_len <
15901           ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) {
15902         o.status.repr = wuffs_base__suspension__short_write;
15903         goto done;
15904       }
15905       uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr)))
15906                    << 16;
15907       s_ptr += 1;
15908       *d_ptr++ = alphabet[0x3F & (s >> 18)];
15909       *d_ptr++ = alphabet[0x3F & (s >> 12)];
15910       if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
15911         *d_ptr++ = '=';
15912         *d_ptr++ = '=';
15913       }
15914       o.status.repr = NULL;
15915       goto done;
15916 
15917     } else {
15918       o.status.repr = NULL;
15919       goto done;
15920     }
15921   } while (0);
15922 
15923 done:
15924   o.num_dst = (size_t)(d_ptr - dst.ptr);
15925   o.num_src = (size_t)(s_ptr - src.ptr);
15926   return o;
15927 }
15928 
15929 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
15930         // defined(WUFFS_CONFIG__MODULE__BASE) ||
15931         // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
15932 
15933 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
15934     defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
15935 
15936 // ---------------- Magic Numbers
15937 
15938 // ICO doesn't start with a magic identifier. Instead, see if the opening bytes
15939 // are plausibly ICO.
15940 //
15941 // Callers should have already verified that (prefix_data.len >= 2) and the
15942 // first two bytes are 0x00.
15943 //
15944 // See:
15945 //  - https://docs.fileformat.com/image/ico/
15946 static int32_t  //
wuffs_base__magic_number_guess_fourcc__maybe_ico(wuffs_base__slice_u8 prefix_data,bool prefix_closed)15947 wuffs_base__magic_number_guess_fourcc__maybe_ico(
15948     wuffs_base__slice_u8 prefix_data,
15949     bool prefix_closed) {
15950   // Allow-list for the Image Type field.
15951   if (prefix_data.len < 4) {
15952     return prefix_closed ? 0 : -1;
15953   } else if (prefix_data.ptr[3] != 0) {
15954     return 0;
15955   }
15956   switch (prefix_data.ptr[2]) {
15957     case 0x01:  // ICO
15958     case 0x02:  // CUR
15959       break;
15960     default:
15961       return 0;
15962   }
15963 
15964   // The Number Of Images should be positive.
15965   if (prefix_data.len < 6) {
15966     return prefix_closed ? 0 : -1;
15967   } else if ((prefix_data.ptr[4] == 0) && (prefix_data.ptr[5] == 0)) {
15968     return 0;
15969   }
15970 
15971   // The first ICONDIRENTRY's fourth byte should be zero.
15972   if (prefix_data.len < 10) {
15973     return prefix_closed ? 0 : -1;
15974   } else if (prefix_data.ptr[9] != 0) {
15975     return 0;
15976   }
15977 
15978   // TODO: have a separate FourCC for CUR?
15979   return 0x49434F20;  // 'ICO 'be
15980 }
15981 
15982 // TGA doesn't start with a magic identifier. Instead, see if the opening bytes
15983 // are plausibly TGA.
15984 //
15985 // Callers should have already verified that (prefix_data.len >= 2) and the
15986 // second byte (prefix_data.ptr[1], the Color Map Type byte), is either 0x00 or
15987 // 0x01.
15988 //
15989 // See:
15990 //  - https://docs.fileformat.com/image/tga/
15991 //  - https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
15992 static int32_t  //
wuffs_base__magic_number_guess_fourcc__maybe_tga(wuffs_base__slice_u8 prefix_data,bool prefix_closed)15993 wuffs_base__magic_number_guess_fourcc__maybe_tga(
15994     wuffs_base__slice_u8 prefix_data,
15995     bool prefix_closed) {
15996   // Allow-list for the Image Type field.
15997   if (prefix_data.len < 3) {
15998     return prefix_closed ? 0 : -1;
15999   }
16000   switch (prefix_data.ptr[2]) {
16001     case 0x01:
16002     case 0x02:
16003     case 0x03:
16004     case 0x09:
16005     case 0x0A:
16006     case 0x0B:
16007       break;
16008     default:
16009       // TODO: 0x20 and 0x21 are invalid, according to the spec, but are
16010       // apparently unofficial extensions.
16011       return 0;
16012   }
16013 
16014   // Allow-list for the Color Map Entry Size field (if the Color Map Type field
16015   // is non-zero) or else all the Color Map fields should be zero.
16016   if (prefix_data.len < 8) {
16017     return prefix_closed ? 0 : -1;
16018   } else if (prefix_data.ptr[1] != 0x00) {
16019     switch (prefix_data.ptr[7]) {
16020       case 0x0F:
16021       case 0x10:
16022       case 0x18:
16023       case 0x20:
16024         break;
16025       default:
16026         return 0;
16027     }
16028   } else if ((prefix_data.ptr[3] | prefix_data.ptr[4] | prefix_data.ptr[5] |
16029               prefix_data.ptr[6] | prefix_data.ptr[7]) != 0x00) {
16030     return 0;
16031   }
16032 
16033   // Allow-list for the Pixel Depth field.
16034   if (prefix_data.len < 17) {
16035     return prefix_closed ? 0 : -1;
16036   }
16037   switch (prefix_data.ptr[16]) {
16038     case 0x01:
16039     case 0x08:
16040     case 0x0F:
16041     case 0x10:
16042     case 0x18:
16043     case 0x20:
16044       break;
16045     default:
16046       return 0;
16047   }
16048 
16049   return 0x54474120;  // 'TGA 'be
16050 }
16051 
16052 WUFFS_BASE__MAYBE_STATIC int32_t  //
wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,bool prefix_closed)16053 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
16054                                       bool prefix_closed) {
16055   // This is similar to (but different from):
16056   //  - the magic/Magdir tables under https://github.com/file/file
16057   //  - the MIME Sniffing algorithm at https://mimesniff.spec.whatwg.org/
16058 
16059   // table holds the 'magic numbers' (which are actually variable length
16060   // strings). The strings may contain NUL bytes, so the "const char* magic"
16061   // value starts with the length-minus-1 of the 'magic number'.
16062   //
16063   // Keep it sorted by magic[1], then magic[0] descending and finally by
16064   // magic[2:]. When multiple entries match, the longest one wins.
16065   //
16066   // The fourcc field might be negated, in which case there's further
16067   // specialization (see § below).
16068   static struct {
16069     int32_t fourcc;
16070     const char* magic;
16071   } table[] = {
16072       {-0x30302020, "\x01\x00\x00"},          // '00  'be
16073       {+0x424D5020, "\x01\x42\x4D"},          // BMP
16074       {+0x47494620, "\x03\x47\x49\x46\x38"},  // GIF
16075       {+0x54494646, "\x03\x49\x49\x2A\x00"},  // TIFF (little-endian)
16076       {+0x54494646, "\x03\x4D\x4D\x00\x2A"},  // TIFF (big-endian)
16077       {-0x52494646, "\x03\x52\x49\x46\x46"},  // RIFF
16078       {+0x4E494520, "\x02\x6E\xC3\xAF"},      // NIE
16079       {+0x514F4920, "\x03\x71\x6F\x69\x66"},  // QOI
16080       {+0x504E4720, "\x03\x89\x50\x4E\x47"},  // PNG
16081       {+0x4A504547, "\x01\xFF\xD8"},          // JPEG
16082   };
16083   static const size_t table_len = sizeof(table) / sizeof(table[0]);
16084 
16085   if (prefix_data.len == 0) {
16086     return prefix_closed ? 0 : -1;
16087   }
16088   uint8_t pre_first_byte = prefix_data.ptr[0];
16089 
16090   int32_t fourcc = 0;
16091   size_t i;
16092   for (i = 0; i < table_len; i++) {
16093     uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1]));
16094     if (pre_first_byte < mag_first_byte) {
16095       break;
16096     } else if (pre_first_byte > mag_first_byte) {
16097       continue;
16098     }
16099     fourcc = table[i].fourcc;
16100 
16101     uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0]));
16102     if (mag_remaining_len == 0) {
16103       goto match;
16104     }
16105 
16106     const char* mag_remaining_ptr = table[i].magic + 2;
16107     uint8_t* pre_remaining_ptr = prefix_data.ptr + 1;
16108     size_t pre_remaining_len = prefix_data.len - 1;
16109     if (pre_remaining_len < mag_remaining_len) {
16110       if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) {
16111         return prefix_closed ? 0 : -1;
16112       }
16113     } else {
16114       if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) {
16115         goto match;
16116       }
16117     }
16118   }
16119 
16120   if (prefix_data.len < 2) {
16121     return prefix_closed ? 0 : -1;
16122   } else if ((prefix_data.ptr[1] == 0x00) || (prefix_data.ptr[1] == 0x01)) {
16123     return wuffs_base__magic_number_guess_fourcc__maybe_tga(prefix_data,
16124                                                             prefix_closed);
16125   }
16126 
16127   return 0;
16128 
16129 match:
16130   // Negative FourCC values (see § above) are further specialized.
16131   if (fourcc < 0) {
16132     fourcc = -fourcc;
16133 
16134     if (fourcc == 0x52494646) {  // 'RIFF'be
16135       if (prefix_data.len < 12) {
16136         return prefix_closed ? 0 : -1;
16137       }
16138       uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix_data.ptr + 8);
16139       if (x == 0x57454250) {  // 'WEBP'be
16140         return 0x57454250;    // 'WEBP'be
16141       }
16142 
16143     } else if (fourcc == 0x30302020) {  // '00  'be
16144       // Binary data starting with multiple 0x00 NUL bytes is quite common.
16145       // Unfortunately, some file formats also don't start with a magic
16146       // identifier, so we have to use heuristics (where the order matters, the
16147       // same as /usr/bin/file's magic/Magdir tables) as best we can. Maybe
16148       // it's TGA, ICO/CUR, etc. Maybe it's something else.
16149       int32_t tga = wuffs_base__magic_number_guess_fourcc__maybe_tga(
16150           prefix_data, prefix_closed);
16151       if (tga != 0) {
16152         return tga;
16153       }
16154       int32_t ico = wuffs_base__magic_number_guess_fourcc__maybe_ico(
16155           prefix_data, prefix_closed);
16156       if (ico != 0) {
16157         return ico;
16158       }
16159       if (prefix_data.len < 4) {
16160         return prefix_closed ? 0 : -1;
16161       } else if ((prefix_data.ptr[2] != 0x00) &&
16162                  ((prefix_data.ptr[2] >= 0x80) ||
16163                   (prefix_data.ptr[3] != 0x00))) {
16164         // Roughly speaking, this could be a non-degenerate (non-0-width and
16165         // non-0-height) WBMP image.
16166         return 0x57424D50;  // 'WBMP'be
16167       }
16168       return 0;
16169     }
16170   }
16171   return fourcc;
16172 }
16173 
16174 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
16175         // defined(WUFFS_CONFIG__MODULE__BASE) ||
16176         // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
16177 
16178 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
16179     defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
16180 
16181 // ---------------- Pixel Swizzler
16182 
16183 static inline uint32_t  //
wuffs_base__swap_u32_argb_abgr(uint32_t u)16184 wuffs_base__swap_u32_argb_abgr(uint32_t u) {
16185   uint32_t o = u & 0xFF00FF00ul;
16186   uint32_t r = u & 0x00FF0000ul;
16187   uint32_t b = u & 0x000000FFul;
16188   return o | (r >> 16) | (b << 16);
16189 }
16190 
16191 static inline uint64_t  //
wuffs_base__swap_u64_argb_abgr(uint64_t u)16192 wuffs_base__swap_u64_argb_abgr(uint64_t u) {
16193   uint64_t o = u & 0xFFFF0000FFFF0000ull;
16194   uint64_t r = u & 0x0000FFFF00000000ull;
16195   uint64_t b = u & 0x000000000000FFFFull;
16196   return o | (r >> 32) | (b << 32);
16197 }
16198 
16199 static inline uint32_t  //
wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c)16200 wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) {
16201   uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
16202   uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
16203   uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
16204   uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
16205   return (a << 24) | (b << 16) | (g << 8) | (r << 0);
16206 }
16207 
16208 // --------
16209 
16210 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)16211 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
16212                                        uint32_t x,
16213                                        uint32_t y) {
16214   if (!pb || (x >= pb->pixcfg.private_impl.width) ||
16215       (y >= pb->pixcfg.private_impl.height)) {
16216     return 0;
16217   }
16218 
16219   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
16220     // TODO: support planar formats.
16221     return 0;
16222   }
16223 
16224   size_t stride = pb->private_impl.planes[0].stride;
16225   const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
16226 
16227   switch (pb->pixcfg.private_impl.pixfmt.repr) {
16228     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
16229     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
16230       return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
16231 
16232     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
16233     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
16234       uint8_t* palette = pb->private_impl.planes[3].ptr;
16235       return wuffs_base__peek_u32le__no_bounds_check(palette +
16236                                                      (4 * ((size_t)row[x])));
16237     }
16238 
16239       // Common formats above. Rarer formats below.
16240 
16241     case WUFFS_BASE__PIXEL_FORMAT__Y:
16242       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x])));
16243     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
16244       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1])));
16245     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
16246       return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0])));
16247 
16248     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: {
16249       uint8_t* palette = pb->private_impl.planes[3].ptr;
16250       return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
16251           wuffs_base__peek_u32le__no_bounds_check(palette +
16252                                                   (4 * ((size_t)row[x]))));
16253     }
16254 
16255     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
16256       return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
16257           wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x))));
16258     case WUFFS_BASE__PIXEL_FORMAT__BGR:
16259       return 0xFF000000 |
16260              wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)));
16261     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
16262       return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
16263           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
16264     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
16265       return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
16266           wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x))));
16267     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
16268       return 0xFF000000 |
16269              wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
16270 
16271     case WUFFS_BASE__PIXEL_FORMAT__RGB:
16272       return wuffs_base__swap_u32_argb_abgr(
16273           0xFF000000 |
16274           wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))));
16275     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
16276       return wuffs_base__swap_u32_argb_abgr(
16277           wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
16278               wuffs_base__peek_u32le__no_bounds_check(row +
16279                                                       (4 * ((size_t)x)))));
16280     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
16281     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
16282       return wuffs_base__swap_u32_argb_abgr(
16283           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
16284     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
16285       return wuffs_base__swap_u32_argb_abgr(
16286           0xFF000000 |
16287           wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
16288 
16289     default:
16290       // TODO: support more formats.
16291       break;
16292   }
16293 
16294   return 0;
16295 }
16296 
16297 // --------
16298 
16299 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)16300 wuffs_base__pixel_buffer__set_color_u32_at(
16301     wuffs_base__pixel_buffer* pb,
16302     uint32_t x,
16303     uint32_t y,
16304     wuffs_base__color_u32_argb_premul color) {
16305   if (!pb) {
16306     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16307   }
16308   if ((x >= pb->pixcfg.private_impl.width) ||
16309       (y >= pb->pixcfg.private_impl.height)) {
16310     return wuffs_base__make_status(wuffs_base__error__bad_argument);
16311   }
16312 
16313   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
16314     // TODO: support planar formats.
16315     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
16316   }
16317 
16318   size_t stride = pb->private_impl.planes[0].stride;
16319   uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
16320 
16321   switch (pb->pixcfg.private_impl.pixfmt.repr) {
16322     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
16323     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
16324       wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color);
16325       break;
16326 
16327       // Common formats above. Rarer formats below.
16328 
16329     case WUFFS_BASE__PIXEL_FORMAT__Y:
16330       wuffs_base__poke_u8__no_bounds_check(
16331           row + ((size_t)x),
16332           wuffs_base__color_u32_argb_premul__as__color_u8_gray(color));
16333       break;
16334     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
16335       wuffs_base__poke_u16le__no_bounds_check(
16336           row + (2 * ((size_t)x)),
16337           wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
16338       break;
16339     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
16340       wuffs_base__poke_u16be__no_bounds_check(
16341           row + (2 * ((size_t)x)),
16342           wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
16343       break;
16344 
16345     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
16346     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
16347     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
16348       wuffs_base__poke_u8__no_bounds_check(
16349           row + ((size_t)x), wuffs_base__pixel_palette__closest_element(
16350                                  wuffs_base__pixel_buffer__palette(pb),
16351                                  pb->pixcfg.private_impl.pixfmt, color));
16352       break;
16353 
16354     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
16355       wuffs_base__poke_u16le__no_bounds_check(
16356           row + (2 * ((size_t)x)),
16357           wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
16358       break;
16359     case WUFFS_BASE__PIXEL_FORMAT__BGR:
16360       wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color);
16361       break;
16362     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
16363       wuffs_base__poke_u32le__no_bounds_check(
16364           row + (4 * ((size_t)x)),
16365           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16366               color));
16367       break;
16368     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
16369       wuffs_base__poke_u64le__no_bounds_check(
16370           row + (8 * ((size_t)x)),
16371           wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
16372               color));
16373       break;
16374 
16375     case WUFFS_BASE__PIXEL_FORMAT__RGB:
16376       wuffs_base__poke_u24le__no_bounds_check(
16377           row + (3 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
16378       break;
16379     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
16380       wuffs_base__poke_u32le__no_bounds_check(
16381           row + (4 * ((size_t)x)),
16382           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16383               wuffs_base__swap_u32_argb_abgr(color)));
16384       break;
16385     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
16386     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
16387       wuffs_base__poke_u32le__no_bounds_check(
16388           row + (4 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
16389       break;
16390 
16391     default:
16392       // TODO: support more formats.
16393       return wuffs_base__make_status(wuffs_base__error__unsupported_option);
16394   }
16395 
16396   return wuffs_base__make_status(NULL);
16397 }
16398 
16399 // --------
16400 
16401 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)16402 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
16403     wuffs_base__pixel_buffer* pb,
16404     wuffs_base__rect_ie_u32 rect,
16405     uint16_t color) {
16406   size_t stride = pb->private_impl.planes[0].stride;
16407   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16408   if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16409     uint8_t* ptr =
16410         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16411     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16412     size_t n;
16413     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16414       wuffs_base__poke_u16le__no_bounds_check(ptr, color);
16415       ptr += 2;
16416     }
16417     return;
16418   }
16419 
16420   uint32_t y;
16421   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16422     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16423                    (2 * ((size_t)rect.min_incl_x));
16424     uint32_t n;
16425     for (n = width; n > 0; n--) {
16426       wuffs_base__poke_u16le__no_bounds_check(ptr, color);
16427       ptr += 2;
16428     }
16429   }
16430 }
16431 
16432 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)16433 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(
16434     wuffs_base__pixel_buffer* pb,
16435     wuffs_base__rect_ie_u32 rect,
16436     uint32_t color) {
16437   size_t stride = pb->private_impl.planes[0].stride;
16438   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16439   if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16440     uint8_t* ptr =
16441         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16442     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16443     size_t n;
16444     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16445       wuffs_base__poke_u24le__no_bounds_check(ptr, color);
16446       ptr += 3;
16447     }
16448     return;
16449   }
16450 
16451   uint32_t y;
16452   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16453     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16454                    (3 * ((size_t)rect.min_incl_x));
16455     uint32_t n;
16456     for (n = width; n > 0; n--) {
16457       wuffs_base__poke_u24le__no_bounds_check(ptr, color);
16458       ptr += 3;
16459     }
16460   }
16461 }
16462 
16463 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)16464 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16465     wuffs_base__pixel_buffer* pb,
16466     wuffs_base__rect_ie_u32 rect,
16467     uint32_t color) {
16468   size_t stride = pb->private_impl.planes[0].stride;
16469   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16470   if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16471     uint8_t* ptr =
16472         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16473     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16474     size_t n;
16475     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16476       wuffs_base__poke_u32le__no_bounds_check(ptr, color);
16477       ptr += 4;
16478     }
16479     return;
16480   }
16481 
16482   uint32_t y;
16483   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16484     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16485                    (4 * ((size_t)rect.min_incl_x));
16486     uint32_t n;
16487     for (n = width; n > 0; n--) {
16488       wuffs_base__poke_u32le__no_bounds_check(ptr, color);
16489       ptr += 4;
16490     }
16491   }
16492 }
16493 
16494 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)16495 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
16496     wuffs_base__pixel_buffer* pb,
16497     wuffs_base__rect_ie_u32 rect,
16498     uint64_t color) {
16499   size_t stride = pb->private_impl.planes[0].stride;
16500   uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16501   if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16502     uint8_t* ptr =
16503         pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16504     uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16505     size_t n;
16506     for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16507       wuffs_base__poke_u64le__no_bounds_check(ptr, color);
16508       ptr += 8;
16509     }
16510     return;
16511   }
16512 
16513   uint32_t y;
16514   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16515     uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16516                    (8 * ((size_t)rect.min_incl_x));
16517     uint32_t n;
16518     for (n = width; n > 0; n--) {
16519       wuffs_base__poke_u64le__no_bounds_check(ptr, color);
16520       ptr += 8;
16521     }
16522   }
16523 }
16524 
16525 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)16526 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
16527     wuffs_base__pixel_buffer* pb,
16528     wuffs_base__rect_ie_u32 rect,
16529     wuffs_base__color_u32_argb_premul color) {
16530   if (!pb) {
16531     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16532   } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) {
16533     return wuffs_base__make_status(NULL);
16534   }
16535   wuffs_base__rect_ie_u32 bounds =
16536       wuffs_base__pixel_config__bounds(&pb->pixcfg);
16537   if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) {
16538     return wuffs_base__make_status(wuffs_base__error__bad_argument);
16539   }
16540 
16541   if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
16542     // TODO: support planar formats.
16543     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
16544   }
16545 
16546   switch (pb->pixcfg.private_impl.pixfmt.repr) {
16547     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
16548     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
16549       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect, color);
16550       return wuffs_base__make_status(NULL);
16551 
16552       // Common formats above. Rarer formats below.
16553 
16554     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
16555       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
16556           pb, rect,
16557           wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
16558       return wuffs_base__make_status(NULL);
16559 
16560     case WUFFS_BASE__PIXEL_FORMAT__BGR:
16561       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect, color);
16562       return wuffs_base__make_status(NULL);
16563 
16564     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
16565       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16566           pb, rect,
16567           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16568               color));
16569       return wuffs_base__make_status(NULL);
16570 
16571     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
16572       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
16573           pb, rect,
16574           wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
16575               color));
16576       return wuffs_base__make_status(NULL);
16577 
16578     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
16579       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16580           pb, rect,
16581           wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16582               wuffs_base__swap_u32_argb_abgr(color)));
16583       return wuffs_base__make_status(NULL);
16584 
16585     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
16586     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
16587       wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16588           pb, rect, wuffs_base__swap_u32_argb_abgr(color));
16589       return wuffs_base__make_status(NULL);
16590   }
16591 
16592   uint32_t y;
16593   for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16594     uint32_t x;
16595     for (x = rect.min_incl_x; x < rect.max_excl_x; x++) {
16596       wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color);
16597     }
16598   }
16599   return wuffs_base__make_status(NULL);
16600 }
16601 
16602 // --------
16603 
16604 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)16605 wuffs_base__pixel_palette__closest_element(
16606     wuffs_base__slice_u8 palette_slice,
16607     wuffs_base__pixel_format palette_format,
16608     wuffs_base__color_u32_argb_premul c) {
16609   size_t n = palette_slice.len / 4;
16610   if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
16611     n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4);
16612   }
16613   size_t best_index = 0;
16614   uint64_t best_score = 0xFFFFFFFFFFFFFFFF;
16615 
16616   // Work in 16-bit color.
16617   uint32_t ca = 0x101 * (0xFF & (c >> 24));
16618   uint32_t cr = 0x101 * (0xFF & (c >> 16));
16619   uint32_t cg = 0x101 * (0xFF & (c >> 8));
16620   uint32_t cb = 0x101 * (0xFF & (c >> 0));
16621 
16622   switch (palette_format.repr) {
16623     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
16624     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
16625     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
16626       bool nonpremul = palette_format.repr ==
16627                        WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL;
16628 
16629       size_t i;
16630       for (i = 0; i < n; i++) {
16631         // Work in 16-bit color.
16632         uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0]));
16633         uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1]));
16634         uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2]));
16635         uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3]));
16636 
16637         // Convert to premultiplied alpha.
16638         if (nonpremul && (pa != 0xFFFF)) {
16639           pb = (pb * pa) / 0xFFFF;
16640           pg = (pg * pa) / 0xFFFF;
16641           pr = (pr * pa) / 0xFFFF;
16642         }
16643 
16644         // These deltas are conceptually int32_t (signed) but after squaring,
16645         // it's equivalent to work in uint32_t (unsigned).
16646         pb -= cb;
16647         pg -= cg;
16648         pr -= cr;
16649         pa -= ca;
16650         uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) +
16651                          ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa));
16652         if (best_score > score) {
16653           best_score = score;
16654           best_index = i;
16655         }
16656       }
16657       break;
16658     }
16659   }
16660 
16661   return (uint8_t)best_index;
16662 }
16663 
16664 // --------
16665 
16666 static inline uint32_t  //
wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_nonpremul)16667 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,
16668                                                    uint32_t src_nonpremul) {
16669   // Extract 16-bit color components.
16670   //
16671   // If the destination is transparent then SRC_OVER is equivalent to SRC: just
16672   // return src_nonpremul. This isn't just an optimization (skipping the rest
16673   // of the function's computation). It also preserves the nonpremul
16674   // distinction between e.g. transparent red and transparent blue that would
16675   // otherwise be lost by converting from nonpremul to premul and back.
16676   uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
16677   if (da == 0) {
16678     return src_nonpremul;
16679   }
16680   uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
16681   uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
16682   uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
16683   uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
16684   uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
16685   uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
16686   uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
16687 
16688   // Convert dst from nonpremul to premul.
16689   dr = (dr * da) / 0xFFFF;
16690   dg = (dg * da) / 0xFFFF;
16691   db = (db * da) / 0xFFFF;
16692 
16693   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16694   uint32_t ia = 0xFFFF - sa;
16695 
16696   // Composite src (nonpremul) over dst (premul).
16697   da = sa + ((da * ia) / 0xFFFF);
16698   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16699   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16700   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16701 
16702   // Convert dst from premul to nonpremul.
16703   if (da != 0) {
16704     dr = (dr * 0xFFFF) / da;
16705     dg = (dg * 0xFFFF) / da;
16706     db = (db * 0xFFFF) / da;
16707   }
16708 
16709   // Convert from 16-bit color to 8-bit color.
16710   da >>= 8;
16711   dr >>= 8;
16712   dg >>= 8;
16713   db >>= 8;
16714 
16715   // Combine components.
16716   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16717 }
16718 
16719 static inline uint64_t  //
wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_nonpremul)16720 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,
16721                                                    uint64_t src_nonpremul) {
16722   // Extract components.
16723   //
16724   // If the destination is transparent then SRC_OVER is equivalent to SRC: just
16725   // return src_nonpremul. This isn't just an optimization (skipping the rest
16726   // of the function's computation). It also preserves the nonpremul
16727   // distinction between e.g. transparent red and transparent blue that would
16728   // otherwise be lost by converting from nonpremul to premul and back.
16729   uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
16730   if (da == 0) {
16731     return src_nonpremul;
16732   }
16733   uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
16734   uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
16735   uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
16736   uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
16737   uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
16738   uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
16739   uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
16740 
16741   // Convert dst from nonpremul to premul.
16742   dr = (dr * da) / 0xFFFF;
16743   dg = (dg * da) / 0xFFFF;
16744   db = (db * da) / 0xFFFF;
16745 
16746   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16747   uint64_t ia = 0xFFFF - sa;
16748 
16749   // Composite src (nonpremul) over dst (premul).
16750   da = sa + ((da * ia) / 0xFFFF);
16751   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16752   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16753   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16754 
16755   // Convert dst from premul to nonpremul.
16756   if (da != 0) {
16757     dr = (dr * 0xFFFF) / da;
16758     dg = (dg * 0xFFFF) / da;
16759     db = (db * 0xFFFF) / da;
16760   }
16761 
16762   // Combine components.
16763   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16764 }
16765 
16766 static inline uint32_t  //
wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_premul)16767 wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,
16768                                                 uint32_t src_premul) {
16769   // Extract 16-bit color components.
16770   uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
16771   uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
16772   uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
16773   uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
16774   uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
16775   uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
16776   uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
16777   uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
16778 
16779   // Convert dst from nonpremul to premul.
16780   dr = (dr * da) / 0xFFFF;
16781   dg = (dg * da) / 0xFFFF;
16782   db = (db * da) / 0xFFFF;
16783 
16784   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16785   uint32_t ia = 0xFFFF - sa;
16786 
16787   // Composite src (premul) over dst (premul).
16788   da = sa + ((da * ia) / 0xFFFF);
16789   dr = sr + ((dr * ia) / 0xFFFF);
16790   dg = sg + ((dg * ia) / 0xFFFF);
16791   db = sb + ((db * ia) / 0xFFFF);
16792 
16793   // Convert dst from premul to nonpremul.
16794   if (da != 0) {
16795     dr = (dr * 0xFFFF) / da;
16796     dg = (dg * 0xFFFF) / da;
16797     db = (db * 0xFFFF) / da;
16798   }
16799 
16800   // Convert from 16-bit color to 8-bit color.
16801   da >>= 8;
16802   dr >>= 8;
16803   dg >>= 8;
16804   db >>= 8;
16805 
16806   // Combine components.
16807   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16808 }
16809 
16810 static inline uint64_t  //
wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_premul)16811 wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,
16812                                                 uint64_t src_premul) {
16813   // Extract components.
16814   uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
16815   uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
16816   uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
16817   uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
16818   uint64_t sa = 0xFFFF & (src_premul >> 48);
16819   uint64_t sr = 0xFFFF & (src_premul >> 32);
16820   uint64_t sg = 0xFFFF & (src_premul >> 16);
16821   uint64_t sb = 0xFFFF & (src_premul >> 0);
16822 
16823   // Convert dst from nonpremul to premul.
16824   dr = (dr * da) / 0xFFFF;
16825   dg = (dg * da) / 0xFFFF;
16826   db = (db * da) / 0xFFFF;
16827 
16828   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16829   uint64_t ia = 0xFFFF - sa;
16830 
16831   // Composite src (premul) over dst (premul).
16832   da = sa + ((da * ia) / 0xFFFF);
16833   dr = sr + ((dr * ia) / 0xFFFF);
16834   dg = sg + ((dg * ia) / 0xFFFF);
16835   db = sb + ((db * ia) / 0xFFFF);
16836 
16837   // Convert dst from premul to nonpremul.
16838   if (da != 0) {
16839     dr = (dr * 0xFFFF) / da;
16840     dg = (dg * 0xFFFF) / da;
16841     db = (db * 0xFFFF) / da;
16842   }
16843 
16844   // Combine components.
16845   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16846 }
16847 
16848 static inline uint32_t  //
wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,uint32_t src_nonpremul)16849 wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,
16850                                                 uint32_t src_nonpremul) {
16851   // Extract 16-bit color components.
16852   uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
16853   uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
16854   uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
16855   uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
16856   uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
16857   uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
16858   uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
16859   uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
16860 
16861   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16862   uint32_t ia = 0xFFFF - sa;
16863 
16864   // Composite src (nonpremul) over dst (premul).
16865   da = sa + ((da * ia) / 0xFFFF);
16866   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16867   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16868   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16869 
16870   // Convert from 16-bit color to 8-bit color.
16871   da >>= 8;
16872   dr >>= 8;
16873   dg >>= 8;
16874   db >>= 8;
16875 
16876   // Combine components.
16877   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16878 }
16879 
16880 static inline uint64_t  //
wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,uint64_t src_nonpremul)16881 wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,
16882                                                 uint64_t src_nonpremul) {
16883   // Extract components.
16884   uint64_t da = 0xFFFF & (dst_premul >> 48);
16885   uint64_t dr = 0xFFFF & (dst_premul >> 32);
16886   uint64_t dg = 0xFFFF & (dst_premul >> 16);
16887   uint64_t db = 0xFFFF & (dst_premul >> 0);
16888   uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
16889   uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
16890   uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
16891   uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
16892 
16893   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16894   uint64_t ia = 0xFFFF - sa;
16895 
16896   // Composite src (nonpremul) over dst (premul).
16897   da = sa + ((da * ia) / 0xFFFF);
16898   dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16899   dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16900   db = ((sb * sa) + (db * ia)) / 0xFFFF;
16901 
16902   // Combine components.
16903   return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16904 }
16905 
16906 static inline uint32_t  //
wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,uint32_t src_premul)16907 wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,
16908                                              uint32_t src_premul) {
16909   // Extract 16-bit color components.
16910   uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
16911   uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
16912   uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
16913   uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
16914   uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
16915   uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
16916   uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
16917   uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
16918 
16919   // Calculate the inverse of the src-alpha: how much of the dst to keep.
16920   uint32_t ia = 0xFFFF - sa;
16921 
16922   // Composite src (premul) over dst (premul).
16923   da = sa + ((da * ia) / 0xFFFF);
16924   dr = sr + ((dr * ia) / 0xFFFF);
16925   dg = sg + ((dg * ia) / 0xFFFF);
16926   db = sb + ((db * ia) / 0xFFFF);
16927 
16928   // Convert from 16-bit color to 8-bit color.
16929   da >>= 8;
16930   dr >>= 8;
16931   dg >>= 8;
16932   db >>= 8;
16933 
16934   // Combine components.
16935   return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16936 }
16937 
16938 // --------
16939 
16940 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)16941 wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t* dst_ptr,
16942                                                        size_t dst_len,
16943                                                        const uint8_t* src_ptr,
16944                                                        size_t src_len,
16945                                                        bool nonpremul) {
16946   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
16947   uint8_t* d = dst_ptr;
16948   const uint8_t* s = src_ptr;
16949 
16950   size_t n = len;
16951   while (n--) {
16952     uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s);
16953     if (nonpremul) {
16954       argb =
16955           wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb);
16956     }
16957     uint32_t b5 = 0x1F & (argb >> (8 - 5));
16958     uint32_t g6 = 0x3F & (argb >> (16 - 6));
16959     uint32_t r5 = 0x1F & (argb >> (24 - 5));
16960     uint32_t alpha = argb & 0xFF000000;
16961     wuffs_base__poke_u32le__no_bounds_check(
16962         d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0));
16963     s += 4;
16964     d += 4;
16965   }
16966   return len;
16967 }
16968 
16969 // --------
16970 
16971 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)16972 wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t* dst_ptr,
16973                                          size_t dst_len,
16974                                          uint8_t* dst_palette_ptr,
16975                                          size_t dst_palette_len,
16976                                          const uint8_t* src_ptr,
16977                                          size_t src_len) {
16978   size_t len = (dst_len < src_len ? dst_len : src_len) / 3;
16979   uint8_t* d = dst_ptr;
16980   const uint8_t* s = src_ptr;
16981 
16982   size_t n = len;
16983   while (n--) {
16984     uint8_t s0 = s[0];
16985     uint8_t s1 = s[1];
16986     uint8_t s2 = s[2];
16987     d[0] = s2;
16988     d[1] = s1;
16989     d[2] = s0;
16990     s += 3;
16991     d += 3;
16992   }
16993   return len;
16994 }
16995 
16996 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
16997 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
16998 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
16999 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)17000 wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42(uint8_t* dst_ptr,
17001                                                   size_t dst_len,
17002                                                   uint8_t* dst_palette_ptr,
17003                                                   size_t dst_palette_len,
17004                                                   const uint8_t* src_ptr,
17005                                                   size_t src_len) {
17006   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
17007   uint8_t* d = dst_ptr;
17008   const uint8_t* s = src_ptr;
17009   size_t n = len;
17010 
17011   __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E,  //
17012                                  +0x0B, +0x08, +0x09, +0x0A,  //
17013                                  +0x07, +0x04, +0x05, +0x06,  //
17014                                  +0x03, +0x00, +0x01, +0x02);
17015 
17016   while (n >= 4) {
17017     __m128i x;
17018     x = _mm_lddqu_si128((const __m128i*)(const void*)s);
17019     x = _mm_shuffle_epi8(x, shuffle);
17020     _mm_storeu_si128((__m128i*)(void*)d, x);
17021 
17022     s += 4 * 4;
17023     d += 4 * 4;
17024     n -= 4;
17025   }
17026 
17027   while (n--) {
17028     uint8_t s0 = s[0];
17029     uint8_t s1 = s[1];
17030     uint8_t s2 = s[2];
17031     uint8_t s3 = s[3];
17032     d[0] = s2;
17033     d[1] = s1;
17034     d[2] = s0;
17035     d[3] = s3;
17036     s += 4;
17037     d += 4;
17038   }
17039   return len;
17040 }
17041 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
17042 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
17043 
17044 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)17045 wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t* dst_ptr,
17046                                            size_t dst_len,
17047                                            uint8_t* dst_palette_ptr,
17048                                            size_t dst_palette_len,
17049                                            const uint8_t* src_ptr,
17050                                            size_t src_len) {
17051   size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
17052   uint8_t* d = dst_ptr;
17053   const uint8_t* s = src_ptr;
17054 
17055   size_t n = len;
17056   while (n--) {
17057     uint8_t s0 = s[0];
17058     uint8_t s1 = s[1];
17059     uint8_t s2 = s[2];
17060     uint8_t s3 = s[3];
17061     d[0] = s2;
17062     d[1] = s1;
17063     d[2] = s0;
17064     d[3] = s3;
17065     s += 4;
17066     d += 4;
17067   }
17068   return len;
17069 }
17070 
17071 // --------
17072 
17073 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)17074 wuffs_base__pixel_swizzler__copy_1_1(uint8_t* dst_ptr,
17075                                      size_t dst_len,
17076                                      uint8_t* dst_palette_ptr,
17077                                      size_t dst_palette_len,
17078                                      const uint8_t* src_ptr,
17079                                      size_t src_len) {
17080   size_t len = (dst_len < src_len) ? dst_len : src_len;
17081   if (len > 0) {
17082     memmove(dst_ptr, src_ptr, len);
17083   }
17084   return len;
17085 }
17086 
17087 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)17088 wuffs_base__pixel_swizzler__copy_2_2(uint8_t* dst_ptr,
17089                                      size_t dst_len,
17090                                      uint8_t* dst_palette_ptr,
17091                                      size_t dst_palette_len,
17092                                      const uint8_t* src_ptr,
17093                                      size_t src_len) {
17094   size_t dst_len2 = dst_len / 2;
17095   size_t src_len2 = src_len / 2;
17096   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
17097   if (len > 0) {
17098     memmove(dst_ptr, src_ptr, len * 2);
17099   }
17100   return len;
17101 }
17102 
17103 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)17104 wuffs_base__pixel_swizzler__copy_3_3(uint8_t* dst_ptr,
17105                                      size_t dst_len,
17106                                      uint8_t* dst_palette_ptr,
17107                                      size_t dst_palette_len,
17108                                      const uint8_t* src_ptr,
17109                                      size_t src_len) {
17110   size_t dst_len3 = dst_len / 3;
17111   size_t src_len3 = src_len / 3;
17112   size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3;
17113   if (len > 0) {
17114     memmove(dst_ptr, src_ptr, len * 3);
17115   }
17116   return len;
17117 }
17118 
17119 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)17120 wuffs_base__pixel_swizzler__copy_4_4(uint8_t* dst_ptr,
17121                                      size_t dst_len,
17122                                      uint8_t* dst_palette_ptr,
17123                                      size_t dst_palette_len,
17124                                      const uint8_t* src_ptr,
17125                                      size_t src_len) {
17126   size_t dst_len4 = dst_len / 4;
17127   size_t src_len4 = src_len / 4;
17128   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
17129   if (len > 0) {
17130     memmove(dst_ptr, src_ptr, len * 4);
17131   }
17132   return len;
17133 }
17134 
17135 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)17136 wuffs_base__pixel_swizzler__copy_8_8(uint8_t* dst_ptr,
17137                                      size_t dst_len,
17138                                      uint8_t* dst_palette_ptr,
17139                                      size_t dst_palette_len,
17140                                      const uint8_t* src_ptr,
17141                                      size_t src_len) {
17142   size_t dst_len8 = dst_len / 8;
17143   size_t src_len8 = src_len / 8;
17144   size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
17145   if (len > 0) {
17146     memmove(dst_ptr, src_ptr, len * 8);
17147   }
17148   return len;
17149 }
17150 
17151 // --------
17152 
17153 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)17154 wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t* dst_ptr,
17155                                          size_t dst_len,
17156                                          uint8_t* dst_palette_ptr,
17157                                          size_t dst_palette_len,
17158                                          const uint8_t* src_ptr,
17159                                          size_t src_len) {
17160   size_t dst_len2 = dst_len / 2;
17161   size_t src_len3 = src_len / 3;
17162   size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
17163   uint8_t* d = dst_ptr;
17164   const uint8_t* s = src_ptr;
17165   size_t n = len;
17166 
17167   // TODO: unroll.
17168 
17169   while (n >= 1) {
17170     uint32_t b5 = s[0] >> 3;
17171     uint32_t g6 = s[1] >> 2;
17172     uint32_t r5 = s[2] >> 3;
17173     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
17174     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17175 
17176     s += 1 * 3;
17177     d += 1 * 2;
17178     n -= 1;
17179   }
17180 
17181   return len;
17182 }
17183 
17184 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)17185 wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t* dst_ptr,
17186                                           size_t dst_len,
17187                                           uint8_t* dst_palette_ptr,
17188                                           size_t dst_palette_len,
17189                                           const uint8_t* src_ptr,
17190                                           size_t src_len) {
17191   size_t dst_len2 = dst_len / 2;
17192   size_t src_len4 = src_len / 4;
17193   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17194   uint8_t* d = dst_ptr;
17195   const uint8_t* s = src_ptr;
17196   size_t n = len;
17197 
17198   // TODO: unroll.
17199 
17200   while (n >= 1) {
17201     uint32_t b5 = s[0] >> 3;
17202     uint32_t g6 = s[1] >> 2;
17203     uint32_t r5 = s[2] >> 3;
17204     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
17205     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17206 
17207     s += 1 * 4;
17208     d += 1 * 2;
17209     n -= 1;
17210   }
17211 
17212   return len;
17213 }
17214 
17215 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)17216 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(
17217     uint8_t* dst_ptr,
17218     size_t dst_len,
17219     uint8_t* dst_palette_ptr,
17220     size_t dst_palette_len,
17221     const uint8_t* src_ptr,
17222     size_t src_len) {
17223   size_t dst_len2 = dst_len / 2;
17224   size_t src_len4 = src_len / 4;
17225   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17226   uint8_t* d = dst_ptr;
17227   const uint8_t* s = src_ptr;
17228   size_t n = len;
17229 
17230   // TODO: unroll.
17231 
17232   while (n >= 1) {
17233     wuffs_base__poke_u16le__no_bounds_check(
17234         d + (0 * 2),
17235         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17236             wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17237                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
17238 
17239     s += 1 * 4;
17240     d += 1 * 2;
17241     n -= 1;
17242   }
17243 
17244   return len;
17245 }
17246 
17247 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)17248 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src(
17249     uint8_t* dst_ptr,
17250     size_t dst_len,
17251     uint8_t* dst_palette_ptr,
17252     size_t dst_palette_len,
17253     const uint8_t* src_ptr,
17254     size_t src_len) {
17255   size_t dst_len2 = dst_len / 2;
17256   size_t src_len8 = src_len / 8;
17257   size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
17258   uint8_t* d = dst_ptr;
17259   const uint8_t* s = src_ptr;
17260   size_t n = len;
17261 
17262   // TODO: unroll.
17263 
17264   while (n >= 1) {
17265     wuffs_base__poke_u16le__no_bounds_check(
17266         d + (0 * 2),
17267         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17268             wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
17269                 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))));
17270 
17271     s += 1 * 8;
17272     d += 1 * 2;
17273     n -= 1;
17274   }
17275 
17276   return len;
17277 }
17278 
17279 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)17280 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(
17281     uint8_t* dst_ptr,
17282     size_t dst_len,
17283     uint8_t* dst_palette_ptr,
17284     size_t dst_palette_len,
17285     const uint8_t* src_ptr,
17286     size_t src_len) {
17287   size_t dst_len2 = dst_len / 2;
17288   size_t src_len4 = src_len / 4;
17289   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17290   uint8_t* d = dst_ptr;
17291   const uint8_t* s = src_ptr;
17292   size_t n = len;
17293 
17294   // TODO: unroll.
17295 
17296   while (n >= 1) {
17297     // Extract 16-bit color components.
17298     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17299     uint32_t sr = 0x101 * ((uint32_t)s[2]);
17300     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17301     uint32_t sb = 0x101 * ((uint32_t)s[0]);
17302 
17303     // Convert from 565 color to 16-bit color.
17304     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17305     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17306     uint32_t dr = (0x8421 * old_r5) >> 4;
17307     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17308     uint32_t dg = (0x1041 * old_g6) >> 2;
17309     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17310     uint32_t db = (0x8421 * old_b5) >> 4;
17311 
17312     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17313     uint32_t ia = 0xFFFF - sa;
17314 
17315     // Composite src (nonpremul) over dst (premul).
17316     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17317     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17318     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17319 
17320     // Convert from 16-bit color to 565 color and combine the components.
17321     uint32_t new_r5 = 0x1F & (dr >> 11);
17322     uint32_t new_g6 = 0x3F & (dg >> 10);
17323     uint32_t new_b5 = 0x1F & (db >> 11);
17324     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17325     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17326 
17327     s += 1 * 4;
17328     d += 1 * 2;
17329     n -= 1;
17330   }
17331 
17332   return len;
17333 }
17334 
17335 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)17336 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over(
17337     uint8_t* dst_ptr,
17338     size_t dst_len,
17339     uint8_t* dst_palette_ptr,
17340     size_t dst_palette_len,
17341     const uint8_t* src_ptr,
17342     size_t src_len) {
17343   size_t dst_len2 = dst_len / 2;
17344   size_t src_len8 = src_len / 8;
17345   size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
17346   uint8_t* d = dst_ptr;
17347   const uint8_t* s = src_ptr;
17348   size_t n = len;
17349 
17350   // TODO: unroll.
17351 
17352   while (n >= 1) {
17353     // Extract 16-bit color components.
17354     uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
17355     uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
17356     uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
17357     uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
17358 
17359     // Convert from 565 color to 16-bit color.
17360     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17361     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17362     uint32_t dr = (0x8421 * old_r5) >> 4;
17363     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17364     uint32_t dg = (0x1041 * old_g6) >> 2;
17365     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17366     uint32_t db = (0x8421 * old_b5) >> 4;
17367 
17368     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17369     uint32_t ia = 0xFFFF - sa;
17370 
17371     // Composite src (nonpremul) over dst (premul).
17372     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17373     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17374     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17375 
17376     // Convert from 16-bit color to 565 color and combine the components.
17377     uint32_t new_r5 = 0x1F & (dr >> 11);
17378     uint32_t new_g6 = 0x3F & (dg >> 10);
17379     uint32_t new_b5 = 0x1F & (db >> 11);
17380     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17381     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17382 
17383     s += 1 * 8;
17384     d += 1 * 2;
17385     n -= 1;
17386   }
17387 
17388   return len;
17389 }
17390 
17391 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)17392 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t* dst_ptr,
17393                                                       size_t dst_len,
17394                                                       uint8_t* dst_palette_ptr,
17395                                                       size_t dst_palette_len,
17396                                                       const uint8_t* src_ptr,
17397                                                       size_t src_len) {
17398   size_t dst_len2 = dst_len / 2;
17399   size_t src_len4 = src_len / 4;
17400   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17401   uint8_t* d = dst_ptr;
17402   const uint8_t* s = src_ptr;
17403   size_t n = len;
17404 
17405   // TODO: unroll.
17406 
17407   while (n >= 1) {
17408     wuffs_base__poke_u16le__no_bounds_check(
17409         d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17410                          wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
17411 
17412     s += 1 * 4;
17413     d += 1 * 2;
17414     n -= 1;
17415   }
17416 
17417   return len;
17418 }
17419 
17420 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)17421 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over(
17422     uint8_t* dst_ptr,
17423     size_t dst_len,
17424     uint8_t* dst_palette_ptr,
17425     size_t dst_palette_len,
17426     const uint8_t* src_ptr,
17427     size_t src_len) {
17428   size_t dst_len2 = dst_len / 2;
17429   size_t src_len4 = src_len / 4;
17430   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17431   uint8_t* d = dst_ptr;
17432   const uint8_t* s = src_ptr;
17433   size_t n = len;
17434 
17435   // TODO: unroll.
17436 
17437   while (n >= 1) {
17438     // Extract 16-bit color components.
17439     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17440     uint32_t sr = 0x101 * ((uint32_t)s[2]);
17441     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17442     uint32_t sb = 0x101 * ((uint32_t)s[0]);
17443 
17444     // Convert from 565 color to 16-bit color.
17445     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17446     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17447     uint32_t dr = (0x8421 * old_r5) >> 4;
17448     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17449     uint32_t dg = (0x1041 * old_g6) >> 2;
17450     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17451     uint32_t db = (0x8421 * old_b5) >> 4;
17452 
17453     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17454     uint32_t ia = 0xFFFF - sa;
17455 
17456     // Composite src (premul) over dst (premul).
17457     dr = sr + ((dr * ia) / 0xFFFF);
17458     dg = sg + ((dg * ia) / 0xFFFF);
17459     db = sb + ((db * ia) / 0xFFFF);
17460 
17461     // Convert from 16-bit color to 565 color and combine the components.
17462     uint32_t new_r5 = 0x1F & (dr >> 11);
17463     uint32_t new_g6 = 0x3F & (dg >> 10);
17464     uint32_t new_b5 = 0x1F & (db >> 11);
17465     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17466     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17467 
17468     s += 1 * 4;
17469     d += 1 * 2;
17470     n -= 1;
17471   }
17472 
17473   return len;
17474 }
17475 
17476 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)17477 wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t* dst_ptr,
17478                                          size_t dst_len,
17479                                          uint8_t* dst_palette_ptr,
17480                                          size_t dst_palette_len,
17481                                          const uint8_t* src_ptr,
17482                                          size_t src_len) {
17483   size_t dst_len2 = dst_len / 2;
17484   size_t src_len3 = src_len / 3;
17485   size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
17486   uint8_t* d = dst_ptr;
17487   const uint8_t* s = src_ptr;
17488   size_t n = len;
17489 
17490   // TODO: unroll.
17491 
17492   while (n >= 1) {
17493     uint32_t r5 = s[0] >> 3;
17494     uint32_t g6 = s[1] >> 2;
17495     uint32_t b5 = s[2] >> 3;
17496     uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
17497     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17498 
17499     s += 1 * 3;
17500     d += 1 * 2;
17501     n -= 1;
17502   }
17503 
17504   return len;
17505 }
17506 
17507 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)17508 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src(
17509     uint8_t* dst_ptr,
17510     size_t dst_len,
17511     uint8_t* dst_palette_ptr,
17512     size_t dst_palette_len,
17513     const uint8_t* src_ptr,
17514     size_t src_len) {
17515   size_t dst_len2 = dst_len / 2;
17516   size_t src_len4 = src_len / 4;
17517   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17518   uint8_t* d = dst_ptr;
17519   const uint8_t* s = src_ptr;
17520   size_t n = len;
17521 
17522   // TODO: unroll.
17523 
17524   while (n >= 1) {
17525     wuffs_base__poke_u16le__no_bounds_check(
17526         d + (0 * 2),
17527         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17528             wuffs_base__swap_u32_argb_abgr(
17529                 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17530                     wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))));
17531 
17532     s += 1 * 4;
17533     d += 1 * 2;
17534     n -= 1;
17535   }
17536 
17537   return len;
17538 }
17539 
17540 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)17541 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over(
17542     uint8_t* dst_ptr,
17543     size_t dst_len,
17544     uint8_t* dst_palette_ptr,
17545     size_t dst_palette_len,
17546     const uint8_t* src_ptr,
17547     size_t src_len) {
17548   size_t dst_len2 = dst_len / 2;
17549   size_t src_len4 = src_len / 4;
17550   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17551   uint8_t* d = dst_ptr;
17552   const uint8_t* s = src_ptr;
17553   size_t n = len;
17554 
17555   // TODO: unroll.
17556 
17557   while (n >= 1) {
17558     // Extract 16-bit color components.
17559     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17560     uint32_t sb = 0x101 * ((uint32_t)s[2]);
17561     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17562     uint32_t sr = 0x101 * ((uint32_t)s[0]);
17563 
17564     // Convert from 565 color to 16-bit color.
17565     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17566     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17567     uint32_t dr = (0x8421 * old_r5) >> 4;
17568     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17569     uint32_t dg = (0x1041 * old_g6) >> 2;
17570     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17571     uint32_t db = (0x8421 * old_b5) >> 4;
17572 
17573     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17574     uint32_t ia = 0xFFFF - sa;
17575 
17576     // Composite src (nonpremul) over dst (premul).
17577     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17578     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17579     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17580 
17581     // Convert from 16-bit color to 565 color and combine the components.
17582     uint32_t new_r5 = 0x1F & (dr >> 11);
17583     uint32_t new_g6 = 0x3F & (dg >> 10);
17584     uint32_t new_b5 = 0x1F & (db >> 11);
17585     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17586     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17587 
17588     s += 1 * 4;
17589     d += 1 * 2;
17590     n -= 1;
17591   }
17592 
17593   return len;
17594 }
17595 
17596 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)17597 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t* dst_ptr,
17598                                                       size_t dst_len,
17599                                                       uint8_t* dst_palette_ptr,
17600                                                       size_t dst_palette_len,
17601                                                       const uint8_t* src_ptr,
17602                                                       size_t src_len) {
17603   size_t dst_len2 = dst_len / 2;
17604   size_t src_len4 = src_len / 4;
17605   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17606   uint8_t* d = dst_ptr;
17607   const uint8_t* s = src_ptr;
17608   size_t n = len;
17609 
17610   // TODO: unroll.
17611 
17612   while (n >= 1) {
17613     wuffs_base__poke_u16le__no_bounds_check(
17614         d + (0 * 2),
17615         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17616             wuffs_base__swap_u32_argb_abgr(
17617                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
17618 
17619     s += 1 * 4;
17620     d += 1 * 2;
17621     n -= 1;
17622   }
17623 
17624   return len;
17625 }
17626 
17627 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)17628 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over(
17629     uint8_t* dst_ptr,
17630     size_t dst_len,
17631     uint8_t* dst_palette_ptr,
17632     size_t dst_palette_len,
17633     const uint8_t* src_ptr,
17634     size_t src_len) {
17635   size_t dst_len2 = dst_len / 2;
17636   size_t src_len4 = src_len / 4;
17637   size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17638   uint8_t* d = dst_ptr;
17639   const uint8_t* s = src_ptr;
17640   size_t n = len;
17641 
17642   // TODO: unroll.
17643 
17644   while (n >= 1) {
17645     // Extract 16-bit color components.
17646     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17647     uint32_t sb = 0x101 * ((uint32_t)s[2]);
17648     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17649     uint32_t sr = 0x101 * ((uint32_t)s[0]);
17650 
17651     // Convert from 565 color to 16-bit color.
17652     uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17653     uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17654     uint32_t dr = (0x8421 * old_r5) >> 4;
17655     uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17656     uint32_t dg = (0x1041 * old_g6) >> 2;
17657     uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17658     uint32_t db = (0x8421 * old_b5) >> 4;
17659 
17660     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17661     uint32_t ia = 0xFFFF - sa;
17662 
17663     // Composite src (premul) over dst (premul).
17664     dr = sr + ((dr * ia) / 0xFFFF);
17665     dg = sg + ((dg * ia) / 0xFFFF);
17666     db = sb + ((db * ia) / 0xFFFF);
17667 
17668     // Convert from 16-bit color to 565 color and combine the components.
17669     uint32_t new_r5 = 0x1F & (dr >> 11);
17670     uint32_t new_g6 = 0x3F & (dg >> 10);
17671     uint32_t new_b5 = 0x1F & (db >> 11);
17672     uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17673     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17674 
17675     s += 1 * 4;
17676     d += 1 * 2;
17677     n -= 1;
17678   }
17679 
17680   return len;
17681 }
17682 
17683 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)17684 wuffs_base__pixel_swizzler__bgr_565__y(uint8_t* dst_ptr,
17685                                        size_t dst_len,
17686                                        uint8_t* dst_palette_ptr,
17687                                        size_t dst_palette_len,
17688                                        const uint8_t* src_ptr,
17689                                        size_t src_len) {
17690   size_t dst_len2 = dst_len / 2;
17691   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17692   uint8_t* d = dst_ptr;
17693   const uint8_t* s = src_ptr;
17694   size_t n = len;
17695 
17696   // TODO: unroll.
17697 
17698   while (n >= 1) {
17699     uint32_t y5 = s[0] >> 3;
17700     uint32_t y6 = s[0] >> 2;
17701     uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
17702     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17703 
17704     s += 1 * 1;
17705     d += 1 * 2;
17706     n -= 1;
17707   }
17708 
17709   return len;
17710 }
17711 
17712 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)17713 wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t* dst_ptr,
17714                                             size_t dst_len,
17715                                             uint8_t* dst_palette_ptr,
17716                                             size_t dst_palette_len,
17717                                             const uint8_t* src_ptr,
17718                                             size_t src_len) {
17719   size_t dst_len2 = dst_len / 2;
17720   size_t src_len2 = src_len / 2;
17721   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
17722   uint8_t* d = dst_ptr;
17723   const uint8_t* s = src_ptr;
17724   size_t n = len;
17725 
17726   // TODO: unroll.
17727 
17728   while (n >= 1) {
17729     uint32_t y5 = s[0] >> 3;
17730     uint32_t y6 = s[0] >> 2;
17731     uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
17732     wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17733 
17734     s += 1 * 2;
17735     d += 1 * 2;
17736     n -= 1;
17737   }
17738 
17739   return len;
17740 }
17741 
17742 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)17743 wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t* dst_ptr,
17744                                                 size_t dst_len,
17745                                                 uint8_t* dst_palette_ptr,
17746                                                 size_t dst_palette_len,
17747                                                 const uint8_t* src_ptr,
17748                                                 size_t src_len) {
17749   if (dst_palette_len !=
17750       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17751     return 0;
17752   }
17753   size_t dst_len2 = dst_len / 2;
17754   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17755   uint8_t* d = dst_ptr;
17756   const uint8_t* s = src_ptr;
17757   size_t n = len;
17758 
17759   const size_t loop_unroll_count = 4;
17760 
17761   while (n >= loop_unroll_count) {
17762     wuffs_base__poke_u16le__no_bounds_check(
17763         d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
17764                          dst_palette_ptr + ((size_t)s[0] * 4)));
17765     wuffs_base__poke_u16le__no_bounds_check(
17766         d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check(
17767                          dst_palette_ptr + ((size_t)s[1] * 4)));
17768     wuffs_base__poke_u16le__no_bounds_check(
17769         d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check(
17770                          dst_palette_ptr + ((size_t)s[2] * 4)));
17771     wuffs_base__poke_u16le__no_bounds_check(
17772         d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check(
17773                          dst_palette_ptr + ((size_t)s[3] * 4)));
17774 
17775     s += loop_unroll_count * 1;
17776     d += loop_unroll_count * 2;
17777     n -= loop_unroll_count;
17778   }
17779 
17780   while (n >= 1) {
17781     wuffs_base__poke_u16le__no_bounds_check(
17782         d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
17783                          dst_palette_ptr + ((size_t)s[0] * 4)));
17784 
17785     s += 1 * 1;
17786     d += 1 * 2;
17787     n -= 1;
17788   }
17789 
17790   return len;
17791 }
17792 
17793 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)17794 wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over(
17795     uint8_t* dst_ptr,
17796     size_t dst_len,
17797     uint8_t* dst_palette_ptr,
17798     size_t dst_palette_len,
17799     const uint8_t* src_ptr,
17800     size_t src_len) {
17801   if (dst_palette_len !=
17802       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17803     return 0;
17804   }
17805   size_t dst_len2 = dst_len / 2;
17806   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17807   uint8_t* d = dst_ptr;
17808   const uint8_t* s = src_ptr;
17809   size_t n = len;
17810 
17811   // TODO: unroll.
17812 
17813   while (n >= 1) {
17814     uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
17815         wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)));
17816     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
17817                                                           ((size_t)s[0] * 4));
17818     wuffs_base__poke_u16le__no_bounds_check(
17819         d + (0 * 2),
17820         wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17821             wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)));
17822 
17823     s += 1 * 1;
17824     d += 1 * 2;
17825     n -= 1;
17826   }
17827 
17828   return len;
17829 }
17830 
17831 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)17832 wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(
17833     uint8_t* dst_ptr,
17834     size_t dst_len,
17835     uint8_t* dst_palette_ptr,
17836     size_t dst_palette_len,
17837     const uint8_t* src_ptr,
17838     size_t src_len) {
17839   if (dst_palette_len !=
17840       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17841     return 0;
17842   }
17843   size_t dst_len2 = dst_len / 2;
17844   size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17845   uint8_t* d = dst_ptr;
17846   const uint8_t* s = src_ptr;
17847   size_t n = len;
17848 
17849   // TODO: unroll.
17850 
17851   while (n >= 1) {
17852     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
17853                                                           ((size_t)s[0] * 4));
17854     if (s0) {
17855       wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0);
17856     }
17857 
17858     s += 1 * 1;
17859     d += 1 * 2;
17860     n -= 1;
17861   }
17862 
17863   return len;
17864 }
17865 
17866 // --------
17867 
17868 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)17869 wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t* dst_ptr,
17870                                          size_t dst_len,
17871                                          uint8_t* dst_palette_ptr,
17872                                          size_t dst_palette_len,
17873                                          const uint8_t* src_ptr,
17874                                          size_t src_len) {
17875   size_t dst_len3 = dst_len / 3;
17876   size_t src_len2 = src_len / 2;
17877   size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
17878   uint8_t* d = dst_ptr;
17879   const uint8_t* s = src_ptr;
17880   size_t n = len;
17881 
17882   // TODO: unroll.
17883 
17884   while (n >= 1) {
17885     uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
17886         wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)));
17887     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17888 
17889     s += 1 * 2;
17890     d += 1 * 3;
17891     n -= 1;
17892   }
17893 
17894   return len;
17895 }
17896 
17897 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)17898 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t* dst_ptr,
17899                                                      size_t dst_len,
17900                                                      uint8_t* dst_palette_ptr,
17901                                                      size_t dst_palette_len,
17902                                                      const uint8_t* src_ptr,
17903                                                      size_t src_len) {
17904   size_t dst_len3 = dst_len / 3;
17905   size_t src_len4 = src_len / 4;
17906   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17907   uint8_t* d = dst_ptr;
17908   const uint8_t* s = src_ptr;
17909   size_t n = len;
17910 
17911   // TODO: unroll.
17912 
17913   while (n >= 1) {
17914     uint32_t s0 =
17915         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17916             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
17917     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17918 
17919     s += 1 * 4;
17920     d += 1 * 3;
17921     n -= 1;
17922   }
17923 
17924   return len;
17925 }
17926 
17927 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)17928 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src(
17929     uint8_t* dst_ptr,
17930     size_t dst_len,
17931     uint8_t* dst_palette_ptr,
17932     size_t dst_palette_len,
17933     const uint8_t* src_ptr,
17934     size_t src_len) {
17935   size_t dst_len3 = dst_len / 3;
17936   size_t src_len8 = src_len / 8;
17937   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
17938   uint8_t* d = dst_ptr;
17939   const uint8_t* s = src_ptr;
17940   size_t n = len;
17941 
17942   // TODO: unroll.
17943 
17944   while (n >= 1) {
17945     uint32_t s0 =
17946         wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
17947             wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
17948     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17949 
17950     s += 1 * 8;
17951     d += 1 * 3;
17952     n -= 1;
17953   }
17954 
17955   return len;
17956 }
17957 
17958 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)17959 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(
17960     uint8_t* dst_ptr,
17961     size_t dst_len,
17962     uint8_t* dst_palette_ptr,
17963     size_t dst_palette_len,
17964     const uint8_t* src_ptr,
17965     size_t src_len) {
17966   size_t dst_len3 = dst_len / 3;
17967   size_t src_len4 = src_len / 4;
17968   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17969   uint8_t* d = dst_ptr;
17970   const uint8_t* s = src_ptr;
17971   size_t n = len;
17972 
17973   // TODO: unroll.
17974 
17975   while (n >= 1) {
17976     // Extract 16-bit color components.
17977     uint32_t dr = 0x101 * ((uint32_t)d[2]);
17978     uint32_t dg = 0x101 * ((uint32_t)d[1]);
17979     uint32_t db = 0x101 * ((uint32_t)d[0]);
17980     uint32_t sa = 0x101 * ((uint32_t)s[3]);
17981     uint32_t sr = 0x101 * ((uint32_t)s[2]);
17982     uint32_t sg = 0x101 * ((uint32_t)s[1]);
17983     uint32_t sb = 0x101 * ((uint32_t)s[0]);
17984 
17985     // Calculate the inverse of the src-alpha: how much of the dst to keep.
17986     uint32_t ia = 0xFFFF - sa;
17987 
17988     // Composite src (nonpremul) over dst (premul).
17989     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17990     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17991     db = ((sb * sa) + (db * ia)) / 0xFFFF;
17992 
17993     // Convert from 16-bit color to 8-bit color.
17994     d[0] = (uint8_t)(db >> 8);
17995     d[1] = (uint8_t)(dg >> 8);
17996     d[2] = (uint8_t)(dr >> 8);
17997 
17998     s += 1 * 4;
17999     d += 1 * 3;
18000     n -= 1;
18001   }
18002 
18003   return len;
18004 }
18005 
18006 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)18007 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over(
18008     uint8_t* dst_ptr,
18009     size_t dst_len,
18010     uint8_t* dst_palette_ptr,
18011     size_t dst_palette_len,
18012     const uint8_t* src_ptr,
18013     size_t src_len) {
18014   size_t dst_len3 = dst_len / 3;
18015   size_t src_len8 = src_len / 8;
18016   size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
18017   uint8_t* d = dst_ptr;
18018   const uint8_t* s = src_ptr;
18019   size_t n = len;
18020 
18021   // TODO: unroll.
18022 
18023   while (n >= 1) {
18024     // Extract 16-bit color components.
18025     uint32_t dr = 0x101 * ((uint32_t)d[2]);
18026     uint32_t dg = 0x101 * ((uint32_t)d[1]);
18027     uint32_t db = 0x101 * ((uint32_t)d[0]);
18028     uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
18029     uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
18030     uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
18031     uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
18032 
18033     // Calculate the inverse of the src-alpha: how much of the dst to keep.
18034     uint32_t ia = 0xFFFF - sa;
18035 
18036     // Composite src (nonpremul) over dst (premul).
18037     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
18038     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
18039     db = ((sb * sa) + (db * ia)) / 0xFFFF;
18040 
18041     // Convert from 16-bit color to 8-bit color.
18042     d[0] = (uint8_t)(db >> 8);
18043     d[1] = (uint8_t)(dg >> 8);
18044     d[2] = (uint8_t)(dr >> 8);
18045 
18046     s += 1 * 8;
18047     d += 1 * 3;
18048     n -= 1;
18049   }
18050 
18051   return len;
18052 }
18053 
18054 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)18055 wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t* dst_ptr,
18056                                                   size_t dst_len,
18057                                                   uint8_t* dst_palette_ptr,
18058                                                   size_t dst_palette_len,
18059                                                   const uint8_t* src_ptr,
18060                                                   size_t src_len) {
18061   size_t dst_len3 = dst_len / 3;
18062   size_t src_len4 = src_len / 4;
18063   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18064   uint8_t* d = dst_ptr;
18065   const uint8_t* s = src_ptr;
18066   size_t n = len;
18067 
18068   while (n >= 1) {
18069     uint8_t s0 = s[0];
18070     uint8_t s1 = s[1];
18071     uint8_t s2 = s[2];
18072     d[0] = s0;
18073     d[1] = s1;
18074     d[2] = s2;
18075 
18076     s += 1 * 4;
18077     d += 1 * 3;
18078     n -= 1;
18079   }
18080 
18081   return len;
18082 }
18083 
18084 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)18085 wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t* dst_ptr,
18086                                                        size_t dst_len,
18087                                                        uint8_t* dst_palette_ptr,
18088                                                        size_t dst_palette_len,
18089                                                        const uint8_t* src_ptr,
18090                                                        size_t src_len) {
18091   size_t dst_len3 = dst_len / 3;
18092   size_t src_len4 = src_len / 4;
18093   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18094   uint8_t* d = dst_ptr;
18095   const uint8_t* s = src_ptr;
18096   size_t n = len;
18097 
18098   while (n >= 1) {
18099     // Extract 16-bit color components.
18100     uint32_t dr = 0x101 * ((uint32_t)d[2]);
18101     uint32_t dg = 0x101 * ((uint32_t)d[1]);
18102     uint32_t db = 0x101 * ((uint32_t)d[0]);
18103     uint32_t sa = 0x101 * ((uint32_t)s[3]);
18104     uint32_t sr = 0x101 * ((uint32_t)s[2]);
18105     uint32_t sg = 0x101 * ((uint32_t)s[1]);
18106     uint32_t sb = 0x101 * ((uint32_t)s[0]);
18107 
18108     // Calculate the inverse of the src-alpha: how much of the dst to keep.
18109     uint32_t ia = 0xFFFF - sa;
18110 
18111     // Composite src (premul) over dst (premul).
18112     dr = sr + ((dr * ia) / 0xFFFF);
18113     dg = sg + ((dg * ia) / 0xFFFF);
18114     db = sb + ((db * ia) / 0xFFFF);
18115 
18116     // Convert from 16-bit color to 8-bit color.
18117     d[0] = (uint8_t)(db >> 8);
18118     d[1] = (uint8_t)(dg >> 8);
18119     d[2] = (uint8_t)(dr >> 8);
18120 
18121     s += 1 * 4;
18122     d += 1 * 3;
18123     n -= 1;
18124   }
18125 
18126   return len;
18127 }
18128 
18129 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)18130 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t* dst_ptr,
18131                                                      size_t dst_len,
18132                                                      uint8_t* dst_palette_ptr,
18133                                                      size_t dst_palette_len,
18134                                                      const uint8_t* src_ptr,
18135                                                      size_t src_len) {
18136   size_t dst_len3 = dst_len / 3;
18137   size_t src_len4 = src_len / 4;
18138   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18139   uint8_t* d = dst_ptr;
18140   const uint8_t* s = src_ptr;
18141   size_t n = len;
18142 
18143   // TODO: unroll.
18144 
18145   while (n >= 1) {
18146     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18147         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
18148             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18149     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
18150 
18151     s += 1 * 4;
18152     d += 1 * 3;
18153     n -= 1;
18154   }
18155 
18156   return len;
18157 }
18158 
18159 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)18160 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over(
18161     uint8_t* dst_ptr,
18162     size_t dst_len,
18163     uint8_t* dst_palette_ptr,
18164     size_t dst_palette_len,
18165     const uint8_t* src_ptr,
18166     size_t src_len) {
18167   size_t dst_len3 = dst_len / 3;
18168   size_t src_len4 = src_len / 4;
18169   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18170   uint8_t* d = dst_ptr;
18171   const uint8_t* s = src_ptr;
18172   size_t n = len;
18173 
18174   // TODO: unroll.
18175 
18176   while (n >= 1) {
18177     // Extract 16-bit color components.
18178     uint32_t dr = 0x101 * ((uint32_t)d[2]);
18179     uint32_t dg = 0x101 * ((uint32_t)d[1]);
18180     uint32_t db = 0x101 * ((uint32_t)d[0]);
18181     uint32_t sa = 0x101 * ((uint32_t)s[3]);
18182     uint32_t sb = 0x101 * ((uint32_t)s[2]);
18183     uint32_t sg = 0x101 * ((uint32_t)s[1]);
18184     uint32_t sr = 0x101 * ((uint32_t)s[0]);
18185 
18186     // Calculate the inverse of the src-alpha: how much of the dst to keep.
18187     uint32_t ia = 0xFFFF - sa;
18188 
18189     // Composite src (nonpremul) over dst (premul).
18190     dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
18191     dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
18192     db = ((sb * sa) + (db * ia)) / 0xFFFF;
18193 
18194     // Convert from 16-bit color to 8-bit color.
18195     d[0] = (uint8_t)(db >> 8);
18196     d[1] = (uint8_t)(dg >> 8);
18197     d[2] = (uint8_t)(dr >> 8);
18198 
18199     s += 1 * 4;
18200     d += 1 * 3;
18201     n -= 1;
18202   }
18203 
18204   return len;
18205 }
18206 
18207 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)18208 wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t* dst_ptr,
18209                                                   size_t dst_len,
18210                                                   uint8_t* dst_palette_ptr,
18211                                                   size_t dst_palette_len,
18212                                                   const uint8_t* src_ptr,
18213                                                   size_t src_len) {
18214   size_t dst_len3 = dst_len / 3;
18215   size_t src_len4 = src_len / 4;
18216   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18217   uint8_t* d = dst_ptr;
18218   const uint8_t* s = src_ptr;
18219   size_t n = len;
18220 
18221   while (n >= 1) {
18222     uint8_t s0 = s[0];
18223     uint8_t s1 = s[1];
18224     uint8_t s2 = s[2];
18225     d[0] = s2;
18226     d[1] = s1;
18227     d[2] = s0;
18228 
18229     s += 1 * 4;
18230     d += 1 * 3;
18231     n -= 1;
18232   }
18233 
18234   return len;
18235 }
18236 
18237 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)18238 wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t* dst_ptr,
18239                                                        size_t dst_len,
18240                                                        uint8_t* dst_palette_ptr,
18241                                                        size_t dst_palette_len,
18242                                                        const uint8_t* src_ptr,
18243                                                        size_t src_len) {
18244   size_t dst_len3 = dst_len / 3;
18245   size_t src_len4 = src_len / 4;
18246   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18247   uint8_t* d = dst_ptr;
18248   const uint8_t* s = src_ptr;
18249   size_t n = len;
18250 
18251   while (n >= 1) {
18252     // Extract 16-bit color components.
18253     uint32_t dr = 0x101 * ((uint32_t)d[2]);
18254     uint32_t dg = 0x101 * ((uint32_t)d[1]);
18255     uint32_t db = 0x101 * ((uint32_t)d[0]);
18256     uint32_t sa = 0x101 * ((uint32_t)s[3]);
18257     uint32_t sb = 0x101 * ((uint32_t)s[2]);
18258     uint32_t sg = 0x101 * ((uint32_t)s[1]);
18259     uint32_t sr = 0x101 * ((uint32_t)s[0]);
18260 
18261     // Calculate the inverse of the src-alpha: how much of the dst to keep.
18262     uint32_t ia = 0xFFFF - sa;
18263 
18264     // Composite src (premul) over dst (premul).
18265     dr = sr + ((dr * ia) / 0xFFFF);
18266     dg = sg + ((dg * ia) / 0xFFFF);
18267     db = sb + ((db * ia) / 0xFFFF);
18268 
18269     // Convert from 16-bit color to 8-bit color.
18270     d[0] = (uint8_t)(db >> 8);
18271     d[1] = (uint8_t)(dg >> 8);
18272     d[2] = (uint8_t)(dr >> 8);
18273 
18274     s += 1 * 4;
18275     d += 1 * 3;
18276     n -= 1;
18277   }
18278 
18279   return len;
18280 }
18281 
18282 // --------
18283 
18284 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)18285 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(
18286     uint8_t* dst_ptr,
18287     size_t dst_len,
18288     uint8_t* dst_palette_ptr,
18289     size_t dst_palette_len,
18290     const uint8_t* src_ptr,
18291     size_t src_len) {
18292   size_t dst_len4 = dst_len / 4;
18293   size_t src_len4 = src_len / 4;
18294   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18295   uint8_t* d = dst_ptr;
18296   const uint8_t* s = src_ptr;
18297   size_t n = len;
18298 
18299   while (n >= 1) {
18300     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18301     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18302     wuffs_base__poke_u32le__no_bounds_check(
18303         d + (0 * 4),
18304         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
18305 
18306     s += 1 * 4;
18307     d += 1 * 4;
18308     n -= 1;
18309   }
18310 
18311   return len;
18312 }
18313 
18314 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)18315 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src(
18316     uint8_t* dst_ptr,
18317     size_t dst_len,
18318     uint8_t* dst_palette_ptr,
18319     size_t dst_palette_len,
18320     const uint8_t* src_ptr,
18321     size_t src_len) {
18322   size_t dst_len4 = dst_len / 4;
18323   size_t src_len8 = src_len / 8;
18324   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18325   uint8_t* d = dst_ptr;
18326   const uint8_t* s = src_ptr;
18327 
18328   size_t n = len;
18329   while (n >= 1) {
18330     wuffs_base__poke_u32le__no_bounds_check(
18331         d + (0 * 4), wuffs_base__color_u64__as__color_u32(
18332                          wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
18333 
18334     s += 1 * 8;
18335     d += 1 * 4;
18336     n -= 1;
18337   }
18338   return len;
18339 }
18340 
18341 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)18342 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over(
18343     uint8_t* dst_ptr,
18344     size_t dst_len,
18345     uint8_t* dst_palette_ptr,
18346     size_t dst_palette_len,
18347     const uint8_t* src_ptr,
18348     size_t src_len) {
18349   size_t dst_len4 = dst_len / 4;
18350   size_t src_len8 = src_len / 8;
18351   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18352   uint8_t* d = dst_ptr;
18353   const uint8_t* s = src_ptr;
18354   size_t n = len;
18355 
18356   while (n >= 1) {
18357     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
18358         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
18359     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18360     wuffs_base__poke_u32le__no_bounds_check(
18361         d + (0 * 4),
18362         wuffs_base__color_u64__as__color_u32(
18363             wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
18364 
18365     s += 1 * 8;
18366     d += 1 * 4;
18367     n -= 1;
18368   }
18369 
18370   return len;
18371 }
18372 
18373 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)18374 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src(
18375     uint8_t* dst_ptr,
18376     size_t dst_len,
18377     uint8_t* dst_palette_ptr,
18378     size_t dst_palette_len,
18379     const uint8_t* src_ptr,
18380     size_t src_len) {
18381   size_t dst_len4 = dst_len / 4;
18382   size_t src_len4 = src_len / 4;
18383   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18384   uint8_t* d = dst_ptr;
18385   const uint8_t* s = src_ptr;
18386   size_t n = len;
18387 
18388   while (n >= 1) {
18389     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18390     wuffs_base__poke_u32le__no_bounds_check(
18391         d + (0 * 4),
18392         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
18393 
18394     s += 1 * 4;
18395     d += 1 * 4;
18396     n -= 1;
18397   }
18398 
18399   return len;
18400 }
18401 
18402 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)18403 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over(
18404     uint8_t* dst_ptr,
18405     size_t dst_len,
18406     uint8_t* dst_palette_ptr,
18407     size_t dst_palette_len,
18408     const uint8_t* src_ptr,
18409     size_t src_len) {
18410   size_t dst_len4 = dst_len / 4;
18411   size_t src_len4 = src_len / 4;
18412   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18413   uint8_t* d = dst_ptr;
18414   const uint8_t* s = src_ptr;
18415   size_t n = len;
18416 
18417   while (n >= 1) {
18418     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18419     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18420     wuffs_base__poke_u32le__no_bounds_check(
18421         d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
18422 
18423     s += 1 * 4;
18424     d += 1 * 4;
18425     n -= 1;
18426   }
18427 
18428   return len;
18429 }
18430 
18431 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)18432 wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over(
18433     uint8_t* dst_ptr,
18434     size_t dst_len,
18435     uint8_t* dst_palette_ptr,
18436     size_t dst_palette_len,
18437     const uint8_t* src_ptr,
18438     size_t src_len) {
18439   if (dst_palette_len !=
18440       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
18441     return 0;
18442   }
18443   size_t dst_len4 = dst_len / 4;
18444   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
18445   uint8_t* d = dst_ptr;
18446   const uint8_t* s = src_ptr;
18447   size_t n = len;
18448 
18449   // TODO: unroll.
18450 
18451   while (n >= 1) {
18452     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18453     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
18454                                                           ((size_t)s[0] * 4));
18455     wuffs_base__poke_u32le__no_bounds_check(
18456         d + (0 * 4),
18457         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
18458 
18459     s += 1 * 1;
18460     d += 1 * 4;
18461     n -= 1;
18462   }
18463 
18464   return len;
18465 }
18466 
18467 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)18468 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over(
18469     uint8_t* dst_ptr,
18470     size_t dst_len,
18471     uint8_t* dst_palette_ptr,
18472     size_t dst_palette_len,
18473     const uint8_t* src_ptr,
18474     size_t src_len) {
18475   size_t dst_len4 = dst_len / 4;
18476   size_t src_len4 = src_len / 4;
18477   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18478   uint8_t* d = dst_ptr;
18479   const uint8_t* s = src_ptr;
18480   size_t n = len;
18481 
18482   while (n >= 1) {
18483     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18484     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18485         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18486     wuffs_base__poke_u32le__no_bounds_check(
18487         d + (0 * 4),
18488         wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
18489 
18490     s += 1 * 4;
18491     d += 1 * 4;
18492     n -= 1;
18493   }
18494 
18495   return len;
18496 }
18497 
18498 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)18499 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src(
18500     uint8_t* dst_ptr,
18501     size_t dst_len,
18502     uint8_t* dst_palette_ptr,
18503     size_t dst_palette_len,
18504     const uint8_t* src_ptr,
18505     size_t src_len) {
18506   size_t dst_len4 = dst_len / 4;
18507   size_t src_len4 = src_len / 4;
18508   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18509   uint8_t* d = dst_ptr;
18510   const uint8_t* s = src_ptr;
18511   size_t n = len;
18512 
18513   while (n >= 1) {
18514     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18515         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18516     wuffs_base__poke_u32le__no_bounds_check(
18517         d + (0 * 4),
18518         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
18519 
18520     s += 1 * 4;
18521     d += 1 * 4;
18522     n -= 1;
18523   }
18524 
18525   return len;
18526 }
18527 
18528 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)18529 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over(
18530     uint8_t* dst_ptr,
18531     size_t dst_len,
18532     uint8_t* dst_palette_ptr,
18533     size_t dst_palette_len,
18534     const uint8_t* src_ptr,
18535     size_t src_len) {
18536   size_t dst_len4 = dst_len / 4;
18537   size_t src_len4 = src_len / 4;
18538   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18539   uint8_t* d = dst_ptr;
18540   const uint8_t* s = src_ptr;
18541   size_t n = len;
18542 
18543   while (n >= 1) {
18544     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18545     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18546         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18547     wuffs_base__poke_u32le__no_bounds_check(
18548         d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
18549 
18550     s += 1 * 4;
18551     d += 1 * 4;
18552     n -= 1;
18553   }
18554 
18555   return len;
18556 }
18557 
18558 // --------
18559 
18560 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)18561 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src(
18562     uint8_t* dst_ptr,
18563     size_t dst_len,
18564     uint8_t* dst_palette_ptr,
18565     size_t dst_palette_len,
18566     const uint8_t* src_ptr,
18567     size_t src_len) {
18568   size_t dst_len8 = dst_len / 8;
18569   size_t src_len4 = src_len / 4;
18570   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18571   uint8_t* d = dst_ptr;
18572   const uint8_t* s = src_ptr;
18573 
18574   size_t n = len;
18575   while (n >= 1) {
18576     uint8_t s0 = s[0];
18577     uint8_t s1 = s[1];
18578     uint8_t s2 = s[2];
18579     uint8_t s3 = s[3];
18580     d[0] = s0;
18581     d[1] = s0;
18582     d[2] = s1;
18583     d[3] = s1;
18584     d[4] = s2;
18585     d[5] = s2;
18586     d[6] = s3;
18587     d[7] = s3;
18588 
18589     s += 1 * 4;
18590     d += 1 * 8;
18591     n -= 1;
18592   }
18593   return len;
18594 }
18595 
18596 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)18597 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over(
18598     uint8_t* dst_ptr,
18599     size_t dst_len,
18600     uint8_t* dst_palette_ptr,
18601     size_t dst_palette_len,
18602     const uint8_t* src_ptr,
18603     size_t src_len) {
18604   size_t dst_len8 = dst_len / 8;
18605   size_t src_len4 = src_len / 4;
18606   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18607   uint8_t* d = dst_ptr;
18608   const uint8_t* s = src_ptr;
18609 
18610   size_t n = len;
18611   while (n >= 1) {
18612     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18613     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18614         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18615     wuffs_base__poke_u64le__no_bounds_check(
18616         d + (0 * 8),
18617         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18618 
18619     s += 1 * 4;
18620     d += 1 * 8;
18621     n -= 1;
18622   }
18623   return len;
18624 }
18625 
18626 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)18627 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(
18628     uint8_t* dst_ptr,
18629     size_t dst_len,
18630     uint8_t* dst_palette_ptr,
18631     size_t dst_palette_len,
18632     const uint8_t* src_ptr,
18633     size_t src_len) {
18634   size_t dst_len8 = dst_len / 8;
18635   size_t src_len8 = src_len / 8;
18636   size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
18637   uint8_t* d = dst_ptr;
18638   const uint8_t* s = src_ptr;
18639 
18640   size_t n = len;
18641   while (n >= 1) {
18642     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18643     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18644     wuffs_base__poke_u64le__no_bounds_check(
18645         d + (0 * 8),
18646         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18647 
18648     s += 1 * 8;
18649     d += 1 * 8;
18650     n -= 1;
18651   }
18652   return len;
18653 }
18654 
18655 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)18656 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src(
18657     uint8_t* dst_ptr,
18658     size_t dst_len,
18659     uint8_t* dst_palette_ptr,
18660     size_t dst_palette_len,
18661     const uint8_t* src_ptr,
18662     size_t src_len) {
18663   size_t dst_len8 = dst_len / 8;
18664   size_t src_len4 = src_len / 4;
18665   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18666   uint8_t* d = dst_ptr;
18667   const uint8_t* s = src_ptr;
18668 
18669   size_t n = len;
18670   while (n >= 1) {
18671     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18672         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
18673             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18674     wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
18675 
18676     s += 1 * 4;
18677     d += 1 * 8;
18678     n -= 1;
18679   }
18680   return len;
18681 }
18682 
18683 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)18684 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over(
18685     uint8_t* dst_ptr,
18686     size_t dst_len,
18687     uint8_t* dst_palette_ptr,
18688     size_t dst_palette_len,
18689     const uint8_t* src_ptr,
18690     size_t src_len) {
18691   size_t dst_len8 = dst_len / 8;
18692   size_t src_len4 = src_len / 4;
18693   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18694   uint8_t* d = dst_ptr;
18695   const uint8_t* s = src_ptr;
18696 
18697   size_t n = len;
18698   while (n >= 1) {
18699     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18700     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18701         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18702     wuffs_base__poke_u64le__no_bounds_check(
18703         d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
18704 
18705     s += 1 * 4;
18706     d += 1 * 8;
18707     n -= 1;
18708   }
18709   return len;
18710 }
18711 
18712 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)18713 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(
18714     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   if (dst_palette_len !=
18721       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
18722     return 0;
18723   }
18724   size_t dst_len8 = dst_len / 8;
18725   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
18726   uint8_t* d = dst_ptr;
18727   const uint8_t* s = src_ptr;
18728   size_t n = len;
18729 
18730   while (n >= 1) {
18731     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18732     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18733         wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
18734                                                 ((size_t)s[0] * 4)));
18735     wuffs_base__poke_u64le__no_bounds_check(
18736         d + (0 * 8),
18737         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18738 
18739     s += 1 * 1;
18740     d += 1 * 8;
18741     n -= 1;
18742   }
18743 
18744   return len;
18745 }
18746 
18747 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)18748 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src(
18749     uint8_t* dst_ptr,
18750     size_t dst_len,
18751     uint8_t* dst_palette_ptr,
18752     size_t dst_palette_len,
18753     const uint8_t* src_ptr,
18754     size_t src_len) {
18755   size_t dst_len8 = dst_len / 8;
18756   size_t src_len4 = src_len / 4;
18757   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18758   uint8_t* d = dst_ptr;
18759   const uint8_t* s = src_ptr;
18760 
18761   size_t n = len;
18762   while (n >= 1) {
18763     uint8_t s0 = s[0];
18764     uint8_t s1 = s[1];
18765     uint8_t s2 = s[2];
18766     uint8_t s3 = s[3];
18767     d[0] = s2;
18768     d[1] = s2;
18769     d[2] = s1;
18770     d[3] = s1;
18771     d[4] = s0;
18772     d[5] = s0;
18773     d[6] = s3;
18774     d[7] = s3;
18775 
18776     s += 1 * 4;
18777     d += 1 * 8;
18778     n -= 1;
18779   }
18780   return len;
18781 }
18782 
18783 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)18784 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over(
18785     uint8_t* dst_ptr,
18786     size_t dst_len,
18787     uint8_t* dst_palette_ptr,
18788     size_t dst_palette_len,
18789     const uint8_t* src_ptr,
18790     size_t src_len) {
18791   size_t dst_len8 = dst_len / 8;
18792   size_t src_len4 = src_len / 4;
18793   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18794   uint8_t* d = dst_ptr;
18795   const uint8_t* s = src_ptr;
18796 
18797   size_t n = len;
18798   while (n >= 1) {
18799     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18800     uint64_t s0 =
18801         wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
18802             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18803     wuffs_base__poke_u64le__no_bounds_check(
18804         d + (0 * 8),
18805         wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18806 
18807     s += 1 * 4;
18808     d += 1 * 8;
18809     n -= 1;
18810   }
18811   return len;
18812 }
18813 
18814 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)18815 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src(
18816     uint8_t* dst_ptr,
18817     size_t dst_len,
18818     uint8_t* dst_palette_ptr,
18819     size_t dst_palette_len,
18820     const uint8_t* src_ptr,
18821     size_t src_len) {
18822   size_t dst_len8 = dst_len / 8;
18823   size_t src_len4 = src_len / 4;
18824   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18825   uint8_t* d = dst_ptr;
18826   const uint8_t* s = src_ptr;
18827 
18828   size_t n = len;
18829   while (n >= 1) {
18830     uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18831         wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
18832             wuffs_base__swap_u32_argb_abgr(
18833                 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
18834     wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
18835 
18836     s += 1 * 4;
18837     d += 1 * 8;
18838     n -= 1;
18839   }
18840   return len;
18841 }
18842 
18843 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)18844 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over(
18845     uint8_t* dst_ptr,
18846     size_t dst_len,
18847     uint8_t* dst_palette_ptr,
18848     size_t dst_palette_len,
18849     const uint8_t* src_ptr,
18850     size_t src_len) {
18851   size_t dst_len8 = dst_len / 8;
18852   size_t src_len4 = src_len / 4;
18853   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18854   uint8_t* d = dst_ptr;
18855   const uint8_t* s = src_ptr;
18856 
18857   size_t n = len;
18858   while (n >= 1) {
18859     uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18860     uint64_t s0 =
18861         wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
18862             wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18863     wuffs_base__poke_u64le__no_bounds_check(
18864         d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
18865 
18866     s += 1 * 4;
18867     d += 1 * 8;
18868     n -= 1;
18869   }
18870   return len;
18871 }
18872 
18873 // --------
18874 
18875 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)18876 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
18877     uint8_t* dst_ptr,
18878     size_t dst_len,
18879     uint8_t* dst_palette_ptr,
18880     size_t dst_palette_len,
18881     const uint8_t* src_ptr,
18882     size_t src_len) {
18883   size_t dst_len4 = dst_len / 4;
18884   size_t src_len4 = src_len / 4;
18885   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18886   uint8_t* d = dst_ptr;
18887   const uint8_t* s = src_ptr;
18888   size_t n = len;
18889 
18890   // TODO: unroll.
18891 
18892   while (n >= 1) {
18893     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18894     wuffs_base__poke_u32le__no_bounds_check(
18895         d + (0 * 4),
18896         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
18897 
18898     s += 1 * 4;
18899     d += 1 * 4;
18900     n -= 1;
18901   }
18902 
18903   return len;
18904 }
18905 
18906 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)18907 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src(
18908     uint8_t* dst_ptr,
18909     size_t dst_len,
18910     uint8_t* dst_palette_ptr,
18911     size_t dst_palette_len,
18912     const uint8_t* src_ptr,
18913     size_t src_len) {
18914   size_t dst_len4 = dst_len / 4;
18915   size_t src_len8 = src_len / 8;
18916   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18917   uint8_t* d = dst_ptr;
18918   const uint8_t* s = src_ptr;
18919   size_t n = len;
18920 
18921   // TODO: unroll.
18922 
18923   while (n >= 1) {
18924     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18925     wuffs_base__poke_u32le__no_bounds_check(
18926         d + (0 * 4),
18927         wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0));
18928 
18929     s += 1 * 8;
18930     d += 1 * 4;
18931     n -= 1;
18932   }
18933 
18934   return len;
18935 }
18936 
18937 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)18938 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(
18939     uint8_t* dst_ptr,
18940     size_t dst_len,
18941     uint8_t* dst_palette_ptr,
18942     size_t dst_palette_len,
18943     const uint8_t* src_ptr,
18944     size_t src_len) {
18945   size_t dst_len4 = dst_len / 4;
18946   size_t src_len4 = src_len / 4;
18947   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18948   uint8_t* d = dst_ptr;
18949   const uint8_t* s = src_ptr;
18950   size_t n = len;
18951 
18952   // TODO: unroll.
18953 
18954   while (n >= 1) {
18955     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18956     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18957     wuffs_base__poke_u32le__no_bounds_check(
18958         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
18959 
18960     s += 1 * 4;
18961     d += 1 * 4;
18962     n -= 1;
18963   }
18964 
18965   return len;
18966 }
18967 
18968 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)18969 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over(
18970     uint8_t* dst_ptr,
18971     size_t dst_len,
18972     uint8_t* dst_palette_ptr,
18973     size_t dst_palette_len,
18974     const uint8_t* src_ptr,
18975     size_t src_len) {
18976   size_t dst_len4 = dst_len / 4;
18977   size_t src_len8 = src_len / 8;
18978   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18979   uint8_t* d = dst_ptr;
18980   const uint8_t* s = src_ptr;
18981   size_t n = len;
18982 
18983   // TODO: unroll.
18984 
18985   while (n >= 1) {
18986     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
18987         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
18988     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18989     wuffs_base__poke_u32le__no_bounds_check(
18990         d + (0 * 4),
18991         wuffs_base__color_u64__as__color_u32(
18992             wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
18993 
18994     s += 1 * 8;
18995     d += 1 * 4;
18996     n -= 1;
18997   }
18998 
18999   return len;
19000 }
19001 
19002 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)19003 wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over(
19004     uint8_t* dst_ptr,
19005     size_t dst_len,
19006     uint8_t* dst_palette_ptr,
19007     size_t dst_palette_len,
19008     const uint8_t* src_ptr,
19009     size_t src_len) {
19010   size_t dst_len4 = dst_len / 4;
19011   size_t src_len4 = src_len / 4;
19012   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19013   uint8_t* d = dst_ptr;
19014   const uint8_t* s = src_ptr;
19015   size_t n = len;
19016 
19017   // TODO: unroll.
19018 
19019   while (n >= 1) {
19020     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19021     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
19022     wuffs_base__poke_u32le__no_bounds_check(
19023         d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
19024 
19025     s += 1 * 4;
19026     d += 1 * 4;
19027     n -= 1;
19028   }
19029 
19030   return len;
19031 }
19032 
19033 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)19034 wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over(
19035     uint8_t* dst_ptr,
19036     size_t dst_len,
19037     uint8_t* dst_palette_ptr,
19038     size_t dst_palette_len,
19039     const uint8_t* src_ptr,
19040     size_t src_len) {
19041   if (dst_palette_len !=
19042       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19043     return 0;
19044   }
19045   size_t dst_len4 = dst_len / 4;
19046   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19047   uint8_t* d = dst_ptr;
19048   const uint8_t* s = src_ptr;
19049   size_t n = len;
19050 
19051   // TODO: unroll.
19052 
19053   while (n >= 1) {
19054     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19055     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19056                                                           ((size_t)s[0] * 4));
19057     wuffs_base__poke_u32le__no_bounds_check(
19058         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
19059 
19060     s += 1 * 1;
19061     d += 1 * 4;
19062     n -= 1;
19063   }
19064 
19065   return len;
19066 }
19067 
19068 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)19069 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
19070     uint8_t* dst_ptr,
19071     size_t dst_len,
19072     uint8_t* dst_palette_ptr,
19073     size_t dst_palette_len,
19074     const uint8_t* src_ptr,
19075     size_t src_len) {
19076   size_t dst_len4 = dst_len / 4;
19077   size_t src_len4 = src_len / 4;
19078   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19079   uint8_t* d = dst_ptr;
19080   const uint8_t* s = src_ptr;
19081   size_t n = len;
19082 
19083   // TODO: unroll.
19084 
19085   while (n >= 1) {
19086     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
19087         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19088     wuffs_base__poke_u32le__no_bounds_check(
19089         d + (0 * 4),
19090         wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
19091 
19092     s += 1 * 4;
19093     d += 1 * 4;
19094     n -= 1;
19095   }
19096 
19097   return len;
19098 }
19099 
19100 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)19101 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over(
19102     uint8_t* dst_ptr,
19103     size_t dst_len,
19104     uint8_t* dst_palette_ptr,
19105     size_t dst_palette_len,
19106     const uint8_t* src_ptr,
19107     size_t src_len) {
19108   size_t dst_len4 = dst_len / 4;
19109   size_t src_len4 = src_len / 4;
19110   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19111   uint8_t* d = dst_ptr;
19112   const uint8_t* s = src_ptr;
19113   size_t n = len;
19114 
19115   // TODO: unroll.
19116 
19117   while (n >= 1) {
19118     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19119     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
19120         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19121     wuffs_base__poke_u32le__no_bounds_check(
19122         d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
19123 
19124     s += 1 * 4;
19125     d += 1 * 4;
19126     n -= 1;
19127   }
19128 
19129   return len;
19130 }
19131 
19132 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)19133 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src(
19134     uint8_t* dst_ptr,
19135     size_t dst_len,
19136     uint8_t* dst_palette_ptr,
19137     size_t dst_palette_len,
19138     const uint8_t* src_ptr,
19139     size_t src_len) {
19140   size_t dst_len4 = dst_len / 4;
19141   size_t src_len8 = src_len / 8;
19142   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19143   uint8_t* d = dst_ptr;
19144   const uint8_t* s = src_ptr;
19145   size_t n = len;
19146 
19147   // TODO: unroll.
19148 
19149   while (n >= 1) {
19150     uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
19151     wuffs_base__poke_u32le__no_bounds_check(
19152         d + (0 * 4),
19153         wuffs_base__swap_u32_argb_abgr(
19154             wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
19155                 s0)));
19156 
19157     s += 1 * 8;
19158     d += 1 * 4;
19159     n -= 1;
19160   }
19161 
19162   return len;
19163 }
19164 
19165 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)19166 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over(
19167     uint8_t* dst_ptr,
19168     size_t dst_len,
19169     uint8_t* dst_palette_ptr,
19170     size_t dst_palette_len,
19171     const uint8_t* src_ptr,
19172     size_t src_len) {
19173   size_t dst_len4 = dst_len / 4;
19174   size_t src_len8 = src_len / 8;
19175   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19176   uint8_t* d = dst_ptr;
19177   const uint8_t* s = src_ptr;
19178   size_t n = len;
19179 
19180   // TODO: unroll.
19181 
19182   while (n >= 1) {
19183     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
19184         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
19185     uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
19186         wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
19187     wuffs_base__poke_u32le__no_bounds_check(
19188         d + (0 * 4),
19189         wuffs_base__color_u64__as__color_u32(
19190             wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
19191 
19192     s += 1 * 8;
19193     d += 1 * 4;
19194     n -= 1;
19195   }
19196 
19197   return len;
19198 }
19199 
19200 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)19201 wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over(
19202     uint8_t* dst_ptr,
19203     size_t dst_len,
19204     uint8_t* dst_palette_ptr,
19205     size_t dst_palette_len,
19206     const uint8_t* src_ptr,
19207     size_t src_len) {
19208   size_t dst_len4 = dst_len / 4;
19209   size_t src_len4 = src_len / 4;
19210   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19211   uint8_t* d = dst_ptr;
19212   const uint8_t* s = src_ptr;
19213   size_t n = len;
19214 
19215   while (n >= 1) {
19216     uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19217     uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
19218         wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19219     wuffs_base__poke_u32le__no_bounds_check(
19220         d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
19221 
19222     s += 1 * 4;
19223     d += 1 * 4;
19224     n -= 1;
19225   }
19226 
19227   return len;
19228 }
19229 
19230 // --------
19231 
19232 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)19233 wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr,
19234                                       size_t dst_len,
19235                                       uint8_t* dst_palette_ptr,
19236                                       size_t dst_palette_len,
19237                                       const uint8_t* src_ptr,
19238                                       size_t src_len) {
19239   size_t dst_len4 = dst_len / 4;
19240   size_t src_len3 = src_len / 3;
19241   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
19242   uint8_t* d = dst_ptr;
19243   const uint8_t* s = src_ptr;
19244   size_t n = len;
19245 
19246   // TODO: unroll.
19247 
19248   while (n >= 1) {
19249     wuffs_base__poke_u32le__no_bounds_check(
19250         d + (0 * 4),
19251         0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3)));
19252 
19253     s += 1 * 3;
19254     d += 1 * 4;
19255     n -= 1;
19256   }
19257 
19258   return len;
19259 }
19260 
19261 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)19262 wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr,
19263                                           size_t dst_len,
19264                                           uint8_t* dst_palette_ptr,
19265                                           size_t dst_palette_len,
19266                                           const uint8_t* src_ptr,
19267                                           size_t src_len) {
19268   size_t dst_len4 = dst_len / 4;
19269   size_t src_len2 = src_len / 2;
19270   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
19271   uint8_t* d = dst_ptr;
19272   const uint8_t* s = src_ptr;
19273   size_t n = len;
19274 
19275   // TODO: unroll.
19276 
19277   while (n >= 1) {
19278     wuffs_base__poke_u32le__no_bounds_check(
19279         d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19280                          wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))));
19281 
19282     s += 1 * 2;
19283     d += 1 * 4;
19284     n -= 1;
19285   }
19286 
19287   return len;
19288 }
19289 
19290 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)19291 wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t* dst_ptr,
19292                                        size_t dst_len,
19293                                        uint8_t* dst_palette_ptr,
19294                                        size_t dst_palette_len,
19295                                        const uint8_t* src_ptr,
19296                                        size_t src_len) {
19297   size_t dst_len4 = dst_len / 4;
19298   size_t src_len4 = src_len / 4;
19299   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19300   uint8_t* d = dst_ptr;
19301   const uint8_t* s = src_ptr;
19302   size_t n = len;
19303 
19304   // TODO: unroll.
19305 
19306   while (n >= 1) {
19307     wuffs_base__poke_u32le__no_bounds_check(
19308         d + (0 * 4),
19309         0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19310 
19311     s += 1 * 4;
19312     d += 1 * 4;
19313     n -= 1;
19314   }
19315 
19316   return len;
19317 }
19318 
19319 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
19320 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19321 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
19322 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)19323 wuffs_base__pixel_swizzler__bgrw__rgb__sse42(uint8_t* dst_ptr,
19324                                              size_t dst_len,
19325                                              uint8_t* dst_palette_ptr,
19326                                              size_t dst_palette_len,
19327                                              const uint8_t* src_ptr,
19328                                              size_t src_len) {
19329   size_t dst_len4 = dst_len / 4;
19330   size_t src_len3 = src_len / 3;
19331   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
19332   uint8_t* d = dst_ptr;
19333   const uint8_t* s = src_ptr;
19334   size_t n = len;
19335 
19336   __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B,  //
19337                                  +0x00, +0x06, +0x07, +0x08,  //
19338                                  +0x00, +0x03, +0x04, +0x05,  //
19339                                  +0x00, +0x00, +0x01, +0x02);
19340   __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00,  //
19341                                -0x01, +0x00, +0x00, +0x00,  //
19342                                -0x01, +0x00, +0x00, +0x00,  //
19343                                -0x01, +0x00, +0x00, +0x00);
19344 
19345   while (n >= 6) {
19346     __m128i x;
19347     x = _mm_lddqu_si128((const __m128i*)(const void*)s);
19348     x = _mm_shuffle_epi8(x, shuffle);
19349     x = _mm_or_si128(x, or_ff);
19350     _mm_storeu_si128((__m128i*)(void*)d, x);
19351 
19352     s += 4 * 3;
19353     d += 4 * 4;
19354     n -= 4;
19355   }
19356 
19357   while (n >= 1) {
19358     uint8_t b0 = s[0];
19359     uint8_t b1 = s[1];
19360     uint8_t b2 = s[2];
19361     d[0] = b2;
19362     d[1] = b1;
19363     d[2] = b0;
19364     d[3] = 0xFF;
19365 
19366     s += 1 * 3;
19367     d += 1 * 4;
19368     n -= 1;
19369   }
19370 
19371   return len;
19372 }
19373 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19374 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
19375 
19376 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)19377 wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t* dst_ptr,
19378                                       size_t dst_len,
19379                                       uint8_t* dst_palette_ptr,
19380                                       size_t dst_palette_len,
19381                                       const uint8_t* src_ptr,
19382                                       size_t src_len) {
19383   size_t dst_len4 = dst_len / 4;
19384   size_t src_len3 = src_len / 3;
19385   size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
19386   uint8_t* d = dst_ptr;
19387   const uint8_t* s = src_ptr;
19388   size_t n = len;
19389 
19390   while (n >= 1) {
19391     uint8_t b0 = s[0];
19392     uint8_t b1 = s[1];
19393     uint8_t b2 = s[2];
19394     d[0] = b2;
19395     d[1] = b1;
19396     d[2] = b0;
19397     d[3] = 0xFF;
19398 
19399     s += 1 * 3;
19400     d += 1 * 4;
19401     n -= 1;
19402   }
19403 
19404   return len;
19405 }
19406 
19407 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)19408 wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t* dst_ptr,
19409                                        size_t dst_len,
19410                                        uint8_t* dst_palette_ptr,
19411                                        size_t dst_palette_len,
19412                                        const uint8_t* src_ptr,
19413                                        size_t src_len) {
19414   size_t dst_len4 = dst_len / 4;
19415   size_t src_len4 = src_len / 4;
19416   size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19417   uint8_t* d = dst_ptr;
19418   const uint8_t* s = src_ptr;
19419   size_t n = len;
19420 
19421   // TODO: unroll.
19422 
19423   while (n >= 1) {
19424     uint8_t b0 = s[0];
19425     uint8_t b1 = s[1];
19426     uint8_t b2 = s[2];
19427     d[0] = b2;
19428     d[1] = b1;
19429     d[2] = b0;
19430     d[3] = 0xFF;
19431 
19432     s += 1 * 4;
19433     d += 1 * 4;
19434     n -= 1;
19435   }
19436 
19437   return len;
19438 }
19439 
19440 // --------
19441 
19442 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)19443 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t* dst_ptr,
19444                                              size_t dst_len,
19445                                              uint8_t* dst_palette_ptr,
19446                                              size_t dst_palette_len,
19447                                              const uint8_t* src_ptr,
19448                                              size_t src_len) {
19449   size_t dst_len8 = dst_len / 8;
19450   size_t src_len3 = src_len / 3;
19451   size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
19452   uint8_t* d = dst_ptr;
19453   const uint8_t* s = src_ptr;
19454   size_t n = len;
19455 
19456   while (n >= 1) {
19457     uint8_t s0 = s[0];
19458     uint8_t s1 = s[1];
19459     uint8_t s2 = s[2];
19460     d[0] = s0;
19461     d[1] = s0;
19462     d[2] = s1;
19463     d[3] = s1;
19464     d[4] = s2;
19465     d[5] = s2;
19466     d[6] = 0xFF;
19467     d[7] = 0xFF;
19468 
19469     s += 1 * 3;
19470     d += 1 * 8;
19471     n -= 1;
19472   }
19473 
19474   return len;
19475 }
19476 
19477 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)19478 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t* dst_ptr,
19479                                                  size_t dst_len,
19480                                                  uint8_t* dst_palette_ptr,
19481                                                  size_t dst_palette_len,
19482                                                  const uint8_t* src_ptr,
19483                                                  size_t src_len) {
19484   size_t dst_len8 = dst_len / 8;
19485   size_t src_len2 = src_len / 2;
19486   size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
19487   uint8_t* d = dst_ptr;
19488   const uint8_t* s = src_ptr;
19489   size_t n = len;
19490 
19491   while (n >= 1) {
19492     wuffs_base__poke_u64le__no_bounds_check(
19493         d + (0 * 8),
19494         wuffs_base__color_u32__as__color_u64(
19495             wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19496                 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
19497 
19498     s += 1 * 2;
19499     d += 1 * 8;
19500     n -= 1;
19501   }
19502 
19503   return len;
19504 }
19505 
19506 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)19507 wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t* dst_ptr,
19508                                               size_t dst_len,
19509                                               uint8_t* dst_palette_ptr,
19510                                               size_t dst_palette_len,
19511                                               const uint8_t* src_ptr,
19512                                               size_t src_len) {
19513   size_t dst_len8 = dst_len / 8;
19514   size_t src_len4 = src_len / 4;
19515   size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
19516   uint8_t* d = dst_ptr;
19517   const uint8_t* s = src_ptr;
19518   size_t n = len;
19519 
19520   while (n >= 1) {
19521     uint8_t s0 = s[0];
19522     uint8_t s1 = s[1];
19523     uint8_t s2 = s[2];
19524     d[0] = s0;
19525     d[1] = s0;
19526     d[2] = s1;
19527     d[3] = s1;
19528     d[4] = s2;
19529     d[5] = s2;
19530     d[6] = 0xFF;
19531     d[7] = 0xFF;
19532 
19533     s += 1 * 4;
19534     d += 1 * 8;
19535     n -= 1;
19536   }
19537 
19538   return len;
19539 }
19540 
19541 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)19542 wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t* dst_ptr,
19543                                              size_t dst_len,
19544                                              uint8_t* dst_palette_ptr,
19545                                              size_t dst_palette_len,
19546                                              const uint8_t* src_ptr,
19547                                              size_t src_len) {
19548   size_t dst_len8 = dst_len / 8;
19549   size_t src_len3 = src_len / 3;
19550   size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
19551   uint8_t* d = dst_ptr;
19552   const uint8_t* s = src_ptr;
19553   size_t n = len;
19554 
19555   while (n >= 1) {
19556     uint8_t s0 = s[0];
19557     uint8_t s1 = s[1];
19558     uint8_t s2 = s[2];
19559     d[0] = s2;
19560     d[1] = s2;
19561     d[2] = s1;
19562     d[3] = s1;
19563     d[4] = s0;
19564     d[5] = s0;
19565     d[6] = 0xFF;
19566     d[7] = 0xFF;
19567 
19568     s += 1 * 3;
19569     d += 1 * 8;
19570     n -= 1;
19571   }
19572 
19573   return len;
19574 }
19575 
19576 // --------
19577 
19578 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)19579 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src(
19580     uint8_t* dst_ptr,
19581     size_t dst_len,
19582     uint8_t* dst_palette_ptr,
19583     size_t dst_palette_len,
19584     const uint8_t* src_ptr,
19585     size_t src_len) {
19586   size_t dst_len4 = dst_len / 4;
19587   size_t src_len8 = src_len / 8;
19588   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19589   uint8_t* d = dst_ptr;
19590   const uint8_t* s = src_ptr;
19591 
19592   size_t n = len;
19593   while (n >= 1) {
19594     wuffs_base__poke_u32le__no_bounds_check(
19595         d + (0 * 4), wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(
19596                          wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
19597 
19598     s += 1 * 8;
19599     d += 1 * 4;
19600     n -= 1;
19601   }
19602   return len;
19603 }
19604 
19605 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)19606 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over(
19607     uint8_t* dst_ptr,
19608     size_t dst_len,
19609     uint8_t* dst_palette_ptr,
19610     size_t dst_palette_len,
19611     const uint8_t* src_ptr,
19612     size_t src_len) {
19613   size_t dst_len4 = dst_len / 4;
19614   size_t src_len8 = src_len / 8;
19615   size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19616   uint8_t* d = dst_ptr;
19617   const uint8_t* s = src_ptr;
19618   size_t n = len;
19619 
19620   while (n >= 1) {
19621     uint64_t d0 = wuffs_base__color_u32__as__color_u64(
19622         wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
19623     uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
19624         wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
19625     wuffs_base__poke_u32le__no_bounds_check(
19626         d + (0 * 4),
19627         wuffs_base__color_u64__as__color_u32(
19628             wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
19629 
19630     s += 1 * 8;
19631     d += 1 * 4;
19632     n -= 1;
19633   }
19634 
19635   return len;
19636 }
19637 
19638 // --------
19639 
19640 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)19641 wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t* dst_ptr,
19642                                           size_t dst_len,
19643                                           uint8_t* dst_palette_ptr,
19644                                           size_t dst_palette_len,
19645                                           const uint8_t* src_ptr,
19646                                           size_t src_len) {
19647   size_t dst_len4 = dst_len / 4;
19648   size_t src_len2 = src_len / 2;
19649   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
19650   uint8_t* d = dst_ptr;
19651   const uint8_t* s = src_ptr;
19652   size_t n = len;
19653 
19654   // TODO: unroll.
19655 
19656   while (n >= 1) {
19657     wuffs_base__poke_u32le__no_bounds_check(
19658         d + (0 * 4),
19659         wuffs_base__swap_u32_argb_abgr(
19660             wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19661                 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
19662 
19663     s += 1 * 2;
19664     d += 1 * 4;
19665     n -= 1;
19666   }
19667 
19668   return len;
19669 }
19670 
19671 // --------
19672 
19673 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)19674 wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr,
19675                                             size_t dst_len,
19676                                             uint8_t* dst_palette_ptr,
19677                                             size_t dst_palette_len,
19678                                             const uint8_t* src_ptr,
19679                                             size_t src_len) {
19680   if (dst_palette_len !=
19681       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19682     return 0;
19683   }
19684   size_t dst_len3 = dst_len / 3;
19685   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19686   uint8_t* d = dst_ptr;
19687   const uint8_t* s = src_ptr;
19688   size_t n = len;
19689 
19690   const size_t loop_unroll_count = 4;
19691 
19692   // The comparison in the while condition is ">", not ">=", because with
19693   // ">=", the last 4-byte store could write past the end of the dst slice.
19694   //
19695   // Each 4-byte store writes one too many bytes, but a subsequent store
19696   // will overwrite that with the correct byte. There is always another
19697   // store, whether a 4-byte store in this loop or a 1-byte store in the
19698   // next loop.
19699   while (n > loop_unroll_count) {
19700     wuffs_base__poke_u32le__no_bounds_check(
19701         d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(
19702                          dst_palette_ptr + ((size_t)s[0] * 4)));
19703     wuffs_base__poke_u32le__no_bounds_check(
19704         d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check(
19705                          dst_palette_ptr + ((size_t)s[1] * 4)));
19706     wuffs_base__poke_u32le__no_bounds_check(
19707         d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check(
19708                          dst_palette_ptr + ((size_t)s[2] * 4)));
19709     wuffs_base__poke_u32le__no_bounds_check(
19710         d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check(
19711                          dst_palette_ptr + ((size_t)s[3] * 4)));
19712 
19713     s += loop_unroll_count * 1;
19714     d += loop_unroll_count * 3;
19715     n -= loop_unroll_count;
19716   }
19717 
19718   while (n >= 1) {
19719     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19720                                                           ((size_t)s[0] * 4));
19721     wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19722 
19723     s += 1 * 1;
19724     d += 1 * 3;
19725     n -= 1;
19726   }
19727 
19728   return len;
19729 }
19730 
19731 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)19732 wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over(
19733     uint8_t* dst_ptr,
19734     size_t dst_len,
19735     uint8_t* dst_palette_ptr,
19736     size_t dst_palette_len,
19737     const uint8_t* src_ptr,
19738     size_t src_len) {
19739   if (dst_palette_len !=
19740       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19741     return 0;
19742   }
19743   size_t dst_len3 = dst_len / 3;
19744   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19745   uint8_t* d = dst_ptr;
19746   const uint8_t* s = src_ptr;
19747   size_t n = len;
19748 
19749   // TODO: unroll.
19750 
19751   while (n >= 1) {
19752     uint32_t d0 =
19753         wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000;
19754     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19755                                                           ((size_t)s[0] * 4));
19756     wuffs_base__poke_u24le__no_bounds_check(
19757         d + (0 * 3), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
19758 
19759     s += 1 * 1;
19760     d += 1 * 3;
19761     n -= 1;
19762   }
19763 
19764   return len;
19765 }
19766 
19767 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)19768 wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(
19769     uint8_t* dst_ptr,
19770     size_t dst_len,
19771     uint8_t* dst_palette_ptr,
19772     size_t dst_palette_len,
19773     const uint8_t* src_ptr,
19774     size_t src_len) {
19775   if (dst_palette_len !=
19776       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19777     return 0;
19778   }
19779   size_t dst_len3 = dst_len / 3;
19780   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19781   uint8_t* d = dst_ptr;
19782   const uint8_t* s = src_ptr;
19783   size_t n = len;
19784 
19785   const size_t loop_unroll_count = 4;
19786 
19787   while (n >= loop_unroll_count) {
19788     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19789                                                           ((size_t)s[0] * 4));
19790     if (s0) {
19791       wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19792     }
19793     uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19794                                                           ((size_t)s[1] * 4));
19795     if (s1) {
19796       wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1);
19797     }
19798     uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19799                                                           ((size_t)s[2] * 4));
19800     if (s2) {
19801       wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2);
19802     }
19803     uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19804                                                           ((size_t)s[3] * 4));
19805     if (s3) {
19806       wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3);
19807     }
19808 
19809     s += loop_unroll_count * 1;
19810     d += loop_unroll_count * 3;
19811     n -= loop_unroll_count;
19812   }
19813 
19814   while (n >= 1) {
19815     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19816                                                           ((size_t)s[0] * 4));
19817     if (s0) {
19818       wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19819     }
19820 
19821     s += 1 * 1;
19822     d += 1 * 3;
19823     n -= 1;
19824   }
19825 
19826   return len;
19827 }
19828 
19829 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)19830 wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr,
19831                                       size_t dst_len,
19832                                       uint8_t* dst_palette_ptr,
19833                                       size_t dst_palette_len,
19834                                       const uint8_t* src_ptr,
19835                                       size_t src_len) {
19836   size_t dst_len3 = dst_len / 3;
19837   size_t src_len4 = src_len / 4;
19838   size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
19839   uint8_t* d = dst_ptr;
19840   const uint8_t* s = src_ptr;
19841   size_t n = len;
19842 
19843   // TODO: unroll.
19844 
19845   while (n >= 1) {
19846     wuffs_base__poke_u24le__no_bounds_check(
19847         d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19848 
19849     s += 1 * 4;
19850     d += 1 * 3;
19851     n -= 1;
19852   }
19853 
19854   return len;
19855 }
19856 
19857 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)19858 wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr,
19859                                    size_t dst_len,
19860                                    uint8_t* dst_palette_ptr,
19861                                    size_t dst_palette_len,
19862                                    const uint8_t* src_ptr,
19863                                    size_t src_len) {
19864   size_t dst_len3 = dst_len / 3;
19865   size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19866   uint8_t* d = dst_ptr;
19867   const uint8_t* s = src_ptr;
19868   size_t n = len;
19869 
19870   // TODO: unroll.
19871 
19872   while (n >= 1) {
19873     uint8_t s0 = s[0];
19874     d[0] = s0;
19875     d[1] = s0;
19876     d[2] = s0;
19877 
19878     s += 1 * 1;
19879     d += 1 * 3;
19880     n -= 1;
19881   }
19882 
19883   return len;
19884 }
19885 
19886 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)19887 wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t* dst_ptr,
19888                                         size_t dst_len,
19889                                         uint8_t* dst_palette_ptr,
19890                                         size_t dst_palette_len,
19891                                         const uint8_t* src_ptr,
19892                                         size_t src_len) {
19893   size_t dst_len3 = dst_len / 3;
19894   size_t src_len2 = src_len / 2;
19895   size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
19896   uint8_t* d = dst_ptr;
19897   const uint8_t* s = src_ptr;
19898   size_t n = len;
19899 
19900   // TODO: unroll.
19901 
19902   while (n >= 1) {
19903     uint8_t s0 = s[0];
19904     d[0] = s0;
19905     d[1] = s0;
19906     d[2] = s0;
19907 
19908     s += 1 * 2;
19909     d += 1 * 3;
19910     n -= 1;
19911   }
19912 
19913   return len;
19914 }
19915 
19916 // --------
19917 
19918 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)19919 wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t* dst_ptr,
19920                                              size_t dst_len,
19921                                              uint8_t* dst_palette_ptr,
19922                                              size_t dst_palette_len,
19923                                              const uint8_t* src_ptr,
19924                                              size_t src_len) {
19925   if (dst_palette_len !=
19926       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19927     return 0;
19928   }
19929   size_t dst_len4 = dst_len / 4;
19930   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19931   uint8_t* d = dst_ptr;
19932   const uint8_t* s = src_ptr;
19933   size_t n = len;
19934 
19935   const size_t loop_unroll_count = 4;
19936 
19937   while (n >= loop_unroll_count) {
19938     wuffs_base__poke_u32le__no_bounds_check(
19939         d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
19940                          dst_palette_ptr + ((size_t)s[0] * 4)));
19941     wuffs_base__poke_u32le__no_bounds_check(
19942         d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check(
19943                          dst_palette_ptr + ((size_t)s[1] * 4)));
19944     wuffs_base__poke_u32le__no_bounds_check(
19945         d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check(
19946                          dst_palette_ptr + ((size_t)s[2] * 4)));
19947     wuffs_base__poke_u32le__no_bounds_check(
19948         d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check(
19949                          dst_palette_ptr + ((size_t)s[3] * 4)));
19950 
19951     s += loop_unroll_count * 1;
19952     d += loop_unroll_count * 4;
19953     n -= loop_unroll_count;
19954   }
19955 
19956   while (n >= 1) {
19957     wuffs_base__poke_u32le__no_bounds_check(
19958         d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
19959                          dst_palette_ptr + ((size_t)s[0] * 4)));
19960 
19961     s += 1 * 1;
19962     d += 1 * 4;
19963     n -= 1;
19964   }
19965 
19966   return len;
19967 }
19968 
19969 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)19970 wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(
19971     uint8_t* dst_ptr,
19972     size_t dst_len,
19973     uint8_t* dst_palette_ptr,
19974     size_t dst_palette_len,
19975     const uint8_t* src_ptr,
19976     size_t src_len) {
19977   if (dst_palette_len !=
19978       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19979     return 0;
19980   }
19981   size_t dst_len4 = dst_len / 4;
19982   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19983   uint8_t* d = dst_ptr;
19984   const uint8_t* s = src_ptr;
19985   size_t n = len;
19986 
19987   const size_t loop_unroll_count = 4;
19988 
19989   while (n >= loop_unroll_count) {
19990     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19991                                                           ((size_t)s[0] * 4));
19992     if (s0) {
19993       wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
19994     }
19995     uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19996                                                           ((size_t)s[1] * 4));
19997     if (s1) {
19998       wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1);
19999     }
20000     uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20001                                                           ((size_t)s[2] * 4));
20002     if (s2) {
20003       wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2);
20004     }
20005     uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20006                                                           ((size_t)s[3] * 4));
20007     if (s3) {
20008       wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3);
20009     }
20010 
20011     s += loop_unroll_count * 1;
20012     d += loop_unroll_count * 4;
20013     n -= loop_unroll_count;
20014   }
20015 
20016   while (n >= 1) {
20017     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20018                                                           ((size_t)s[0] * 4));
20019     if (s0) {
20020       wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
20021     }
20022 
20023     s += 1 * 1;
20024     d += 1 * 4;
20025     n -= 1;
20026   }
20027 
20028   return len;
20029 }
20030 
20031 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
20032 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20033 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
20034 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)20035 wuffs_base__pixel_swizzler__xxxx__y__sse42(uint8_t* dst_ptr,
20036                                            size_t dst_len,
20037                                            uint8_t* dst_palette_ptr,
20038                                            size_t dst_palette_len,
20039                                            const uint8_t* src_ptr,
20040                                            size_t src_len) {
20041   size_t dst_len4 = dst_len / 4;
20042   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
20043   uint8_t* d = dst_ptr;
20044   const uint8_t* s = src_ptr;
20045   size_t n = len;
20046 
20047   __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03,  //
20048                                  +0x02, +0x02, +0x02, +0x02,  //
20049                                  +0x01, +0x01, +0x01, +0x01,  //
20050                                  +0x00, +0x00, +0x00, +0x00);
20051   __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00,  //
20052                                -0x01, +0x00, +0x00, +0x00,  //
20053                                -0x01, +0x00, +0x00, +0x00,  //
20054                                -0x01, +0x00, +0x00, +0x00);
20055 
20056   while (n >= 4) {
20057     __m128i x;
20058     x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s)));
20059     x = _mm_shuffle_epi8(x, shuffle);
20060     x = _mm_or_si128(x, or_ff);
20061     _mm_storeu_si128((__m128i*)(void*)d, x);
20062 
20063     s += 4 * 1;
20064     d += 4 * 4;
20065     n -= 4;
20066   }
20067 
20068   while (n >= 1) {
20069     wuffs_base__poke_u32le__no_bounds_check(
20070         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
20071 
20072     s += 1 * 1;
20073     d += 1 * 4;
20074     n -= 1;
20075   }
20076 
20077   return len;
20078 }
20079 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20080 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
20081 
20082 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)20083 wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr,
20084                                     size_t dst_len,
20085                                     uint8_t* dst_palette_ptr,
20086                                     size_t dst_palette_len,
20087                                     const uint8_t* src_ptr,
20088                                     size_t src_len) {
20089   size_t dst_len4 = dst_len / 4;
20090   size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
20091   uint8_t* d = dst_ptr;
20092   const uint8_t* s = src_ptr;
20093   size_t n = len;
20094 
20095   while (n >= 1) {
20096     wuffs_base__poke_u32le__no_bounds_check(
20097         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
20098 
20099     s += 1 * 1;
20100     d += 1 * 4;
20101     n -= 1;
20102   }
20103 
20104   return len;
20105 }
20106 
20107 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)20108 wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t* dst_ptr,
20109                                          size_t dst_len,
20110                                          uint8_t* dst_palette_ptr,
20111                                          size_t dst_palette_len,
20112                                          const uint8_t* src_ptr,
20113                                          size_t src_len) {
20114   size_t dst_len4 = dst_len / 4;
20115   size_t src_len2 = src_len / 2;
20116   size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
20117   uint8_t* d = dst_ptr;
20118   const uint8_t* s = src_ptr;
20119   size_t n = len;
20120 
20121   while (n >= 1) {
20122     wuffs_base__poke_u32le__no_bounds_check(
20123         d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
20124 
20125     s += 1 * 2;
20126     d += 1 * 4;
20127     n -= 1;
20128   }
20129 
20130   return len;
20131 }
20132 
20133 // --------
20134 
20135 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)20136 wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t* dst_ptr,
20137                                                  size_t dst_len,
20138                                                  uint8_t* dst_palette_ptr,
20139                                                  size_t dst_palette_len,
20140                                                  const uint8_t* src_ptr,
20141                                                  size_t src_len) {
20142   if (dst_palette_len !=
20143       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20144     return 0;
20145   }
20146   size_t dst_len8 = dst_len / 8;
20147   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
20148   uint8_t* d = dst_ptr;
20149   const uint8_t* s = src_ptr;
20150   size_t n = len;
20151 
20152   while (n >= 1) {
20153     wuffs_base__poke_u64le__no_bounds_check(
20154         d + (0 * 8), wuffs_base__color_u32__as__color_u64(
20155                          wuffs_base__peek_u32le__no_bounds_check(
20156                              dst_palette_ptr + ((size_t)s[0] * 4))));
20157 
20158     s += 1 * 1;
20159     d += 1 * 8;
20160     n -= 1;
20161   }
20162 
20163   return len;
20164 }
20165 
20166 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)20167 wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over(
20168     uint8_t* dst_ptr,
20169     size_t dst_len,
20170     uint8_t* dst_palette_ptr,
20171     size_t dst_palette_len,
20172     const uint8_t* src_ptr,
20173     size_t src_len) {
20174   if (dst_palette_len !=
20175       WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20176     return 0;
20177   }
20178   size_t dst_len8 = dst_len / 8;
20179   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
20180   uint8_t* d = dst_ptr;
20181   const uint8_t* s = src_ptr;
20182   size_t n = len;
20183 
20184   while (n >= 1) {
20185     uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20186                                                           ((size_t)s[0] * 4));
20187     if (s0) {
20188       wuffs_base__poke_u64le__no_bounds_check(
20189           d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0));
20190     }
20191 
20192     s += 1 * 1;
20193     d += 1 * 8;
20194     n -= 1;
20195   }
20196 
20197   return len;
20198 }
20199 
20200 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)20201 wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t* dst_ptr,
20202                                         size_t dst_len,
20203                                         uint8_t* dst_palette_ptr,
20204                                         size_t dst_palette_len,
20205                                         const uint8_t* src_ptr,
20206                                         size_t src_len) {
20207   size_t dst_len8 = dst_len / 8;
20208   size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
20209   uint8_t* d = dst_ptr;
20210   const uint8_t* s = src_ptr;
20211   size_t n = len;
20212 
20213   while (n >= 1) {
20214     wuffs_base__poke_u64le__no_bounds_check(
20215         d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0]));
20216 
20217     s += 1 * 1;
20218     d += 1 * 8;
20219     n -= 1;
20220   }
20221 
20222   return len;
20223 }
20224 
20225 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)20226 wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t* dst_ptr,
20227                                              size_t dst_len,
20228                                              uint8_t* dst_palette_ptr,
20229                                              size_t dst_palette_len,
20230                                              const uint8_t* src_ptr,
20231                                              size_t src_len) {
20232   size_t dst_len8 = dst_len / 8;
20233   size_t src_len2 = src_len / 2;
20234   size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
20235   uint8_t* d = dst_ptr;
20236   const uint8_t* s = src_ptr;
20237   size_t n = len;
20238 
20239   while (n >= 1) {
20240     uint64_t s0 =
20241         ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2))));
20242     wuffs_base__poke_u64le__no_bounds_check(
20243         d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0));
20244 
20245     s += 1 * 2;
20246     d += 1 * 8;
20247     n -= 1;
20248   }
20249 
20250   return len;
20251 }
20252 
20253 // --------
20254 
20255 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)20256 wuffs_base__pixel_swizzler__y__y_16be(uint8_t* dst_ptr,
20257                                       size_t dst_len,
20258                                       uint8_t* dst_palette_ptr,
20259                                       size_t dst_palette_len,
20260                                       const uint8_t* src_ptr,
20261                                       size_t src_len) {
20262   size_t src_len2 = src_len / 2;
20263   size_t len = (dst_len < src_len2) ? dst_len : src_len2;
20264   uint8_t* d = dst_ptr;
20265   const uint8_t* s = src_ptr;
20266   size_t n = len;
20267 
20268   while (n >= 1) {
20269     d[0] = s[0];
20270 
20271     s += 1 * 2;
20272     d += 1 * 1;
20273     n -= 1;
20274   }
20275 
20276   return len;
20277 }
20278 
20279 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)20280 wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t* dst_ptr,
20281                                            size_t dst_len,
20282                                            uint8_t* dst_palette_ptr,
20283                                            size_t dst_palette_len,
20284                                            const uint8_t* src_ptr,
20285                                            size_t src_len) {
20286   size_t dst_len2 = dst_len / 2;
20287   size_t src_len2 = src_len / 2;
20288   size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
20289   uint8_t* d = dst_ptr;
20290   const uint8_t* s = src_ptr;
20291   size_t n = len;
20292 
20293   while (n >= 1) {
20294     uint8_t s0 = s[0];
20295     uint8_t s1 = s[1];
20296     d[0] = s1;
20297     d[1] = s0;
20298 
20299     s += 1 * 2;
20300     d += 1 * 2;
20301     n -= 1;
20302   }
20303 
20304   return len;
20305 }
20306 
20307 // --------
20308 
20309 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)20310 wuffs_base__pixel_swizzler__transparent_black_src(
20311     uint8_t* dst_ptr,
20312     size_t dst_len,
20313     uint8_t* dst_palette_ptr,
20314     size_t dst_palette_len,
20315     uint64_t num_pixels,
20316     uint32_t dst_pixfmt_bytes_per_pixel) {
20317   uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
20318   if (n > num_pixels) {
20319     n = num_pixels;
20320   }
20321   memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel)));
20322   return n;
20323 }
20324 
20325 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)20326 wuffs_base__pixel_swizzler__transparent_black_src_over(
20327     uint8_t* dst_ptr,
20328     size_t dst_len,
20329     uint8_t* dst_palette_ptr,
20330     size_t dst_palette_len,
20331     uint64_t num_pixels,
20332     uint32_t dst_pixfmt_bytes_per_pixel) {
20333   uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
20334   if (n > num_pixels) {
20335     n = num_pixels;
20336   }
20337   return n;
20338 }
20339 
20340 // --------
20341 
20342 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)20343 wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler* p,
20344                                        wuffs_base__pixel_format dst_pixfmt,
20345                                        wuffs_base__slice_u8 dst_palette,
20346                                        wuffs_base__slice_u8 src_palette,
20347                                        wuffs_base__pixel_blend blend) {
20348   switch (dst_pixfmt.repr) {
20349     case WUFFS_BASE__PIXEL_FORMAT__Y:
20350       return wuffs_base__pixel_swizzler__copy_1_1;
20351 
20352     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20353       return wuffs_base__pixel_swizzler__bgr_565__y;
20354 
20355     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20356     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20357       return wuffs_base__pixel_swizzler__xxx__y;
20358 
20359     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20360     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20361     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20362     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20363     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20364     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20365     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20366     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20367 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20368       if (wuffs_base__cpu_arch__have_x86_sse42()) {
20369         return wuffs_base__pixel_swizzler__xxxx__y__sse42;
20370       }
20371 #endif
20372       return wuffs_base__pixel_swizzler__xxxx__y;
20373 
20374     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20375     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20376     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
20377     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
20378       return wuffs_base__pixel_swizzler__xxxxxxxx__y;
20379   }
20380   return NULL;
20381 }
20382 
20383 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)20384 wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler* p,
20385                                             wuffs_base__pixel_format dst_pixfmt,
20386                                             wuffs_base__slice_u8 dst_palette,
20387                                             wuffs_base__slice_u8 src_palette,
20388                                             wuffs_base__pixel_blend blend) {
20389   switch (dst_pixfmt.repr) {
20390     case WUFFS_BASE__PIXEL_FORMAT__Y:
20391       return wuffs_base__pixel_swizzler__y__y_16be;
20392 
20393     case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
20394       return wuffs_base__pixel_swizzler__y_16le__y_16be;
20395 
20396     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
20397       return wuffs_base__pixel_swizzler__copy_2_2;
20398 
20399     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20400       return wuffs_base__pixel_swizzler__bgr_565__y_16be;
20401 
20402     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20403     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20404       return wuffs_base__pixel_swizzler__xxx__y_16be;
20405 
20406     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20407     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20408     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20409     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20410     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20411     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20412     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20413     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20414       return wuffs_base__pixel_swizzler__xxxx__y_16be;
20415 
20416     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20417     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20418     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
20419     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
20420       return wuffs_base__pixel_swizzler__xxxxxxxx__y_16be;
20421   }
20422   return NULL;
20423 }
20424 
20425 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)20426 wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
20427     wuffs_base__pixel_swizzler* p,
20428     wuffs_base__pixel_format dst_pixfmt,
20429     wuffs_base__slice_u8 dst_palette,
20430     wuffs_base__slice_u8 src_palette,
20431     wuffs_base__pixel_blend blend) {
20432   switch (dst_pixfmt.repr) {
20433     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
20434       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20435           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20436         return NULL;
20437       }
20438       switch (blend) {
20439         case WUFFS_BASE__PIXEL_BLEND__SRC:
20440           return wuffs_base__pixel_swizzler__copy_1_1;
20441       }
20442       return NULL;
20443 
20444     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20445       switch (blend) {
20446         case WUFFS_BASE__PIXEL_BLEND__SRC:
20447           if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
20448                   dst_palette.ptr, dst_palette.len, src_palette.ptr,
20449                   src_palette.len, true) !=
20450               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20451             return NULL;
20452           }
20453           return wuffs_base__pixel_swizzler__bgr_565__index__src;
20454         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20455           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20456               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20457             return NULL;
20458           }
20459           return wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over;
20460       }
20461       return NULL;
20462 
20463     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20464       switch (blend) {
20465         case WUFFS_BASE__PIXEL_BLEND__SRC:
20466           if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
20467                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20468                   src_palette.len) !=
20469               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20470             return NULL;
20471           }
20472           return wuffs_base__pixel_swizzler__xxx__index__src;
20473         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20474           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20475               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20476             return NULL;
20477           }
20478           return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over;
20479       }
20480       return NULL;
20481 
20482     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20483       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20484           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20485         return NULL;
20486       }
20487       switch (blend) {
20488         case WUFFS_BASE__PIXEL_BLEND__SRC:
20489           return wuffs_base__pixel_swizzler__xxxx__index__src;
20490         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20491           return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
20492       }
20493       return NULL;
20494 
20495     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20496       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20497           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20498         return NULL;
20499       }
20500       switch (blend) {
20501         case WUFFS_BASE__PIXEL_BLEND__SRC:
20502           return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
20503         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20504           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over;
20505       }
20506       return NULL;
20507 
20508     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20509       switch (blend) {
20510         case WUFFS_BASE__PIXEL_BLEND__SRC:
20511           if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
20512                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20513                   src_palette.len) !=
20514               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20515             return NULL;
20516           }
20517           return wuffs_base__pixel_swizzler__xxxx__index__src;
20518         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20519           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20520               WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20521             return NULL;
20522           }
20523           return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
20524       }
20525       return NULL;
20526 
20527     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20528       // TODO.
20529       break;
20530 
20531     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20532       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20533               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20534               src_palette.len) !=
20535           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20536         return NULL;
20537       }
20538       switch (blend) {
20539         case WUFFS_BASE__PIXEL_BLEND__SRC:
20540           return wuffs_base__pixel_swizzler__xxxx__index__src;
20541         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20542           return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
20543       }
20544       return NULL;
20545 
20546     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20547       switch (blend) {
20548         case WUFFS_BASE__PIXEL_BLEND__SRC:
20549           if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
20550                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20551                   src_palette.len) !=
20552               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20553             return NULL;
20554           }
20555           return wuffs_base__pixel_swizzler__xxxx__index__src;
20556         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20557           if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20558                   dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20559                   src_palette.len) !=
20560               (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20561             return NULL;
20562           }
20563           return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
20564       }
20565       return NULL;
20566 
20567     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20568       // TODO.
20569       break;
20570   }
20571   return NULL;
20572 }
20573 
20574 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)20575 wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
20576     wuffs_base__pixel_swizzler* p,
20577     wuffs_base__pixel_format dst_pixfmt,
20578     wuffs_base__slice_u8 dst_palette,
20579     wuffs_base__slice_u8 src_palette,
20580     wuffs_base__pixel_blend blend) {
20581   switch (dst_pixfmt.repr) {
20582     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
20583     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
20584     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
20585       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20586           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20587         return NULL;
20588       }
20589       switch (blend) {
20590         case WUFFS_BASE__PIXEL_BLEND__SRC:
20591           return wuffs_base__pixel_swizzler__copy_1_1;
20592       }
20593       return NULL;
20594 
20595     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20596       if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
20597               dst_palette.ptr, dst_palette.len, src_palette.ptr,
20598               src_palette.len, false) !=
20599           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20600         return NULL;
20601       }
20602       switch (blend) {
20603         case WUFFS_BASE__PIXEL_BLEND__SRC:
20604           return wuffs_base__pixel_swizzler__bgr_565__index__src;
20605         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20606           return wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over;
20607       }
20608       return NULL;
20609 
20610     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20611       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20612           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20613         return NULL;
20614       }
20615       switch (blend) {
20616         case WUFFS_BASE__PIXEL_BLEND__SRC:
20617           return wuffs_base__pixel_swizzler__xxx__index__src;
20618         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20619           return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
20620       }
20621       return NULL;
20622 
20623     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20624     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20625     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20626       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20627           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20628         return NULL;
20629       }
20630       switch (blend) {
20631         case WUFFS_BASE__PIXEL_BLEND__SRC:
20632           return wuffs_base__pixel_swizzler__xxxx__index__src;
20633         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20634           return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
20635       }
20636       return NULL;
20637 
20638     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20639     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20640       if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20641           WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20642         return NULL;
20643       }
20644       switch (blend) {
20645         case WUFFS_BASE__PIXEL_BLEND__SRC:
20646           return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
20647         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20648           return wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over;
20649       }
20650       return NULL;
20651 
20652     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20653       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20654               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20655               src_palette.len) !=
20656           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20657         return NULL;
20658       }
20659       switch (blend) {
20660         case WUFFS_BASE__PIXEL_BLEND__SRC:
20661           return wuffs_base__pixel_swizzler__xxx__index__src;
20662         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20663           return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
20664       }
20665       return NULL;
20666 
20667     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20668     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20669     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20670       if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20671               dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20672               src_palette.len) !=
20673           (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20674         return NULL;
20675       }
20676       switch (blend) {
20677         case WUFFS_BASE__PIXEL_BLEND__SRC:
20678           return wuffs_base__pixel_swizzler__xxxx__index__src;
20679         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20680           return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
20681       }
20682       return NULL;
20683   }
20684   return NULL;
20685 }
20686 
20687 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)20688 wuffs_base__pixel_swizzler__prepare__bgr_565(
20689     wuffs_base__pixel_swizzler* p,
20690     wuffs_base__pixel_format dst_pixfmt,
20691     wuffs_base__slice_u8 dst_palette,
20692     wuffs_base__slice_u8 src_palette,
20693     wuffs_base__pixel_blend blend) {
20694   switch (dst_pixfmt.repr) {
20695     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20696       return wuffs_base__pixel_swizzler__copy_2_2;
20697 
20698     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20699       return wuffs_base__pixel_swizzler__bgr__bgr_565;
20700 
20701     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20702     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20703     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20704     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20705       return wuffs_base__pixel_swizzler__bgrw__bgr_565;
20706 
20707     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20708     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20709       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565;
20710 
20711     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20712     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20713     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20714     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20715       return wuffs_base__pixel_swizzler__rgbw__bgr_565;
20716   }
20717   return NULL;
20718 }
20719 
20720 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)20721 wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler* p,
20722                                          wuffs_base__pixel_format dst_pixfmt,
20723                                          wuffs_base__slice_u8 dst_palette,
20724                                          wuffs_base__slice_u8 src_palette,
20725                                          wuffs_base__pixel_blend blend) {
20726   switch (dst_pixfmt.repr) {
20727     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20728       return wuffs_base__pixel_swizzler__bgr_565__bgr;
20729 
20730     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20731       return wuffs_base__pixel_swizzler__copy_3_3;
20732 
20733     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20734     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20735     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20736     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20737       return wuffs_base__pixel_swizzler__bgrw__bgr;
20738 
20739     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20740     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20741       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr;
20742 
20743     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20744       return wuffs_base__pixel_swizzler__swap_rgb_bgr;
20745 
20746     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20747     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20748     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20749     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20750 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20751       if (wuffs_base__cpu_arch__have_x86_sse42()) {
20752         return wuffs_base__pixel_swizzler__bgrw__rgb__sse42;
20753       }
20754 #endif
20755       return wuffs_base__pixel_swizzler__bgrw__rgb;
20756   }
20757   return NULL;
20758 }
20759 
20760 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)20761 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
20762     wuffs_base__pixel_swizzler* p,
20763     wuffs_base__pixel_format dst_pixfmt,
20764     wuffs_base__slice_u8 dst_palette,
20765     wuffs_base__slice_u8 src_palette,
20766     wuffs_base__pixel_blend blend) {
20767   switch (dst_pixfmt.repr) {
20768     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20769       switch (blend) {
20770         case WUFFS_BASE__PIXEL_BLEND__SRC:
20771           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src;
20772         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20773           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over;
20774       }
20775       return NULL;
20776 
20777     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20778       switch (blend) {
20779         case WUFFS_BASE__PIXEL_BLEND__SRC:
20780           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
20781         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20782           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
20783       }
20784       return NULL;
20785 
20786     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20787       switch (blend) {
20788         case WUFFS_BASE__PIXEL_BLEND__SRC:
20789           return wuffs_base__pixel_swizzler__copy_4_4;
20790         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20791           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
20792       }
20793       return NULL;
20794 
20795     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20796       switch (blend) {
20797         case WUFFS_BASE__PIXEL_BLEND__SRC:
20798           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src;
20799         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20800           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over;
20801       }
20802       return NULL;
20803 
20804     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20805       switch (blend) {
20806         case WUFFS_BASE__PIXEL_BLEND__SRC:
20807           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
20808         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20809           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
20810       }
20811       return NULL;
20812 
20813     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20814     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20815       // TODO.
20816       break;
20817 
20818     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20819       // TODO.
20820       break;
20821 
20822     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20823       switch (blend) {
20824         case WUFFS_BASE__PIXEL_BLEND__SRC:
20825 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20826           if (wuffs_base__cpu_arch__have_x86_sse42()) {
20827             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
20828           }
20829 #endif
20830           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
20831         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20832           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
20833       }
20834       return NULL;
20835 
20836     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20837       switch (blend) {
20838         case WUFFS_BASE__PIXEL_BLEND__SRC:
20839           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
20840         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20841           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
20842       }
20843       return NULL;
20844 
20845     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20846     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20847       // TODO.
20848       break;
20849   }
20850   return NULL;
20851 }
20852 
20853 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)20854 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
20855     wuffs_base__pixel_swizzler* p,
20856     wuffs_base__pixel_format dst_pixfmt,
20857     wuffs_base__slice_u8 dst_palette,
20858     wuffs_base__slice_u8 src_palette,
20859     wuffs_base__pixel_blend blend) {
20860   switch (dst_pixfmt.repr) {
20861     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20862       switch (blend) {
20863         case WUFFS_BASE__PIXEL_BLEND__SRC:
20864           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src;
20865         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20866           return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over;
20867       }
20868       return NULL;
20869 
20870     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20871       switch (blend) {
20872         case WUFFS_BASE__PIXEL_BLEND__SRC:
20873           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src;
20874         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20875           return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over;
20876       }
20877       return NULL;
20878 
20879     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20880       switch (blend) {
20881         case WUFFS_BASE__PIXEL_BLEND__SRC:
20882           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src;
20883         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20884           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over;
20885       }
20886       return NULL;
20887 
20888     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20889       switch (blend) {
20890         case WUFFS_BASE__PIXEL_BLEND__SRC:
20891           return wuffs_base__pixel_swizzler__copy_8_8;
20892         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20893           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over;
20894       }
20895       return NULL;
20896 
20897     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20898       switch (blend) {
20899         case WUFFS_BASE__PIXEL_BLEND__SRC:
20900           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src;
20901         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20902           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over;
20903       }
20904       return NULL;
20905 
20906     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20907     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20908       // TODO.
20909       break;
20910 
20911     case WUFFS_BASE__PIXEL_FORMAT__RGB:
20912       // TODO.
20913       break;
20914 
20915     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20916       switch (blend) {
20917         case WUFFS_BASE__PIXEL_BLEND__SRC:
20918           return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src;
20919         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20920           return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over;
20921       }
20922       break;
20923 
20924     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20925       switch (blend) {
20926         case WUFFS_BASE__PIXEL_BLEND__SRC:
20927           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src;
20928         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20929           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over;
20930       }
20931       return NULL;
20932 
20933     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20934     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20935       // TODO.
20936       break;
20937   }
20938   return NULL;
20939 }
20940 
20941 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)20942 wuffs_base__pixel_swizzler__prepare__bgra_premul(
20943     wuffs_base__pixel_swizzler* p,
20944     wuffs_base__pixel_format dst_pixfmt,
20945     wuffs_base__slice_u8 dst_palette,
20946     wuffs_base__slice_u8 src_palette,
20947     wuffs_base__pixel_blend blend) {
20948   switch (dst_pixfmt.repr) {
20949     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20950       switch (blend) {
20951         case WUFFS_BASE__PIXEL_BLEND__SRC:
20952           return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src;
20953         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20954           return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over;
20955       }
20956       return NULL;
20957 
20958     case WUFFS_BASE__PIXEL_FORMAT__BGR:
20959       switch (blend) {
20960         case WUFFS_BASE__PIXEL_BLEND__SRC:
20961           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src;
20962         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20963           return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over;
20964       }
20965       return NULL;
20966 
20967     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20968       switch (blend) {
20969         case WUFFS_BASE__PIXEL_BLEND__SRC:
20970           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
20971         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20972           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
20973       }
20974       return NULL;
20975 
20976     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20977       switch (blend) {
20978         case WUFFS_BASE__PIXEL_BLEND__SRC:
20979           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src;
20980         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20981           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over;
20982       }
20983       return NULL;
20984 
20985     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20986       switch (blend) {
20987         case WUFFS_BASE__PIXEL_BLEND__SRC:
20988           return wuffs_base__pixel_swizzler__copy_4_4;
20989         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20990           return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
20991       }
20992       return NULL;
20993 
20994     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20995       switch (blend) {
20996         case WUFFS_BASE__PIXEL_BLEND__SRC:
20997           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
20998         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20999           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
21000       }
21001       return NULL;
21002 
21003     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21004       switch (blend) {
21005         case WUFFS_BASE__PIXEL_BLEND__SRC:
21006 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21007           if (wuffs_base__cpu_arch__have_x86_sse42()) {
21008             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
21009           }
21010 #endif
21011           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
21012         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21013           return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
21014       }
21015       return NULL;
21016   }
21017   return NULL;
21018 }
21019 
21020 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)21021 wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler* p,
21022                                           wuffs_base__pixel_format dst_pixfmt,
21023                                           wuffs_base__slice_u8 dst_palette,
21024                                           wuffs_base__slice_u8 src_palette,
21025                                           wuffs_base__pixel_blend blend) {
21026   switch (dst_pixfmt.repr) {
21027     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21028       return wuffs_base__pixel_swizzler__bgr_565__bgrx;
21029 
21030     case WUFFS_BASE__PIXEL_FORMAT__BGR:
21031       return wuffs_base__pixel_swizzler__xxx__xxxx;
21032 
21033     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21034     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21035     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
21036       return wuffs_base__pixel_swizzler__bgrw__bgrx;
21037 
21038     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21039       return wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx;
21040 
21041     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21042       return wuffs_base__pixel_swizzler__copy_4_4;
21043 
21044     case WUFFS_BASE__PIXEL_FORMAT__RGB:
21045       // TODO.
21046       break;
21047 
21048     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21049     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21050     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
21051     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
21052       return wuffs_base__pixel_swizzler__bgrw__rgbx;
21053   }
21054   return NULL;
21055 }
21056 
21057 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)21058 wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler* p,
21059                                          wuffs_base__pixel_format dst_pixfmt,
21060                                          wuffs_base__slice_u8 dst_palette,
21061                                          wuffs_base__slice_u8 src_palette,
21062                                          wuffs_base__pixel_blend blend) {
21063   switch (dst_pixfmt.repr) {
21064     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21065       return wuffs_base__pixel_swizzler__bgr_565__rgb;
21066 
21067     case WUFFS_BASE__PIXEL_FORMAT__BGR:
21068       return wuffs_base__pixel_swizzler__swap_rgb_bgr;
21069 
21070     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21071     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21072     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
21073     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21074 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21075       if (wuffs_base__cpu_arch__have_x86_sse42()) {
21076         return wuffs_base__pixel_swizzler__bgrw__rgb__sse42;
21077       }
21078 #endif
21079       return wuffs_base__pixel_swizzler__bgrw__rgb;
21080 
21081     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21082       return wuffs_base__pixel_swizzler__bgrw_4x16le__rgb;
21083 
21084     case WUFFS_BASE__PIXEL_FORMAT__RGB:
21085       return wuffs_base__pixel_swizzler__copy_3_3;
21086 
21087     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21088     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21089     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
21090     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
21091       return wuffs_base__pixel_swizzler__bgrw__bgr;
21092   }
21093   return NULL;
21094 }
21095 
21096 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)21097 wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
21098     wuffs_base__pixel_swizzler* p,
21099     wuffs_base__pixel_format dst_pixfmt,
21100     wuffs_base__slice_u8 dst_palette,
21101     wuffs_base__slice_u8 src_palette,
21102     wuffs_base__pixel_blend blend) {
21103   switch (dst_pixfmt.repr) {
21104     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21105       switch (blend) {
21106         case WUFFS_BASE__PIXEL_BLEND__SRC:
21107           return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src;
21108         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21109           return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over;
21110       }
21111       return NULL;
21112 
21113     case WUFFS_BASE__PIXEL_FORMAT__BGR:
21114       switch (blend) {
21115         case WUFFS_BASE__PIXEL_BLEND__SRC:
21116           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src;
21117         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21118           return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over;
21119       }
21120       return NULL;
21121 
21122     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21123       switch (blend) {
21124         case WUFFS_BASE__PIXEL_BLEND__SRC:
21125 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21126           if (wuffs_base__cpu_arch__have_x86_sse42()) {
21127             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
21128           }
21129 #endif
21130           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
21131         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21132           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
21133       }
21134       return NULL;
21135 
21136     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21137       switch (blend) {
21138         case WUFFS_BASE__PIXEL_BLEND__SRC:
21139           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src;
21140         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21141           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over;
21142       }
21143       return NULL;
21144 
21145     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21146       switch (blend) {
21147         case WUFFS_BASE__PIXEL_BLEND__SRC:
21148           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
21149         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21150           return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
21151       }
21152       return NULL;
21153 
21154     case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
21155     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21156       // TODO.
21157       break;
21158 
21159     case WUFFS_BASE__PIXEL_FORMAT__RGB:
21160       // TODO.
21161       break;
21162 
21163     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21164       switch (blend) {
21165         case WUFFS_BASE__PIXEL_BLEND__SRC:
21166           return wuffs_base__pixel_swizzler__copy_4_4;
21167         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21168           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
21169       }
21170       return NULL;
21171 
21172     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21173       switch (blend) {
21174         case WUFFS_BASE__PIXEL_BLEND__SRC:
21175           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
21176         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21177           return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
21178       }
21179       return NULL;
21180 
21181     case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
21182     case WUFFS_BASE__PIXEL_FORMAT__RGBX:
21183       // TODO.
21184       break;
21185   }
21186   return NULL;
21187 }
21188 
21189 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)21190 wuffs_base__pixel_swizzler__prepare__rgba_premul(
21191     wuffs_base__pixel_swizzler* p,
21192     wuffs_base__pixel_format dst_pixfmt,
21193     wuffs_base__slice_u8 dst_palette,
21194     wuffs_base__slice_u8 src_palette,
21195     wuffs_base__pixel_blend blend) {
21196   switch (dst_pixfmt.repr) {
21197     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21198       switch (blend) {
21199         case WUFFS_BASE__PIXEL_BLEND__SRC:
21200           return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src;
21201         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21202           return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over;
21203       }
21204       return NULL;
21205 
21206     case WUFFS_BASE__PIXEL_FORMAT__BGR:
21207       switch (blend) {
21208         case WUFFS_BASE__PIXEL_BLEND__SRC:
21209           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src;
21210         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21211           return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over;
21212       }
21213       return NULL;
21214 
21215     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21216       switch (blend) {
21217         case WUFFS_BASE__PIXEL_BLEND__SRC:
21218           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
21219         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21220           return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
21221       }
21222       return NULL;
21223 
21224     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21225       switch (blend) {
21226         case WUFFS_BASE__PIXEL_BLEND__SRC:
21227           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src;
21228         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21229           return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over;
21230       }
21231       return NULL;
21232 
21233     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21234       switch (blend) {
21235         case WUFFS_BASE__PIXEL_BLEND__SRC:
21236 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21237           if (wuffs_base__cpu_arch__have_x86_sse42()) {
21238             return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
21239           }
21240 #endif
21241           return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
21242         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21243           return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
21244       }
21245       return NULL;
21246 
21247     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21248       switch (blend) {
21249         case WUFFS_BASE__PIXEL_BLEND__SRC:
21250           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
21251         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21252           return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
21253       }
21254       return NULL;
21255 
21256     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21257       switch (blend) {
21258         case WUFFS_BASE__PIXEL_BLEND__SRC:
21259           return wuffs_base__pixel_swizzler__copy_4_4;
21260         case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21261           return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
21262       }
21263       return NULL;
21264   }
21265   return NULL;
21266 }
21267 
21268 // --------
21269 
21270 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)21271 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
21272                                     wuffs_base__pixel_format dst_pixfmt,
21273                                     wuffs_base__slice_u8 dst_palette,
21274                                     wuffs_base__pixel_format src_pixfmt,
21275                                     wuffs_base__slice_u8 src_palette,
21276                                     wuffs_base__pixel_blend blend) {
21277   if (!p) {
21278     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21279   }
21280   p->private_impl.func = NULL;
21281   p->private_impl.transparent_black_func = NULL;
21282   p->private_impl.dst_pixfmt_bytes_per_pixel = 0;
21283   p->private_impl.src_pixfmt_bytes_per_pixel = 0;
21284 
21285   wuffs_base__pixel_swizzler__func func = NULL;
21286   wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func =
21287       NULL;
21288 
21289   uint32_t dst_pixfmt_bits_per_pixel =
21290       wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt);
21291   if ((dst_pixfmt_bits_per_pixel == 0) ||
21292       ((dst_pixfmt_bits_per_pixel & 7) != 0)) {
21293     return wuffs_base__make_status(
21294         wuffs_base__error__unsupported_pixel_swizzler_option);
21295   }
21296 
21297   uint32_t src_pixfmt_bits_per_pixel =
21298       wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);
21299   if ((src_pixfmt_bits_per_pixel == 0) ||
21300       ((src_pixfmt_bits_per_pixel & 7) != 0)) {
21301     return wuffs_base__make_status(
21302         wuffs_base__error__unsupported_pixel_swizzler_option);
21303   }
21304 
21305   // TODO: support many more formats.
21306 
21307   switch (blend) {
21308     case WUFFS_BASE__PIXEL_BLEND__SRC:
21309       transparent_black_func =
21310           wuffs_base__pixel_swizzler__transparent_black_src;
21311       break;
21312 
21313     case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21314       transparent_black_func =
21315           wuffs_base__pixel_swizzler__transparent_black_src_over;
21316       break;
21317   }
21318 
21319   switch (src_pixfmt.repr) {
21320     case WUFFS_BASE__PIXEL_FORMAT__Y:
21321       func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette,
21322                                                     src_palette, blend);
21323       break;
21324 
21325     case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
21326       func = wuffs_base__pixel_swizzler__prepare__y_16be(
21327           p, dst_pixfmt, dst_palette, src_palette, blend);
21328       break;
21329 
21330     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
21331       func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
21332           p, dst_pixfmt, dst_palette, src_palette, blend);
21333       break;
21334 
21335     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
21336       func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
21337           p, dst_pixfmt, dst_palette, src_palette, blend);
21338       break;
21339 
21340     case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21341       func = wuffs_base__pixel_swizzler__prepare__bgr_565(
21342           p, dst_pixfmt, dst_palette, src_palette, blend);
21343       break;
21344 
21345     case WUFFS_BASE__PIXEL_FORMAT__BGR:
21346       func = wuffs_base__pixel_swizzler__prepare__bgr(
21347           p, dst_pixfmt, dst_palette, src_palette, blend);
21348       break;
21349 
21350     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21351       func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
21352           p, dst_pixfmt, dst_palette, src_palette, blend);
21353       break;
21354 
21355     case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21356       func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
21357           p, dst_pixfmt, dst_palette, src_palette, blend);
21358       break;
21359 
21360     case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21361       func = wuffs_base__pixel_swizzler__prepare__bgra_premul(
21362           p, dst_pixfmt, dst_palette, src_palette, blend);
21363       break;
21364 
21365     case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21366       func = wuffs_base__pixel_swizzler__prepare__bgrx(
21367           p, dst_pixfmt, dst_palette, src_palette, blend);
21368       break;
21369 
21370     case WUFFS_BASE__PIXEL_FORMAT__RGB:
21371       func = wuffs_base__pixel_swizzler__prepare__rgb(
21372           p, dst_pixfmt, dst_palette, src_palette, blend);
21373       break;
21374 
21375     case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21376       func = wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
21377           p, dst_pixfmt, dst_palette, src_palette, blend);
21378       break;
21379 
21380     case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21381       func = wuffs_base__pixel_swizzler__prepare__rgba_premul(
21382           p, dst_pixfmt, dst_palette, src_palette, blend);
21383       break;
21384   }
21385 
21386   p->private_impl.func = func;
21387   p->private_impl.transparent_black_func = transparent_black_func;
21388   p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;
21389   p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;
21390   return wuffs_base__make_status(
21391       func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);
21392 }
21393 
21394 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)21395 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
21396     const wuffs_base__pixel_swizzler* p,
21397     uint32_t up_to_num_pixels,
21398     wuffs_base__slice_u8 dst,
21399     wuffs_base__slice_u8 dst_palette,
21400     const uint8_t** ptr_iop_r,
21401     const uint8_t* io2_r) {
21402   if (p && p->private_impl.func) {
21403     const uint8_t* iop_r = *ptr_iop_r;
21404     uint64_t src_len = wuffs_base__u64__min(
21405         ((uint64_t)up_to_num_pixels) *
21406             ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
21407         ((uint64_t)(io2_r - iop_r)));
21408     uint64_t n =
21409         (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
21410                                 dst_palette.len, iop_r, (size_t)src_len);
21411     *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
21412     return n;
21413   }
21414   return 0;
21415 }
21416 
21417 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)21418 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
21419     const wuffs_base__pixel_swizzler* p,
21420     wuffs_base__slice_u8 dst,
21421     wuffs_base__slice_u8 dst_palette,
21422     const uint8_t** ptr_iop_r,
21423     const uint8_t* io2_r) {
21424   if (p && p->private_impl.func) {
21425     const uint8_t* iop_r = *ptr_iop_r;
21426     uint64_t src_len = ((uint64_t)(io2_r - iop_r));
21427     uint64_t n =
21428         (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
21429                                 dst_palette.len, iop_r, (size_t)src_len);
21430     *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
21431     return n;
21432   }
21433   return 0;
21434 }
21435 
21436 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)21437 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
21438     const wuffs_base__pixel_swizzler* p,
21439     wuffs_base__slice_u8 dst,
21440     wuffs_base__slice_u8 dst_palette,
21441     wuffs_base__slice_u8 src) {
21442   if (p && p->private_impl.func) {
21443     return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
21444                                    dst_palette.len, src.ptr, src.len);
21445   }
21446   return 0;
21447 }
21448 
21449 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)21450 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
21451     const wuffs_base__pixel_swizzler* p,
21452     wuffs_base__slice_u8 dst,
21453     wuffs_base__slice_u8 dst_palette,
21454     uint64_t num_pixels) {
21455   if (p && p->private_impl.transparent_black_func) {
21456     return (*p->private_impl.transparent_black_func)(
21457         dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,
21458         p->private_impl.dst_pixfmt_bytes_per_pixel);
21459   }
21460   return 0;
21461 }
21462 
21463 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
21464         // defined(WUFFS_CONFIG__MODULE__BASE) ||
21465         // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
21466 
21467 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
21468     defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
21469 
21470 // ---------------- Unicode and UTF-8
21471 
21472 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst,uint32_t code_point)21473 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {
21474   if (code_point <= 0x7F) {
21475     if (dst.len >= 1) {
21476       dst.ptr[0] = (uint8_t)(code_point);
21477       return 1;
21478     }
21479 
21480   } else if (code_point <= 0x07FF) {
21481     if (dst.len >= 2) {
21482       dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));
21483       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
21484       return 2;
21485     }
21486 
21487   } else if (code_point <= 0xFFFF) {
21488     if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {
21489       dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));
21490       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
21491       dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
21492       return 3;
21493     }
21494 
21495   } else if (code_point <= 0x10FFFF) {
21496     if (dst.len >= 4) {
21497       dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));
21498       dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
21499       dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
21500       dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
21501       return 4;
21502     }
21503   }
21504 
21505   return 0;
21506 }
21507 
21508 // wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a
21509 // UTF-8 encoded code point, based on the encoding's initial byte.
21510 //  - 0x00 is 1-byte UTF-8 (ASCII).
21511 //  - 0x01 is the start of 2-byte UTF-8.
21512 //  - 0x02 is the start of 3-byte UTF-8.
21513 //  - 0x03 is the start of 4-byte UTF-8.
21514 //  - 0x40 is a UTF-8 tail byte.
21515 //  - 0x80 is invalid UTF-8.
21516 //
21517 // RFC 3629 (UTF-8) gives this grammar for valid UTF-8:
21518 //    UTF8-1      = %x00-7F
21519 //    UTF8-2      = %xC2-DF UTF8-tail
21520 //    UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
21521 //                  %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
21522 //    UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
21523 //                  %xF4 %x80-8F 2( UTF8-tail )
21524 //    UTF8-tail   = %x80-BF
21525 static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {
21526     // 0     1     2     3     4     5     6     7
21527     // 8     9     A     B     C     D     E     F
21528     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x00 ..= 0x07.
21529     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x08 ..= 0x0F.
21530     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x10 ..= 0x17.
21531     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x18 ..= 0x1F.
21532     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x20 ..= 0x27.
21533     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x28 ..= 0x2F.
21534     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x30 ..= 0x37.
21535     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x38 ..= 0x3F.
21536 
21537     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x40 ..= 0x47.
21538     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x48 ..= 0x4F.
21539     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x50 ..= 0x57.
21540     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x58 ..= 0x5F.
21541     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x60 ..= 0x67.
21542     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x68 ..= 0x6F.
21543     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x70 ..= 0x77.
21544     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // 0x78 ..= 0x7F.
21545 
21546     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x80 ..= 0x87.
21547     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x88 ..= 0x8F.
21548     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x90 ..= 0x97.
21549     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0x98 ..= 0x9F.
21550     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xA0 ..= 0xA7.
21551     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xA8 ..= 0xAF.
21552     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xB0 ..= 0xB7.
21553     0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  // 0xB8 ..= 0xBF.
21554 
21555     0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xC0 ..= 0xC7.
21556     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xC8 ..= 0xCF.
21557     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xD0 ..= 0xD7.
21558     0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  // 0xD8 ..= 0xDF.
21559     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  // 0xE0 ..= 0xE7.
21560     0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  // 0xE8 ..= 0xEF.
21561     0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80,  // 0xF0 ..= 0xF7.
21562     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,  // 0xF8 ..= 0xFF.
21563     // 0     1     2     3     4     5     6     7
21564     // 8     9     A     B     C     D     E     F
21565 };
21566 
21567 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output  //
wuffs_base__utf_8__next(const uint8_t * s_ptr,size_t s_len)21568 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) {
21569   if (s_len == 0) {
21570     return wuffs_base__make_utf_8__next__output(0, 0);
21571   }
21572   uint32_t c = s_ptr[0];
21573   switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) {
21574     case 0:
21575       return wuffs_base__make_utf_8__next__output(c, 1);
21576 
21577     case 1:
21578       if (s_len < 2) {
21579         break;
21580       }
21581       c = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
21582       if ((c & 0xC000) != 0x8000) {
21583         break;
21584       }
21585       c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8));
21586       return wuffs_base__make_utf_8__next__output(c, 2);
21587 
21588     case 2:
21589       if (s_len < 3) {
21590         break;
21591       }
21592       c = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
21593       if ((c & 0xC0C000) != 0x808000) {
21594         break;
21595       }
21596       c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) |
21597           (0x00003F & (c >> 16));
21598       if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) {
21599         break;
21600       }
21601       return wuffs_base__make_utf_8__next__output(c, 3);
21602 
21603     case 3:
21604       if (s_len < 4) {
21605         break;
21606       }
21607       c = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
21608       if ((c & 0xC0C0C000) != 0x80808000) {
21609         break;
21610       }
21611       c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) |
21612           (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24));
21613       if ((c <= 0xFFFF) || (0x110000 <= c)) {
21614         break;
21615       }
21616       return wuffs_base__make_utf_8__next__output(c, 4);
21617   }
21618 
21619   return wuffs_base__make_utf_8__next__output(
21620       WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
21621 }
21622 
21623 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)21624 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) {
21625   if (s_len == 0) {
21626     return wuffs_base__make_utf_8__next__output(0, 0);
21627   }
21628   const uint8_t* ptr = &s_ptr[s_len - 1];
21629   if (*ptr < 0x80) {
21630     return wuffs_base__make_utf_8__next__output(*ptr, 1);
21631 
21632   } else if (*ptr < 0xC0) {
21633     const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0];
21634     uint32_t n = 1;
21635     while (ptr != too_far) {
21636       ptr--;
21637       n++;
21638       if (*ptr < 0x80) {
21639         break;
21640       } else if (*ptr < 0xC0) {
21641         continue;
21642       }
21643       wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n);
21644       if (o.byte_length != n) {
21645         break;
21646       }
21647       return o;
21648     }
21649   }
21650 
21651   return wuffs_base__make_utf_8__next__output(
21652       WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
21653 }
21654 
21655 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__utf_8__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)21656 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
21657   // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time).
21658   //
21659   // TODO: possibly optimize this by manually inlining the
21660   // wuffs_base__utf_8__next calls.
21661   size_t original_len = s_len;
21662   while (s_len > 0) {
21663     wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len);
21664     if ((o.code_point > 0x7F) && (o.byte_length == 1)) {
21665       break;
21666     }
21667     s_ptr += o.byte_length;
21668     s_len -= o.byte_length;
21669   }
21670   return original_len - s_len;
21671 }
21672 
21673 WUFFS_BASE__MAYBE_STATIC size_t  //
wuffs_base__ascii__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)21674 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
21675   // TODO: possibly optimize this by checking 4 or 8 bytes at a time.
21676   const uint8_t* original_ptr = s_ptr;
21677   const uint8_t* p = s_ptr;
21678   const uint8_t* q = s_ptr + s_len;
21679   for (; (p != q) && ((*p & 0x80) == 0); p++) {
21680   }
21681   return (size_t)(p - original_ptr);
21682 }
21683 
21684 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
21685         // defined(WUFFS_CONFIG__MODULE__BASE) ||
21686         // defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
21687 
21688 #ifdef __cplusplus
21689 }  // extern "C"
21690 #endif
21691 
21692 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
21693 
21694 // ---------------- Status Codes Implementations
21695 
21696 // ---------------- Private Consts
21697 
21698 // ---------------- Private Initializer Prototypes
21699 
21700 // ---------------- Private Function Prototypes
21701 
21702 static wuffs_base__empty_struct
21703 wuffs_adler32__hasher__up(
21704     wuffs_adler32__hasher* self,
21705     wuffs_base__slice_u8 a_x);
21706 
21707 static wuffs_base__empty_struct
21708 wuffs_adler32__hasher__up__choosy_default(
21709     wuffs_adler32__hasher* self,
21710     wuffs_base__slice_u8 a_x);
21711 
21712 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21713 static wuffs_base__empty_struct
21714 wuffs_adler32__hasher__up_arm_neon(
21715     wuffs_adler32__hasher* self,
21716     wuffs_base__slice_u8 a_x);
21717 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21718 
21719 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21720 static wuffs_base__empty_struct
21721 wuffs_adler32__hasher__up_x86_sse42(
21722     wuffs_adler32__hasher* self,
21723     wuffs_base__slice_u8 a_x);
21724 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21725 
21726 // ---------------- VTables
21727 
21728 const wuffs_base__hasher_u32__func_ptrs
21729 wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
21730   (wuffs_base__empty_struct(*)(void*,
21731       uint32_t,
21732       bool))(&wuffs_adler32__hasher__set_quirk_enabled),
21733   (uint32_t(*)(void*,
21734       wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32),
21735 };
21736 
21737 // ---------------- Initializer Implementations
21738 
21739 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)21740 wuffs_adler32__hasher__initialize(
21741     wuffs_adler32__hasher* self,
21742     size_t sizeof_star_self,
21743     uint64_t wuffs_version,
21744     uint32_t options){
21745   if (!self) {
21746     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21747   }
21748   if (sizeof(*self) != sizeof_star_self) {
21749     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
21750   }
21751   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
21752       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
21753     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
21754   }
21755 
21756   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
21757     // The whole point of this if-check is to detect an uninitialized *self.
21758     // We disable the warning on GCC. Clang-5.0 does not have this warning.
21759 #if !defined(__clang__) && defined(__GNUC__)
21760 #pragma GCC diagnostic push
21761 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
21762 #endif
21763     if (self->private_impl.magic != 0) {
21764       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
21765     }
21766 #if !defined(__clang__) && defined(__GNUC__)
21767 #pragma GCC diagnostic pop
21768 #endif
21769   } else {
21770     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
21771       memset(self, 0, sizeof(*self));
21772       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
21773     } else {
21774       memset(&(self->private_impl), 0, sizeof(self->private_impl));
21775     }
21776   }
21777 
21778   self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default;
21779 
21780   self->private_impl.magic = WUFFS_BASE__MAGIC;
21781   self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
21782       wuffs_base__hasher_u32__vtable_name;
21783   self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
21784       (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
21785   return wuffs_base__make_status(NULL);
21786 }
21787 
21788 wuffs_adler32__hasher*
wuffs_adler32__hasher__alloc()21789 wuffs_adler32__hasher__alloc() {
21790   wuffs_adler32__hasher* x =
21791       (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
21792   if (!x) {
21793     return NULL;
21794   }
21795   if (wuffs_adler32__hasher__initialize(
21796       x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
21797     free(x);
21798     return NULL;
21799   }
21800   return x;
21801 }
21802 
21803 size_t
sizeof__wuffs_adler32__hasher()21804 sizeof__wuffs_adler32__hasher() {
21805   return sizeof(wuffs_adler32__hasher);
21806 }
21807 
21808 // ---------------- Function Implementations
21809 
21810 // -------- func adler32.hasher.set_quirk_enabled
21811 
21812 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)21813 wuffs_adler32__hasher__set_quirk_enabled(
21814     wuffs_adler32__hasher* self,
21815     uint32_t a_quirk,
21816     bool a_enabled) {
21817   return wuffs_base__make_empty_struct();
21818 }
21819 
21820 // -------- func adler32.hasher.update_u32
21821 
21822 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_adler32__hasher__update_u32(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21823 wuffs_adler32__hasher__update_u32(
21824     wuffs_adler32__hasher* self,
21825     wuffs_base__slice_u8 a_x) {
21826   if (!self) {
21827     return 0;
21828   }
21829   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
21830     return 0;
21831   }
21832 
21833   if ( ! self->private_impl.f_started) {
21834     self->private_impl.f_started = true;
21835     self->private_impl.f_state = 1;
21836     self->private_impl.choosy_up = (
21837 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21838         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon :
21839 #endif
21840 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21841         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 :
21842 #endif
21843         self->private_impl.choosy_up);
21844   }
21845   wuffs_adler32__hasher__up(self, a_x);
21846   return self->private_impl.f_state;
21847 }
21848 
21849 // -------- func adler32.hasher.up
21850 
21851 static wuffs_base__empty_struct
wuffs_adler32__hasher__up(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21852 wuffs_adler32__hasher__up(
21853     wuffs_adler32__hasher* self,
21854     wuffs_base__slice_u8 a_x) {
21855   return (*self->private_impl.choosy_up)(self, a_x);
21856 }
21857 
21858 static wuffs_base__empty_struct
wuffs_adler32__hasher__up__choosy_default(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21859 wuffs_adler32__hasher__up__choosy_default(
21860     wuffs_adler32__hasher* self,
21861     wuffs_base__slice_u8 a_x) {
21862   uint32_t v_s1 = 0;
21863   uint32_t v_s2 = 0;
21864   wuffs_base__slice_u8 v_remaining = {0};
21865   wuffs_base__slice_u8 v_p = {0};
21866 
21867   v_s1 = ((self->private_impl.f_state) & 0xFFFF);
21868   v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
21869   while (((uint64_t)(a_x.len)) > 0) {
21870     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
21871     if (((uint64_t)(a_x.len)) > 5552) {
21872       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552);
21873       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552);
21874     }
21875     {
21876       wuffs_base__slice_u8 i_slice_p = a_x;
21877       v_p.ptr = i_slice_p.ptr;
21878       v_p.len = 1;
21879       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
21880       while (v_p.ptr < i_end0_p) {
21881         v_s1 += ((uint32_t)(v_p.ptr[0]));
21882         v_s2 += v_s1;
21883         v_p.ptr += 1;
21884         v_s1 += ((uint32_t)(v_p.ptr[0]));
21885         v_s2 += v_s1;
21886         v_p.ptr += 1;
21887         v_s1 += ((uint32_t)(v_p.ptr[0]));
21888         v_s2 += v_s1;
21889         v_p.ptr += 1;
21890         v_s1 += ((uint32_t)(v_p.ptr[0]));
21891         v_s2 += v_s1;
21892         v_p.ptr += 1;
21893         v_s1 += ((uint32_t)(v_p.ptr[0]));
21894         v_s2 += v_s1;
21895         v_p.ptr += 1;
21896         v_s1 += ((uint32_t)(v_p.ptr[0]));
21897         v_s2 += v_s1;
21898         v_p.ptr += 1;
21899         v_s1 += ((uint32_t)(v_p.ptr[0]));
21900         v_s2 += v_s1;
21901         v_p.ptr += 1;
21902         v_s1 += ((uint32_t)(v_p.ptr[0]));
21903         v_s2 += v_s1;
21904         v_p.ptr += 1;
21905       }
21906       v_p.len = 1;
21907       uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
21908       while (v_p.ptr < i_end1_p) {
21909         v_s1 += ((uint32_t)(v_p.ptr[0]));
21910         v_s2 += v_s1;
21911         v_p.ptr += 1;
21912       }
21913       v_p.len = 0;
21914     }
21915     v_s1 %= 65521;
21916     v_s2 %= 65521;
21917     a_x = v_remaining;
21918   }
21919   self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
21920   return wuffs_base__make_empty_struct();
21921 }
21922 
21923 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
21924 // -------- func adler32.hasher.up_arm_neon
21925 
21926 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21927 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_arm_neon(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21928 wuffs_adler32__hasher__up_arm_neon(
21929     wuffs_adler32__hasher* self,
21930     wuffs_base__slice_u8 a_x) {
21931   uint32_t v_s1 = 0;
21932   uint32_t v_s2 = 0;
21933   wuffs_base__slice_u8 v_remaining = {0};
21934   wuffs_base__slice_u8 v_p = {0};
21935   uint8x16_t v_p__left = {0};
21936   uint8x16_t v_p_right = {0};
21937   uint32x4_t v_v1 = {0};
21938   uint32x4_t v_v2 = {0};
21939   uint16x8_t v_col0 = {0};
21940   uint16x8_t v_col1 = {0};
21941   uint16x8_t v_col2 = {0};
21942   uint16x8_t v_col3 = {0};
21943   uint32x2_t v_sum1 = {0};
21944   uint32x2_t v_sum2 = {0};
21945   uint32x2_t v_sum12 = {0};
21946   uint32_t v_num_iterate_bytes = 0;
21947   uint64_t v_tail_index = 0;
21948 
21949   v_s1 = ((self->private_impl.f_state) & 0xFFFF);
21950   v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
21951   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
21952     v_s1 += ((uint32_t)(a_x.ptr[0]));
21953     v_s2 += v_s1;
21954     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
21955   }
21956   v_s1 %= 65521;
21957   v_s2 %= 65521;
21958   while (((uint64_t)(a_x.len)) > 0) {
21959     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
21960     if (((uint64_t)(a_x.len)) > 5536) {
21961       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536);
21962       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536);
21963     }
21964     v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264)));
21965     v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
21966     v_v1 = vdupq_n_u32(0);
21967     v_v2 = vdupq_n_u32(0);
21968     v_col0 = vdupq_n_u16(0);
21969     v_col1 = vdupq_n_u16(0);
21970     v_col2 = vdupq_n_u16(0);
21971     v_col3 = vdupq_n_u16(0);
21972     {
21973       wuffs_base__slice_u8 i_slice_p = a_x;
21974       v_p.ptr = i_slice_p.ptr;
21975       v_p.len = 32;
21976       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
21977       while (v_p.ptr < i_end0_p) {
21978         v_p__left = vld1q_u8(v_p.ptr);
21979         v_p_right = vld1q_u8(v_p.ptr + 16);
21980         v_v2 = vaddq_u32(v_v2, v_v1);
21981         v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right));
21982         v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left));
21983         v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left));
21984         v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right));
21985         v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right));
21986         v_p.ptr += 32;
21987       }
21988       v_p.len = 0;
21989     }
21990 
21991     static const uint16x4_t table_0 {32, 31, 30, 29};
21992     static const uint16x4_t table_1 {28, 27, 26, 25};
21993     static const uint16x4_t table_2 {24, 23, 22, 21};
21994     static const uint16x4_t table_3 {20, 19, 18, 17};
21995     static const uint16x4_t table_4 {16, 15, 14, 13};
21996     static const uint16x4_t table_5 {12, 11, 10,  9};
21997     static const uint16x4_t table_6 { 8,  7,  6,  5};
21998     static const uint16x4_t table_7 { 4,  3,  2,  1};
21999 
22000     v_v2 = vshlq_n_u32(v_v2, 5);
22001     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0),  table_0);
22002     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), table_1);
22003     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1),  table_2);
22004     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), table_3);
22005     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2),  table_4);
22006     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), table_5);
22007     v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3),  table_6);
22008     v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), table_7);
22009     v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1));
22010     v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2));
22011     v_sum12 = vpadd_u32(v_sum1, v_sum2);
22012     v_s1 += vget_lane_u32(v_sum12, 0);
22013     v_s2 += vget_lane_u32(v_sum12, 1);
22014     v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
22015     if (v_tail_index < ((uint64_t)(a_x.len))) {
22016       {
22017         wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
22018         v_p.ptr = i_slice_p.ptr;
22019         v_p.len = 1;
22020         uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
22021         while (v_p.ptr < i_end0_p) {
22022           v_s1 += ((uint32_t)(v_p.ptr[0]));
22023           v_s2 += v_s1;
22024           v_p.ptr += 1;
22025         }
22026         v_p.len = 0;
22027       }
22028     }
22029     v_s1 %= 65521;
22030     v_s2 %= 65521;
22031     a_x = v_remaining;
22032   }
22033   self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
22034   return wuffs_base__make_empty_struct();
22035 }
22036 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
22037 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
22038 
22039 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
22040 // -------- func adler32.hasher.up_x86_sse42
22041 
22042 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
22043 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
22044 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_x86_sse42(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)22045 wuffs_adler32__hasher__up_x86_sse42(
22046     wuffs_adler32__hasher* self,
22047     wuffs_base__slice_u8 a_x) {
22048   uint32_t v_s1 = 0;
22049   uint32_t v_s2 = 0;
22050   wuffs_base__slice_u8 v_remaining = {0};
22051   wuffs_base__slice_u8 v_p = {0};
22052   __m128i v_zeroes = {0};
22053   __m128i v_ones = {0};
22054   __m128i v_weights__left = {0};
22055   __m128i v_weights_right = {0};
22056   __m128i v_q__left = {0};
22057   __m128i v_q_right = {0};
22058   __m128i v_v1 = {0};
22059   __m128i v_v2 = {0};
22060   __m128i v_v2j = {0};
22061   __m128i v_v2k = {0};
22062   uint32_t v_num_iterate_bytes = 0;
22063   uint64_t v_tail_index = 0;
22064 
22065   v_zeroes = _mm_set1_epi16((int16_t)(0));
22066   v_ones = _mm_set1_epi16((int16_t)(1));
22067   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));
22068   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));
22069   v_s1 = ((self->private_impl.f_state) & 0xFFFF);
22070   v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
22071   while (((uint64_t)(a_x.len)) > 0) {
22072     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
22073     if (((uint64_t)(a_x.len)) > 5536) {
22074       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536);
22075       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536);
22076     }
22077     v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264)));
22078     v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
22079     v_v1 = _mm_setzero_si128();
22080     v_v2j = _mm_setzero_si128();
22081     v_v2k = _mm_setzero_si128();
22082     {
22083       wuffs_base__slice_u8 i_slice_p = a_x;
22084       v_p.ptr = i_slice_p.ptr;
22085       v_p.len = 32;
22086       uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
22087       while (v_p.ptr < i_end0_p) {
22088         v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr));
22089         v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16));
22090         v_v2j = _mm_add_epi32(v_v2j, v_v1);
22091         v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes));
22092         v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes));
22093         v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left)));
22094         v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right)));
22095         v_p.ptr += 32;
22096       }
22097       v_p.len = 0;
22098     }
22099     v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177)));
22100     v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78)));
22101     v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1)));
22102     v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5)));
22103     v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177)));
22104     v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78)));
22105     v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2)));
22106     v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
22107     if (v_tail_index < ((uint64_t)(a_x.len))) {
22108       {
22109         wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
22110         v_p.ptr = i_slice_p.ptr;
22111         v_p.len = 1;
22112         uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
22113         while (v_p.ptr < i_end0_p) {
22114           v_s1 += ((uint32_t)(v_p.ptr[0]));
22115           v_s2 += v_s1;
22116           v_p.ptr += 1;
22117         }
22118         v_p.len = 0;
22119       }
22120     }
22121     v_s1 %= 65521;
22122     v_s2 %= 65521;
22123     a_x = v_remaining;
22124   }
22125   self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
22126   return wuffs_base__make_empty_struct();
22127 }
22128 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
22129 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
22130 
22131 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
22132 
22133 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
22134 
22135 // ---------------- Status Codes Implementations
22136 
22137 const char wuffs_bmp__error__bad_header[] = "#bmp: bad header";
22138 const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression";
22139 const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file";
22140 const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read";
22141 
22142 // ---------------- Private Consts
22143 
22144 #define WUFFS_BMP__COMPRESSION_NONE 0
22145 
22146 #define WUFFS_BMP__COMPRESSION_RLE8 1
22147 
22148 #define WUFFS_BMP__COMPRESSION_RLE4 2
22149 
22150 #define WUFFS_BMP__COMPRESSION_BITFIELDS 3
22151 
22152 #define WUFFS_BMP__COMPRESSION_JPEG 4
22153 
22154 #define WUFFS_BMP__COMPRESSION_PNG 5
22155 
22156 #define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6
22157 
22158 #define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256
22159 
22160 #define WUFFS_BMP__RLE_STATE_NEUTRAL 0
22161 
22162 #define WUFFS_BMP__RLE_STATE_RUN 1
22163 
22164 #define WUFFS_BMP__RLE_STATE_ESCAPE 2
22165 
22166 #define WUFFS_BMP__RLE_STATE_LITERAL 3
22167 
22168 #define WUFFS_BMP__RLE_STATE_DELTA_X 4
22169 
22170 #define WUFFS_BMP__RLE_STATE_DELTA_Y 5
22171 
22172 // ---------------- Private Initializer Prototypes
22173 
22174 // ---------------- Private Function Prototypes
22175 
22176 static wuffs_base__status
22177 wuffs_bmp__decoder__swizzle_none(
22178     wuffs_bmp__decoder* self,
22179     wuffs_base__pixel_buffer* a_dst,
22180     wuffs_base__io_buffer* a_src);
22181 
22182 static wuffs_base__status
22183 wuffs_bmp__decoder__swizzle_rle(
22184     wuffs_bmp__decoder* self,
22185     wuffs_base__pixel_buffer* a_dst,
22186     wuffs_base__io_buffer* a_src);
22187 
22188 static wuffs_base__status
22189 wuffs_bmp__decoder__swizzle_bitfields(
22190     wuffs_bmp__decoder* self,
22191     wuffs_base__pixel_buffer* a_dst,
22192     wuffs_base__io_buffer* a_src);
22193 
22194 static wuffs_base__status
22195 wuffs_bmp__decoder__swizzle_low_bit_depth(
22196     wuffs_bmp__decoder* self,
22197     wuffs_base__pixel_buffer* a_dst,
22198     wuffs_base__io_buffer* a_src);
22199 
22200 static wuffs_base__status
22201 wuffs_bmp__decoder__read_palette(
22202     wuffs_bmp__decoder* self,
22203     wuffs_base__io_buffer* a_src);
22204 
22205 static wuffs_base__status
22206 wuffs_bmp__decoder__process_masks(
22207     wuffs_bmp__decoder* self);
22208 
22209 // ---------------- VTables
22210 
22211 const wuffs_base__image_decoder__func_ptrs
22212 wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
22213   (wuffs_base__status(*)(void*,
22214       wuffs_base__pixel_buffer*,
22215       wuffs_base__io_buffer*,
22216       wuffs_base__pixel_blend,
22217       wuffs_base__slice_u8,
22218       wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame),
22219   (wuffs_base__status(*)(void*,
22220       wuffs_base__frame_config*,
22221       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config),
22222   (wuffs_base__status(*)(void*,
22223       wuffs_base__image_config*,
22224       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config),
22225   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect),
22226   (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops),
22227   (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs),
22228   (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames),
22229   (wuffs_base__status(*)(void*,
22230       uint64_t,
22231       uint64_t))(&wuffs_bmp__decoder__restart_frame),
22232   (wuffs_base__empty_struct(*)(void*,
22233       uint32_t,
22234       bool))(&wuffs_bmp__decoder__set_quirk_enabled),
22235   (wuffs_base__empty_struct(*)(void*,
22236       uint32_t,
22237       bool))(&wuffs_bmp__decoder__set_report_metadata),
22238   (wuffs_base__status(*)(void*,
22239       wuffs_base__io_buffer*,
22240       wuffs_base__more_information*,
22241       wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more),
22242   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len),
22243 };
22244 
22245 // ---------------- Initializer Implementations
22246 
22247 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)22248 wuffs_bmp__decoder__initialize(
22249     wuffs_bmp__decoder* self,
22250     size_t sizeof_star_self,
22251     uint64_t wuffs_version,
22252     uint32_t options){
22253   if (!self) {
22254     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22255   }
22256   if (sizeof(*self) != sizeof_star_self) {
22257     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
22258   }
22259   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
22260       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
22261     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
22262   }
22263 
22264   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
22265     // The whole point of this if-check is to detect an uninitialized *self.
22266     // We disable the warning on GCC. Clang-5.0 does not have this warning.
22267 #if !defined(__clang__) && defined(__GNUC__)
22268 #pragma GCC diagnostic push
22269 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
22270 #endif
22271     if (self->private_impl.magic != 0) {
22272       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
22273     }
22274 #if !defined(__clang__) && defined(__GNUC__)
22275 #pragma GCC diagnostic pop
22276 #endif
22277   } else {
22278     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
22279       memset(self, 0, sizeof(*self));
22280       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
22281     } else {
22282       memset(&(self->private_impl), 0, sizeof(self->private_impl));
22283     }
22284   }
22285 
22286   self->private_impl.magic = WUFFS_BASE__MAGIC;
22287   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
22288       wuffs_base__image_decoder__vtable_name;
22289   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
22290       (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
22291   return wuffs_base__make_status(NULL);
22292 }
22293 
22294 wuffs_bmp__decoder*
wuffs_bmp__decoder__alloc()22295 wuffs_bmp__decoder__alloc() {
22296   wuffs_bmp__decoder* x =
22297       (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
22298   if (!x) {
22299     return NULL;
22300   }
22301   if (wuffs_bmp__decoder__initialize(
22302       x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
22303     free(x);
22304     return NULL;
22305   }
22306   return x;
22307 }
22308 
22309 size_t
sizeof__wuffs_bmp__decoder()22310 sizeof__wuffs_bmp__decoder() {
22311   return sizeof(wuffs_bmp__decoder);
22312 }
22313 
22314 // ---------------- Function Implementations
22315 
22316 // -------- func bmp.decoder.set_quirk_enabled
22317 
22318 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)22319 wuffs_bmp__decoder__set_quirk_enabled(
22320     wuffs_bmp__decoder* self,
22321     uint32_t a_quirk,
22322     bool a_enabled) {
22323   return wuffs_base__make_empty_struct();
22324 }
22325 
22326 // -------- func bmp.decoder.decode_image_config
22327 
22328 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)22329 wuffs_bmp__decoder__decode_image_config(
22330     wuffs_bmp__decoder* self,
22331     wuffs_base__image_config* a_dst,
22332     wuffs_base__io_buffer* a_src) {
22333   if (!self) {
22334     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22335   }
22336   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
22337     return wuffs_base__make_status(
22338         (self->private_impl.magic == WUFFS_BASE__DISABLED)
22339         ? wuffs_base__error__disabled_by_previous_error
22340         : wuffs_base__error__initialize_not_called);
22341   }
22342   if (!a_src) {
22343     self->private_impl.magic = WUFFS_BASE__DISABLED;
22344     return wuffs_base__make_status(wuffs_base__error__bad_argument);
22345   }
22346   if ((self->private_impl.active_coroutine != 0) &&
22347       (self->private_impl.active_coroutine != 1)) {
22348     self->private_impl.magic = WUFFS_BASE__DISABLED;
22349     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
22350   }
22351   self->private_impl.active_coroutine = 0;
22352   wuffs_base__status status = wuffs_base__make_status(NULL);
22353 
22354   uint32_t v_magic = 0;
22355   uint32_t v_width = 0;
22356   uint32_t v_height = 0;
22357   uint32_t v_planes = 0;
22358   uint32_t v_dst_pixfmt = 0;
22359   uint32_t v_byte_width = 0;
22360 
22361   const uint8_t* iop_a_src = NULL;
22362   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22363   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22364   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22365   if (a_src) {
22366     io0_a_src = a_src->data.ptr;
22367     io1_a_src = io0_a_src + a_src->meta.ri;
22368     iop_a_src = io1_a_src;
22369     io2_a_src = io0_a_src + a_src->meta.wi;
22370   }
22371 
22372   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
22373   switch (coro_susp_point) {
22374     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
22375 
22376     if ((self->private_impl.f_call_sequence != 0) || (self->private_impl.f_io_redirect_fourcc == 1)) {
22377       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
22378       goto exit;
22379     } else if (self->private_impl.f_io_redirect_fourcc != 0) {
22380       status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22381       goto ok;
22382     }
22383     {
22384       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
22385       uint32_t t_0;
22386       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22387         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22388         iop_a_src += 2;
22389       } else {
22390         self->private_data.s_decode_image_config[0].scratch = 0;
22391         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
22392         while (true) {
22393           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22394             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22395             goto suspend;
22396           }
22397           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22398           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
22399           *scratch <<= 8;
22400           *scratch >>= 8;
22401           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
22402           if (num_bits_0 == 8) {
22403             t_0 = ((uint32_t)(*scratch));
22404             break;
22405           }
22406           num_bits_0 += 8;
22407           *scratch |= ((uint64_t)(num_bits_0)) << 56;
22408         }
22409       }
22410       v_magic = t_0;
22411     }
22412     if (v_magic != 19778) {
22413       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22414       goto exit;
22415     }
22416     self->private_data.s_decode_image_config[0].scratch = 8;
22417     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
22418     if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22419       self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22420       iop_a_src = io2_a_src;
22421       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22422       goto suspend;
22423     }
22424     iop_a_src += self->private_data.s_decode_image_config[0].scratch;
22425     {
22426       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
22427       uint32_t t_1;
22428       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22429         t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22430         iop_a_src += 4;
22431       } else {
22432         self->private_data.s_decode_image_config[0].scratch = 0;
22433         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
22434         while (true) {
22435           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22436             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22437             goto suspend;
22438           }
22439           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22440           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
22441           *scratch <<= 8;
22442           *scratch >>= 8;
22443           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
22444           if (num_bits_1 == 24) {
22445             t_1 = ((uint32_t)(*scratch));
22446             break;
22447           }
22448           num_bits_1 += 8;
22449           *scratch |= ((uint64_t)(num_bits_1)) << 56;
22450         }
22451       }
22452       self->private_impl.f_padding = t_1;
22453     }
22454     if (self->private_impl.f_padding < 14) {
22455       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22456       goto exit;
22457     }
22458     self->private_impl.f_padding -= 14;
22459     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))));
22460     {
22461       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
22462       uint32_t t_2;
22463       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22464         t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22465         iop_a_src += 4;
22466       } else {
22467         self->private_data.s_decode_image_config[0].scratch = 0;
22468         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
22469         while (true) {
22470           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22471             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22472             goto suspend;
22473           }
22474           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22475           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
22476           *scratch <<= 8;
22477           *scratch >>= 8;
22478           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
22479           if (num_bits_2 == 24) {
22480             t_2 = ((uint32_t)(*scratch));
22481             break;
22482           }
22483           num_bits_2 += 8;
22484           *scratch |= ((uint64_t)(num_bits_2)) << 56;
22485         }
22486       }
22487       self->private_impl.f_bitmap_info_len = t_2;
22488     }
22489     if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) {
22490       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22491       goto exit;
22492     }
22493     self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len;
22494     if (self->private_impl.f_bitmap_info_len == 12) {
22495       {
22496         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
22497         uint32_t t_3;
22498         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22499           t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22500           iop_a_src += 2;
22501         } else {
22502           self->private_data.s_decode_image_config[0].scratch = 0;
22503           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
22504           while (true) {
22505             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22506               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22507               goto suspend;
22508             }
22509             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22510             uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
22511             *scratch <<= 8;
22512             *scratch >>= 8;
22513             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
22514             if (num_bits_3 == 8) {
22515               t_3 = ((uint32_t)(*scratch));
22516               break;
22517             }
22518             num_bits_3 += 8;
22519             *scratch |= ((uint64_t)(num_bits_3)) << 56;
22520           }
22521         }
22522         self->private_impl.f_width = t_3;
22523       }
22524       {
22525         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
22526         uint32_t t_4;
22527         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22528           t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22529           iop_a_src += 2;
22530         } else {
22531           self->private_data.s_decode_image_config[0].scratch = 0;
22532           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
22533           while (true) {
22534             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22535               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22536               goto suspend;
22537             }
22538             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22539             uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
22540             *scratch <<= 8;
22541             *scratch >>= 8;
22542             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
22543             if (num_bits_4 == 8) {
22544               t_4 = ((uint32_t)(*scratch));
22545               break;
22546             }
22547             num_bits_4 += 8;
22548             *scratch |= ((uint64_t)(num_bits_4)) << 56;
22549           }
22550         }
22551         self->private_impl.f_height = t_4;
22552       }
22553       {
22554         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
22555         uint32_t t_5;
22556         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22557           t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22558           iop_a_src += 2;
22559         } else {
22560           self->private_data.s_decode_image_config[0].scratch = 0;
22561           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
22562           while (true) {
22563             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22564               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22565               goto suspend;
22566             }
22567             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22568             uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
22569             *scratch <<= 8;
22570             *scratch >>= 8;
22571             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
22572             if (num_bits_5 == 8) {
22573               t_5 = ((uint32_t)(*scratch));
22574               break;
22575             }
22576             num_bits_5 += 8;
22577             *scratch |= ((uint64_t)(num_bits_5)) << 56;
22578           }
22579         }
22580         v_planes = t_5;
22581       }
22582       if (v_planes != 1) {
22583         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22584         goto exit;
22585       }
22586       {
22587         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
22588         uint32_t t_6;
22589         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22590           t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22591           iop_a_src += 2;
22592         } else {
22593           self->private_data.s_decode_image_config[0].scratch = 0;
22594           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
22595           while (true) {
22596             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22597               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22598               goto suspend;
22599             }
22600             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22601             uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
22602             *scratch <<= 8;
22603             *scratch >>= 8;
22604             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
22605             if (num_bits_6 == 8) {
22606               t_6 = ((uint32_t)(*scratch));
22607               break;
22608             }
22609             num_bits_6 += 8;
22610             *scratch |= ((uint64_t)(num_bits_6)) << 56;
22611           }
22612         }
22613         self->private_impl.f_bits_per_pixel = t_6;
22614       }
22615     } else if (self->private_impl.f_bitmap_info_len == 16) {
22616       {
22617         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
22618         uint32_t t_7;
22619         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22620           t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22621           iop_a_src += 4;
22622         } else {
22623           self->private_data.s_decode_image_config[0].scratch = 0;
22624           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
22625           while (true) {
22626             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22627               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22628               goto suspend;
22629             }
22630             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22631             uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
22632             *scratch <<= 8;
22633             *scratch >>= 8;
22634             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
22635             if (num_bits_7 == 24) {
22636               t_7 = ((uint32_t)(*scratch));
22637               break;
22638             }
22639             num_bits_7 += 8;
22640             *scratch |= ((uint64_t)(num_bits_7)) << 56;
22641           }
22642         }
22643         v_width = t_7;
22644       }
22645       if (v_width >= 2147483648) {
22646         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22647         goto exit;
22648       }
22649       self->private_impl.f_width = v_width;
22650       {
22651         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
22652         uint32_t t_8;
22653         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22654           t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22655           iop_a_src += 4;
22656         } else {
22657           self->private_data.s_decode_image_config[0].scratch = 0;
22658           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
22659           while (true) {
22660             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22661               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22662               goto suspend;
22663             }
22664             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22665             uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
22666             *scratch <<= 8;
22667             *scratch >>= 8;
22668             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
22669             if (num_bits_8 == 24) {
22670               t_8 = ((uint32_t)(*scratch));
22671               break;
22672             }
22673             num_bits_8 += 8;
22674             *scratch |= ((uint64_t)(num_bits_8)) << 56;
22675           }
22676         }
22677         v_height = t_8;
22678       }
22679       if (v_height >= 2147483648) {
22680         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22681         goto exit;
22682       }
22683       self->private_impl.f_height = v_height;
22684       {
22685         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
22686         uint32_t t_9;
22687         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22688           t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22689           iop_a_src += 2;
22690         } else {
22691           self->private_data.s_decode_image_config[0].scratch = 0;
22692           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
22693           while (true) {
22694             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22695               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22696               goto suspend;
22697             }
22698             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22699             uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
22700             *scratch <<= 8;
22701             *scratch >>= 8;
22702             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
22703             if (num_bits_9 == 8) {
22704               t_9 = ((uint32_t)(*scratch));
22705               break;
22706             }
22707             num_bits_9 += 8;
22708             *scratch |= ((uint64_t)(num_bits_9)) << 56;
22709           }
22710         }
22711         v_planes = t_9;
22712       }
22713       if (v_planes != 1) {
22714         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22715         goto exit;
22716       }
22717       {
22718         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
22719         uint32_t t_10;
22720         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22721           t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22722           iop_a_src += 2;
22723         } else {
22724           self->private_data.s_decode_image_config[0].scratch = 0;
22725           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
22726           while (true) {
22727             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22728               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22729               goto suspend;
22730             }
22731             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22732             uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
22733             *scratch <<= 8;
22734             *scratch >>= 8;
22735             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
22736             if (num_bits_10 == 8) {
22737               t_10 = ((uint32_t)(*scratch));
22738               break;
22739             }
22740             num_bits_10 += 8;
22741             *scratch |= ((uint64_t)(num_bits_10)) << 56;
22742           }
22743         }
22744         self->private_impl.f_bits_per_pixel = t_10;
22745       }
22746     } else {
22747       {
22748         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
22749         uint32_t t_11;
22750         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22751           t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22752           iop_a_src += 4;
22753         } else {
22754           self->private_data.s_decode_image_config[0].scratch = 0;
22755           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
22756           while (true) {
22757             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22758               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22759               goto suspend;
22760             }
22761             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22762             uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
22763             *scratch <<= 8;
22764             *scratch >>= 8;
22765             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
22766             if (num_bits_11 == 24) {
22767               t_11 = ((uint32_t)(*scratch));
22768               break;
22769             }
22770             num_bits_11 += 8;
22771             *scratch |= ((uint64_t)(num_bits_11)) << 56;
22772           }
22773         }
22774         v_width = t_11;
22775       }
22776       if (v_width >= 2147483648) {
22777         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22778         goto exit;
22779       }
22780       self->private_impl.f_width = v_width;
22781       {
22782         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
22783         uint32_t t_12;
22784         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22785           t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22786           iop_a_src += 4;
22787         } else {
22788           self->private_data.s_decode_image_config[0].scratch = 0;
22789           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
22790           while (true) {
22791             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22792               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22793               goto suspend;
22794             }
22795             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22796             uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
22797             *scratch <<= 8;
22798             *scratch >>= 8;
22799             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
22800             if (num_bits_12 == 24) {
22801               t_12 = ((uint32_t)(*scratch));
22802               break;
22803             }
22804             num_bits_12 += 8;
22805             *scratch |= ((uint64_t)(num_bits_12)) << 56;
22806           }
22807         }
22808         v_height = t_12;
22809       }
22810       if (v_height == 2147483648) {
22811         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22812         goto exit;
22813       } else if (v_height >= 2147483648) {
22814         self->private_impl.f_height = (((uint32_t)(0 - v_height)) & 2147483647);
22815         self->private_impl.f_top_down = true;
22816       } else {
22817         self->private_impl.f_height = v_height;
22818       }
22819       {
22820         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
22821         uint32_t t_13;
22822         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22823           t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22824           iop_a_src += 2;
22825         } else {
22826           self->private_data.s_decode_image_config[0].scratch = 0;
22827           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
22828           while (true) {
22829             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22830               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22831               goto suspend;
22832             }
22833             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22834             uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56));
22835             *scratch <<= 8;
22836             *scratch >>= 8;
22837             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13;
22838             if (num_bits_13 == 8) {
22839               t_13 = ((uint32_t)(*scratch));
22840               break;
22841             }
22842             num_bits_13 += 8;
22843             *scratch |= ((uint64_t)(num_bits_13)) << 56;
22844           }
22845         }
22846         v_planes = t_13;
22847       }
22848       if (v_planes != 1) {
22849         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22850         goto exit;
22851       }
22852       {
22853         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
22854         uint32_t t_14;
22855         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22856           t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22857           iop_a_src += 2;
22858         } else {
22859           self->private_data.s_decode_image_config[0].scratch = 0;
22860           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31);
22861           while (true) {
22862             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22863               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22864               goto suspend;
22865             }
22866             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22867             uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56));
22868             *scratch <<= 8;
22869             *scratch >>= 8;
22870             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14;
22871             if (num_bits_14 == 8) {
22872               t_14 = ((uint32_t)(*scratch));
22873               break;
22874             }
22875             num_bits_14 += 8;
22876             *scratch |= ((uint64_t)(num_bits_14)) << 56;
22877           }
22878         }
22879         self->private_impl.f_bits_per_pixel = t_14;
22880       }
22881       {
22882         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
22883         uint32_t t_15;
22884         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22885           t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22886           iop_a_src += 4;
22887         } else {
22888           self->private_data.s_decode_image_config[0].scratch = 0;
22889           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
22890           while (true) {
22891             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22892               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22893               goto suspend;
22894             }
22895             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22896             uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56));
22897             *scratch <<= 8;
22898             *scratch >>= 8;
22899             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15;
22900             if (num_bits_15 == 24) {
22901               t_15 = ((uint32_t)(*scratch));
22902               break;
22903             }
22904             num_bits_15 += 8;
22905             *scratch |= ((uint64_t)(num_bits_15)) << 56;
22906           }
22907         }
22908         self->private_impl.f_compression = t_15;
22909       }
22910       if (self->private_impl.f_bits_per_pixel == 0) {
22911         if (self->private_impl.f_compression == 4) {
22912           self->private_impl.f_io_redirect_fourcc = 1246774599;
22913           status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22914           goto ok;
22915         } else if (self->private_impl.f_compression == 5) {
22916           self->private_impl.f_io_redirect_fourcc = 1347307296;
22917           status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22918           goto ok;
22919         }
22920         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22921         goto exit;
22922       }
22923       self->private_data.s_decode_image_config[0].scratch = 20;
22924       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34);
22925       if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22926         self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22927         iop_a_src = io2_a_src;
22928         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22929         goto suspend;
22930       }
22931       iop_a_src += self->private_data.s_decode_image_config[0].scratch;
22932       if (self->private_impl.f_bitmap_info_len == 40) {
22933         if (self->private_impl.f_bits_per_pixel >= 16) {
22934           if (self->private_impl.f_padding >= 16) {
22935             self->private_impl.f_bitmap_info_len = 56;
22936             self->private_impl.f_padding -= 16;
22937           } else if (self->private_impl.f_padding >= 12) {
22938             self->private_impl.f_bitmap_info_len = 52;
22939             self->private_impl.f_padding -= 12;
22940           }
22941         }
22942       } else if ((self->private_impl.f_bitmap_info_len != 52) &&
22943           (self->private_impl.f_bitmap_info_len != 56) &&
22944           (self->private_impl.f_bitmap_info_len != 64) &&
22945           (self->private_impl.f_bitmap_info_len != 108) &&
22946           (self->private_impl.f_bitmap_info_len != 124)) {
22947         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22948         goto exit;
22949       }
22950       if (self->private_impl.f_compression == 6) {
22951         self->private_impl.f_compression = 3;
22952       }
22953       if (self->private_impl.f_compression == 3) {
22954         if (self->private_impl.f_bitmap_info_len >= 52) {
22955           {
22956             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35);
22957             uint32_t t_16;
22958             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22959               t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22960               iop_a_src += 4;
22961             } else {
22962               self->private_data.s_decode_image_config[0].scratch = 0;
22963               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36);
22964               while (true) {
22965                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22966                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22967                   goto suspend;
22968                 }
22969                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22970                 uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56));
22971                 *scratch <<= 8;
22972                 *scratch >>= 8;
22973                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16;
22974                 if (num_bits_16 == 24) {
22975                   t_16 = ((uint32_t)(*scratch));
22976                   break;
22977                 }
22978                 num_bits_16 += 8;
22979                 *scratch |= ((uint64_t)(num_bits_16)) << 56;
22980               }
22981             }
22982             self->private_impl.f_channel_masks[2] = t_16;
22983           }
22984           {
22985             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37);
22986             uint32_t t_17;
22987             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22988               t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22989               iop_a_src += 4;
22990             } else {
22991               self->private_data.s_decode_image_config[0].scratch = 0;
22992               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38);
22993               while (true) {
22994                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22995                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22996                   goto suspend;
22997                 }
22998                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22999                 uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56));
23000                 *scratch <<= 8;
23001                 *scratch >>= 8;
23002                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17;
23003                 if (num_bits_17 == 24) {
23004                   t_17 = ((uint32_t)(*scratch));
23005                   break;
23006                 }
23007                 num_bits_17 += 8;
23008                 *scratch |= ((uint64_t)(num_bits_17)) << 56;
23009               }
23010             }
23011             self->private_impl.f_channel_masks[1] = t_17;
23012           }
23013           {
23014             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39);
23015             uint32_t t_18;
23016             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
23017               t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23018               iop_a_src += 4;
23019             } else {
23020               self->private_data.s_decode_image_config[0].scratch = 0;
23021               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40);
23022               while (true) {
23023                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
23024                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23025                   goto suspend;
23026                 }
23027                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
23028                 uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56));
23029                 *scratch <<= 8;
23030                 *scratch >>= 8;
23031                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18;
23032                 if (num_bits_18 == 24) {
23033                   t_18 = ((uint32_t)(*scratch));
23034                   break;
23035                 }
23036                 num_bits_18 += 8;
23037                 *scratch |= ((uint64_t)(num_bits_18)) << 56;
23038               }
23039             }
23040             self->private_impl.f_channel_masks[0] = t_18;
23041           }
23042           if (self->private_impl.f_bitmap_info_len >= 56) {
23043             {
23044               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41);
23045               uint32_t t_19;
23046               if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
23047                 t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23048                 iop_a_src += 4;
23049               } else {
23050                 self->private_data.s_decode_image_config[0].scratch = 0;
23051                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42);
23052                 while (true) {
23053                   if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
23054                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23055                     goto suspend;
23056                   }
23057                   uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
23058                   uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56));
23059                   *scratch <<= 8;
23060                   *scratch >>= 8;
23061                   *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19;
23062                   if (num_bits_19 == 24) {
23063                     t_19 = ((uint32_t)(*scratch));
23064                     break;
23065                   }
23066                   num_bits_19 += 8;
23067                   *scratch |= ((uint64_t)(num_bits_19)) << 56;
23068                 }
23069               }
23070               self->private_impl.f_channel_masks[3] = t_19;
23071             }
23072             self->private_data.s_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56));
23073             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43);
23074             if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23075               self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23076               iop_a_src = io2_a_src;
23077               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23078               goto suspend;
23079             }
23080             iop_a_src += self->private_data.s_decode_image_config[0].scratch;
23081           }
23082           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)) {
23083             if (self->private_impl.f_bits_per_pixel == 24) {
23084               self->private_impl.f_compression = 0;
23085             } else if (self->private_impl.f_bits_per_pixel == 32) {
23086               if ((self->private_impl.f_channel_masks[3] == 0) || (self->private_impl.f_channel_masks[3] == 4278190080)) {
23087                 self->private_impl.f_compression = 0;
23088               }
23089             }
23090           }
23091           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44);
23092           status = wuffs_bmp__decoder__process_masks(self);
23093           if (status.repr) {
23094             goto suspend;
23095           }
23096         }
23097       } else if (self->private_impl.f_bitmap_info_len >= 40) {
23098         self->private_data.s_decode_image_config[0].scratch = (self->private_impl.f_bitmap_info_len - 40);
23099         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45);
23100         if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23101           self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23102           iop_a_src = io2_a_src;
23103           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23104           goto suspend;
23105         }
23106         iop_a_src += self->private_data.s_decode_image_config[0].scratch;
23107       } else {
23108         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23109         goto exit;
23110       }
23111     }
23112     if (self->private_impl.f_compression != 3) {
23113       if (self->private_impl.f_bits_per_pixel < 16) {
23114         if (a_src) {
23115           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23116         }
23117         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46);
23118         status = wuffs_bmp__decoder__read_palette(self, a_src);
23119         if (a_src) {
23120           iop_a_src = a_src->data.ptr + a_src->meta.ri;
23121         }
23122         if (status.repr) {
23123           goto suspend;
23124         }
23125       }
23126     }
23127     if (self->private_impl.f_compression == 0) {
23128       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)) {
23129         self->private_impl.f_src_pixfmt = 2198077448;
23130         self->private_impl.f_compression = 256;
23131       } else if (self->private_impl.f_bits_per_pixel == 8) {
23132         self->private_impl.f_src_pixfmt = 2198077448;
23133       } else if (self->private_impl.f_bits_per_pixel == 16) {
23134         self->private_impl.f_compression = 3;
23135         self->private_impl.f_channel_masks[0] = 31;
23136         self->private_impl.f_channel_masks[1] = 992;
23137         self->private_impl.f_channel_masks[2] = 31744;
23138         self->private_impl.f_channel_masks[3] = 0;
23139         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47);
23140         status = wuffs_bmp__decoder__process_masks(self);
23141         if (status.repr) {
23142           goto suspend;
23143         }
23144         self->private_impl.f_src_pixfmt = 2164308923;
23145       } else if (self->private_impl.f_bits_per_pixel == 24) {
23146         self->private_impl.f_src_pixfmt = 2147485832;
23147       } else if (self->private_impl.f_bits_per_pixel == 32) {
23148         if (self->private_impl.f_channel_masks[3] == 0) {
23149           self->private_impl.f_src_pixfmt = 2415954056;
23150         } else {
23151           self->private_impl.f_src_pixfmt = 2164295816;
23152         }
23153       } else {
23154         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23155         goto exit;
23156       }
23157     } else if (self->private_impl.f_compression == 1) {
23158       if (self->private_impl.f_bits_per_pixel == 8) {
23159         self->private_impl.f_src_pixfmt = 2198077448;
23160       } else {
23161         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23162         goto exit;
23163       }
23164     } else if (self->private_impl.f_compression == 2) {
23165       if (self->private_impl.f_bits_per_pixel == 4) {
23166         self->private_impl.f_src_pixfmt = 2198077448;
23167       } else {
23168         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23169         goto exit;
23170       }
23171     } else if (self->private_impl.f_compression == 3) {
23172       if ((self->private_impl.f_bits_per_pixel == 16) || (self->private_impl.f_bits_per_pixel == 32)) {
23173         self->private_impl.f_src_pixfmt = 2164308923;
23174       } else {
23175         status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23176         goto exit;
23177       }
23178     } else {
23179       status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23180       goto exit;
23181     }
23182     if (((self->private_impl.f_bitmap_info_len < 40) || (self->private_impl.f_bitmap_info_len == 64)) &&
23183         (self->private_impl.f_bits_per_pixel != 1) &&
23184         (self->private_impl.f_bits_per_pixel != 4) &&
23185         (self->private_impl.f_bits_per_pixel != 8) &&
23186         (self->private_impl.f_bits_per_pixel != 24)) {
23187       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
23188       goto exit;
23189     }
23190     if (self->private_impl.f_bits_per_pixel == 1) {
23191       v_byte_width = ((self->private_impl.f_width >> 3) + (((self->private_impl.f_width & 7) + 7) >> 3));
23192       self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
23193     } else if (self->private_impl.f_bits_per_pixel == 2) {
23194       v_byte_width = ((self->private_impl.f_width >> 2) + (((self->private_impl.f_width & 3) + 3) >> 2));
23195       self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
23196     } else if (self->private_impl.f_bits_per_pixel == 4) {
23197       v_byte_width = ((self->private_impl.f_width >> 1) + (self->private_impl.f_width & 1));
23198       self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
23199     } else if (self->private_impl.f_bits_per_pixel == 8) {
23200       self->private_impl.f_pad_per_row = ((4 - (self->private_impl.f_width & 3)) & 3);
23201     } else if (self->private_impl.f_bits_per_pixel == 16) {
23202       self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1) * 2);
23203     } else if (self->private_impl.f_bits_per_pixel == 24) {
23204       self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3);
23205     } else if (self->private_impl.f_bits_per_pixel == 32) {
23206       self->private_impl.f_pad_per_row = 0;
23207     }
23208     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)));
23209     if (a_dst != NULL) {
23210       v_dst_pixfmt = 2164295816;
23211       if ((self->private_impl.f_channel_num_bits[0] > 8) ||
23212           (self->private_impl.f_channel_num_bits[1] > 8) ||
23213           (self->private_impl.f_channel_num_bits[2] > 8) ||
23214           (self->private_impl.f_channel_num_bits[3] > 8)) {
23215         v_dst_pixfmt = 2164308923;
23216       }
23217       wuffs_base__image_config__set(
23218           a_dst,
23219           v_dst_pixfmt,
23220           0,
23221           self->private_impl.f_width,
23222           self->private_impl.f_height,
23223           self->private_impl.f_frame_config_io_position,
23224           (self->private_impl.f_channel_masks[3] == 0));
23225     }
23226     self->private_impl.f_call_sequence = 3;
23227 
23228     ok:
23229     self->private_impl.p_decode_image_config[0] = 0;
23230     goto exit;
23231   }
23232 
23233   goto suspend;
23234   suspend:
23235   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23236   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
23237 
23238   goto exit;
23239   exit:
23240   if (a_src) {
23241     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23242   }
23243 
23244   if (wuffs_base__status__is_error(&status)) {
23245     self->private_impl.magic = WUFFS_BASE__DISABLED;
23246   }
23247   return status;
23248 }
23249 
23250 // -------- func bmp.decoder.decode_frame_config
23251 
23252 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)23253 wuffs_bmp__decoder__decode_frame_config(
23254     wuffs_bmp__decoder* self,
23255     wuffs_base__frame_config* a_dst,
23256     wuffs_base__io_buffer* a_src) {
23257   if (!self) {
23258     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23259   }
23260   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
23261     return wuffs_base__make_status(
23262         (self->private_impl.magic == WUFFS_BASE__DISABLED)
23263         ? wuffs_base__error__disabled_by_previous_error
23264         : wuffs_base__error__initialize_not_called);
23265   }
23266   if (!a_src) {
23267     self->private_impl.magic = WUFFS_BASE__DISABLED;
23268     return wuffs_base__make_status(wuffs_base__error__bad_argument);
23269   }
23270   if ((self->private_impl.active_coroutine != 0) &&
23271       (self->private_impl.active_coroutine != 2)) {
23272     self->private_impl.magic = WUFFS_BASE__DISABLED;
23273     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
23274   }
23275   self->private_impl.active_coroutine = 0;
23276   wuffs_base__status status = wuffs_base__make_status(NULL);
23277 
23278   const uint8_t* iop_a_src = NULL;
23279   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23280   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23281   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23282   if (a_src) {
23283     io0_a_src = a_src->data.ptr;
23284     io1_a_src = io0_a_src + a_src->meta.ri;
23285     iop_a_src = io1_a_src;
23286     io2_a_src = io0_a_src + a_src->meta.wi;
23287   }
23288 
23289   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
23290   switch (coro_susp_point) {
23291     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23292 
23293     if (self->private_impl.f_call_sequence < 3) {
23294       if (a_src) {
23295         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23296       }
23297       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
23298       status = wuffs_bmp__decoder__decode_image_config(self, NULL, a_src);
23299       if (a_src) {
23300         iop_a_src = a_src->data.ptr + a_src->meta.ri;
23301       }
23302       if (status.repr) {
23303         goto suspend;
23304       }
23305     } else if (self->private_impl.f_call_sequence == 3) {
23306       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)))) {
23307         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
23308         goto exit;
23309       }
23310     } else if (self->private_impl.f_call_sequence == 4) {
23311       self->private_impl.f_call_sequence = 255;
23312       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
23313       goto ok;
23314     } else {
23315       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
23316       goto ok;
23317     }
23318     if (a_dst != NULL) {
23319       wuffs_base__frame_config__set(
23320           a_dst,
23321           wuffs_base__utility__make_rect_ie_u32(
23322           0,
23323           0,
23324           self->private_impl.f_width,
23325           self->private_impl.f_height),
23326           ((wuffs_base__flicks)(0)),
23327           0,
23328           self->private_impl.f_frame_config_io_position,
23329           0,
23330           true,
23331           false,
23332           4278190080);
23333     }
23334     self->private_impl.f_call_sequence = 4;
23335 
23336     ok:
23337     self->private_impl.p_decode_frame_config[0] = 0;
23338     goto exit;
23339   }
23340 
23341   goto suspend;
23342   suspend:
23343   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23344   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
23345 
23346   goto exit;
23347   exit:
23348   if (a_src) {
23349     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23350   }
23351 
23352   if (wuffs_base__status__is_error(&status)) {
23353     self->private_impl.magic = WUFFS_BASE__DISABLED;
23354   }
23355   return status;
23356 }
23357 
23358 // -------- func bmp.decoder.decode_frame
23359 
23360 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)23361 wuffs_bmp__decoder__decode_frame(
23362     wuffs_bmp__decoder* self,
23363     wuffs_base__pixel_buffer* a_dst,
23364     wuffs_base__io_buffer* a_src,
23365     wuffs_base__pixel_blend a_blend,
23366     wuffs_base__slice_u8 a_workbuf,
23367     wuffs_base__decode_frame_options* a_opts) {
23368   if (!self) {
23369     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23370   }
23371   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
23372     return wuffs_base__make_status(
23373         (self->private_impl.magic == WUFFS_BASE__DISABLED)
23374         ? wuffs_base__error__disabled_by_previous_error
23375         : wuffs_base__error__initialize_not_called);
23376   }
23377   if (!a_dst || !a_src) {
23378     self->private_impl.magic = WUFFS_BASE__DISABLED;
23379     return wuffs_base__make_status(wuffs_base__error__bad_argument);
23380   }
23381   if ((self->private_impl.active_coroutine != 0) &&
23382       (self->private_impl.active_coroutine != 3)) {
23383     self->private_impl.magic = WUFFS_BASE__DISABLED;
23384     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
23385   }
23386   self->private_impl.active_coroutine = 0;
23387   wuffs_base__status status = wuffs_base__make_status(NULL);
23388 
23389   wuffs_base__status v_status = wuffs_base__make_status(NULL);
23390 
23391   const uint8_t* iop_a_src = NULL;
23392   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23393   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23394   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23395   if (a_src) {
23396     io0_a_src = a_src->data.ptr;
23397     io1_a_src = io0_a_src + a_src->meta.ri;
23398     iop_a_src = io1_a_src;
23399     io2_a_src = io0_a_src + a_src->meta.wi;
23400   }
23401 
23402   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
23403   if (coro_susp_point) {
23404     v_status = self->private_data.s_decode_frame[0].v_status;
23405   }
23406   switch (coro_susp_point) {
23407     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23408 
23409     if (self->private_impl.f_call_sequence < 4) {
23410       if (a_src) {
23411         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23412       }
23413       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
23414       status = wuffs_bmp__decoder__decode_frame_config(self, NULL, a_src);
23415       if (a_src) {
23416         iop_a_src = a_src->data.ptr + a_src->meta.ri;
23417       }
23418       if (status.repr) {
23419         goto suspend;
23420       }
23421     } else if (self->private_impl.f_call_sequence == 4) {
23422     } else {
23423       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
23424       goto ok;
23425     }
23426     self->private_data.s_decode_frame[0].scratch = self->private_impl.f_padding;
23427     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
23428     if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23429       self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23430       iop_a_src = io2_a_src;
23431       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23432       goto suspend;
23433     }
23434     iop_a_src += self->private_data.s_decode_frame[0].scratch;
23435     if ((self->private_impl.f_width > 0) && (self->private_impl.f_height > 0)) {
23436       self->private_impl.f_dst_x = 0;
23437       if (self->private_impl.f_top_down) {
23438         self->private_impl.f_dst_y = 0;
23439         self->private_impl.f_dst_y_inc = 1;
23440       } else {
23441         self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1));
23442         self->private_impl.f_dst_y_inc = 4294967295;
23443       }
23444       v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
23445           wuffs_base__pixel_buffer__pixel_format(a_dst),
23446           wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024)),
23447           wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
23448           wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
23449           a_blend);
23450       if ( ! wuffs_base__status__is_ok(&v_status)) {
23451         status = v_status;
23452         if (wuffs_base__status__is_error(&status)) {
23453           goto exit;
23454         } else if (wuffs_base__status__is_suspension(&status)) {
23455           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
23456           goto exit;
23457         }
23458         goto ok;
23459       }
23460       while (true) {
23461         if (self->private_impl.f_compression == 0) {
23462           if (a_src) {
23463             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23464           }
23465           v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src);
23466           if (a_src) {
23467             iop_a_src = a_src->data.ptr + a_src->meta.ri;
23468           }
23469         } else if (self->private_impl.f_compression < 3) {
23470           if (a_src) {
23471             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23472           }
23473           v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src);
23474           if (a_src) {
23475             iop_a_src = a_src->data.ptr + a_src->meta.ri;
23476           }
23477         } else if (self->private_impl.f_compression == 3) {
23478           if (a_src) {
23479             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23480           }
23481           v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src);
23482           if (a_src) {
23483             iop_a_src = a_src->data.ptr + a_src->meta.ri;
23484           }
23485         } else {
23486           if (a_src) {
23487             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23488           }
23489           v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src);
23490           if (a_src) {
23491             iop_a_src = a_src->data.ptr + a_src->meta.ri;
23492           }
23493         }
23494         if (wuffs_base__status__is_ok(&v_status)) {
23495           goto label__0__break;
23496         } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) {
23497           status = v_status;
23498           if (wuffs_base__status__is_error(&status)) {
23499             goto exit;
23500           } else if (wuffs_base__status__is_suspension(&status)) {
23501             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
23502             goto exit;
23503           }
23504           goto ok;
23505         }
23506         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23507         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
23508       }
23509       label__0__break:;
23510       self->private_data.s_decode_frame[0].scratch = self->private_impl.f_pending_pad;
23511       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
23512       if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23513         self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23514         iop_a_src = io2_a_src;
23515         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23516         goto suspend;
23517       }
23518       iop_a_src += self->private_data.s_decode_frame[0].scratch;
23519       self->private_impl.f_pending_pad = 0;
23520     }
23521     self->private_impl.f_call_sequence = 255;
23522 
23523     ok:
23524     self->private_impl.p_decode_frame[0] = 0;
23525     goto exit;
23526   }
23527 
23528   goto suspend;
23529   suspend:
23530   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23531   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
23532   self->private_data.s_decode_frame[0].v_status = v_status;
23533 
23534   goto exit;
23535   exit:
23536   if (a_src) {
23537     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23538   }
23539 
23540   if (wuffs_base__status__is_error(&status)) {
23541     self->private_impl.magic = WUFFS_BASE__DISABLED;
23542   }
23543   return status;
23544 }
23545 
23546 // -------- func bmp.decoder.swizzle_none
23547 
23548 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)23549 wuffs_bmp__decoder__swizzle_none(
23550     wuffs_bmp__decoder* self,
23551     wuffs_base__pixel_buffer* a_dst,
23552     wuffs_base__io_buffer* a_src) {
23553   wuffs_base__status status = wuffs_base__make_status(NULL);
23554 
23555   wuffs_base__pixel_format v_dst_pixfmt = {0};
23556   uint32_t v_dst_bits_per_pixel = 0;
23557   uint64_t v_dst_bytes_per_pixel = 0;
23558   uint64_t v_dst_bytes_per_row = 0;
23559   wuffs_base__slice_u8 v_dst_palette = {0};
23560   wuffs_base__table_u8 v_tab = {0};
23561   wuffs_base__slice_u8 v_dst = {0};
23562   uint64_t v_i = 0;
23563   uint64_t v_n = 0;
23564 
23565   const uint8_t* iop_a_src = NULL;
23566   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23567   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23568   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23569   if (a_src) {
23570     io0_a_src = a_src->data.ptr;
23571     io1_a_src = io0_a_src + a_src->meta.ri;
23572     iop_a_src = io1_a_src;
23573     io2_a_src = io0_a_src + a_src->meta.wi;
23574   }
23575 
23576   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23577   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23578   if ((v_dst_bits_per_pixel & 7) != 0) {
23579     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23580     goto exit;
23581   }
23582   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23583   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23584   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23585   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23586   label__outer__continue:;
23587   while (true) {
23588     while (self->private_impl.f_pending_pad > 0) {
23589       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23590         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23591         goto ok;
23592       }
23593       self->private_impl.f_pending_pad -= 1;
23594       iop_a_src += 1;
23595     }
23596     label__inner__continue:;
23597     while (true) {
23598       if (self->private_impl.f_dst_x == self->private_impl.f_width) {
23599         self->private_impl.f_dst_x = 0;
23600         self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23601         if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23602           if (self->private_impl.f_height > 0) {
23603             self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23604           }
23605           goto label__outer__break;
23606         } else if (self->private_impl.f_pad_per_row != 0) {
23607           self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23608           goto label__outer__continue;
23609         }
23610       }
23611       v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23612       if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
23613         v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
23614       }
23615       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23616       if (v_i >= ((uint64_t)(v_dst.len))) {
23617         goto label__inner__continue;
23618       }
23619       v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
23620           &self->private_impl.f_swizzler,
23621           wuffs_base__slice_u8__subslice_i(v_dst, v_i),
23622           v_dst_palette,
23623           &iop_a_src,
23624           io2_a_src);
23625       if (v_n == 0) {
23626         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23627         goto ok;
23628       }
23629       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23630     }
23631   }
23632   label__outer__break:;
23633   status = wuffs_base__make_status(NULL);
23634   goto ok;
23635 
23636   ok:
23637   goto exit;
23638   exit:
23639   if (a_src) {
23640     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23641   }
23642 
23643   return status;
23644 }
23645 
23646 // -------- func bmp.decoder.swizzle_rle
23647 
23648 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)23649 wuffs_bmp__decoder__swizzle_rle(
23650     wuffs_bmp__decoder* self,
23651     wuffs_base__pixel_buffer* a_dst,
23652     wuffs_base__io_buffer* a_src) {
23653   wuffs_base__status status = wuffs_base__make_status(NULL);
23654 
23655   wuffs_base__pixel_format v_dst_pixfmt = {0};
23656   uint32_t v_dst_bits_per_pixel = 0;
23657   uint64_t v_dst_bytes_per_pixel = 0;
23658   uint64_t v_dst_bytes_per_row = 0;
23659   wuffs_base__slice_u8 v_dst_palette = {0};
23660   wuffs_base__table_u8 v_tab = {0};
23661   wuffs_base__slice_u8 v_row = {0};
23662   wuffs_base__slice_u8 v_dst = {0};
23663   uint64_t v_i = 0;
23664   uint64_t v_n = 0;
23665   uint32_t v_p0 = 0;
23666   uint8_t v_code = 0;
23667   uint8_t v_indexes[2] = {0};
23668   uint32_t v_rle_state = 0;
23669   uint32_t v_chunk_bits = 0;
23670   uint32_t v_chunk_count = 0;
23671 
23672   const uint8_t* iop_a_src = NULL;
23673   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23674   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23675   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23676   if (a_src) {
23677     io0_a_src = a_src->data.ptr;
23678     io1_a_src = io0_a_src + a_src->meta.ri;
23679     iop_a_src = io1_a_src;
23680     io2_a_src = io0_a_src + a_src->meta.wi;
23681   }
23682 
23683   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23684   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23685   if ((v_dst_bits_per_pixel & 7) != 0) {
23686     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23687     goto exit;
23688   }
23689   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23690   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23691   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23692   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23693   v_rle_state = self->private_impl.f_rle_state;
23694   label__outer__continue:;
23695   while (true) {
23696     v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23697     if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23698       v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23699     }
23700     label__middle__continue:;
23701     while (true) {
23702       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23703       if (v_i <= ((uint64_t)(v_row.len))) {
23704         v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i);
23705       } else {
23706         v_dst = wuffs_base__utility__empty_slice_u8();
23707       }
23708       while (true) {
23709         label__inner__continue:;
23710         while (true) {
23711           if (v_rle_state == 0) {
23712             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23713               goto label__goto_suspend__break;
23714             }
23715             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23716             iop_a_src += 1;
23717             if (v_code == 0) {
23718               v_rle_state = 2;
23719               goto label__inner__continue;
23720             }
23721             self->private_impl.f_rle_length = ((uint32_t)(v_code));
23722             v_rle_state = 1;
23723             goto label__inner__continue;
23724           } else if (v_rle_state == 1) {
23725             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23726               goto label__goto_suspend__break;
23727             }
23728             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23729             iop_a_src += 1;
23730             if (self->private_impl.f_bits_per_pixel == 8) {
23731               v_p0 = 0;
23732               while (v_p0 < self->private_impl.f_rle_length) {
23733                 self->private_data.f_scratch[v_p0] = v_code;
23734                 v_p0 += 1;
23735               }
23736             } else {
23737               v_indexes[0] = ((uint8_t)((v_code >> 4)));
23738               v_indexes[1] = (v_code & 15);
23739               v_p0 = 0;
23740               while (v_p0 < self->private_impl.f_rle_length) {
23741                 self->private_data.f_scratch[(v_p0 + 0)] = v_indexes[0];
23742                 self->private_data.f_scratch[(v_p0 + 1)] = v_indexes[1];
23743                 v_p0 += 2;
23744               }
23745             }
23746             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));
23747             wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length);
23748             v_rle_state = 0;
23749             goto label__middle__continue;
23750           } else if (v_rle_state == 2) {
23751             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23752               goto label__goto_suspend__break;
23753             }
23754             v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23755             iop_a_src += 1;
23756             if (v_code < 2) {
23757               if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0)) {
23758                 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23759                 goto exit;
23760               }
23761               wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u);
23762               self->private_impl.f_dst_x = 0;
23763               self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23764               if (v_code > 0) {
23765                 goto label__outer__break;
23766               }
23767               v_rle_state = 0;
23768               goto label__outer__continue;
23769             } else if (v_code == 2) {
23770               v_rle_state = 4;
23771               goto label__inner__continue;
23772             }
23773             self->private_impl.f_rle_length = ((uint32_t)(v_code));
23774             self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8) && ((v_code & 1) != 0));
23775             v_rle_state = 3;
23776             goto label__inner__continue;
23777           } else if (v_rle_state == 3) {
23778             if (self->private_impl.f_bits_per_pixel == 8) {
23779               v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
23780                   &self->private_impl.f_swizzler,
23781                   self->private_impl.f_rle_length,
23782                   v_dst,
23783                   v_dst_palette,
23784                   &iop_a_src,
23785                   io2_a_src);
23786               wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23787               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)((v_n & 4294967295))));
23788             } else {
23789               v_chunk_count = ((self->private_impl.f_rle_length + 3) / 4);
23790               v_p0 = 0;
23791               while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2)) {
23792                 v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
23793                 iop_a_src += 2;
23794                 self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((15 & (v_chunk_bits >> 12))));
23795                 self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((15 & (v_chunk_bits >> 8))));
23796                 self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((15 & (v_chunk_bits >> 4))));
23797                 self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((15 & (v_chunk_bits >> 0))));
23798                 v_p0 = ((v_p0 & 255) + 4);
23799                 v_chunk_count -= 1;
23800               }
23801               v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length);
23802               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));
23803               wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0);
23804               wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0);
23805             }
23806             if (self->private_impl.f_rle_length > 0) {
23807               goto label__goto_suspend__break;
23808             }
23809             if (self->private_impl.f_rle_padded) {
23810               if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23811                 goto label__goto_suspend__break;
23812               }
23813               iop_a_src += 1;
23814               self->private_impl.f_rle_padded = false;
23815             }
23816             v_rle_state = 0;
23817             goto label__middle__continue;
23818           } else if (v_rle_state == 4) {
23819             if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23820               goto label__goto_suspend__break;
23821             }
23822             self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23823             iop_a_src += 1;
23824             v_rle_state = 5;
23825             goto label__inner__continue;
23826           }
23827           if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23828             goto label__goto_suspend__break;
23829           }
23830           v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23831           iop_a_src += 1;
23832           if (self->private_impl.f_rle_delta_x > 0) {
23833             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)));
23834             wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x)));
23835             self->private_impl.f_rle_delta_x = 0;
23836             if (self->private_impl.f_dst_x > self->private_impl.f_width) {
23837               status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23838               goto exit;
23839             }
23840           }
23841           if (v_code > 0) {
23842 #if defined(__GNUC__)
23843 #pragma GCC diagnostic push
23844 #pragma GCC diagnostic ignored "-Wconversion"
23845 #endif
23846             v_code -= 1;
23847 #if defined(__GNUC__)
23848 #pragma GCC diagnostic pop
23849 #endif
23850             while (true) {
23851               self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23852               if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23853                 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23854                 goto exit;
23855               }
23856               v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23857               if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23858                 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23859               }
23860               if (v_code <= 0) {
23861                 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)));
23862                 goto label__0__break;
23863               }
23864               wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
23865 #if defined(__GNUC__)
23866 #pragma GCC diagnostic push
23867 #pragma GCC diagnostic ignored "-Wconversion"
23868 #endif
23869               v_code -= 1;
23870 #if defined(__GNUC__)
23871 #pragma GCC diagnostic pop
23872 #endif
23873             }
23874             label__0__break:;
23875           }
23876           v_rle_state = 0;
23877           goto label__middle__continue;
23878         }
23879       }
23880       label__goto_suspend__break:;
23881       self->private_impl.f_rle_state = v_rle_state;
23882       status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23883       goto ok;
23884     }
23885   }
23886   label__outer__break:;
23887   while (self->private_impl.f_dst_y < self->private_impl.f_height) {
23888     v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23889     if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23890       v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23891     }
23892     wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
23893     self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23894   }
23895   status = wuffs_base__make_status(NULL);
23896   goto ok;
23897 
23898   ok:
23899   goto exit;
23900   exit:
23901   if (a_src) {
23902     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23903   }
23904 
23905   return status;
23906 }
23907 
23908 // -------- func bmp.decoder.swizzle_bitfields
23909 
23910 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)23911 wuffs_bmp__decoder__swizzle_bitfields(
23912     wuffs_bmp__decoder* self,
23913     wuffs_base__pixel_buffer* a_dst,
23914     wuffs_base__io_buffer* a_src) {
23915   wuffs_base__status status = wuffs_base__make_status(NULL);
23916 
23917   wuffs_base__pixel_format v_dst_pixfmt = {0};
23918   uint32_t v_dst_bits_per_pixel = 0;
23919   uint64_t v_dst_bytes_per_pixel = 0;
23920   uint64_t v_dst_bytes_per_row = 0;
23921   wuffs_base__slice_u8 v_dst_palette = {0};
23922   wuffs_base__table_u8 v_tab = {0};
23923   wuffs_base__slice_u8 v_dst = {0};
23924   uint64_t v_i = 0;
23925   uint64_t v_n = 0;
23926   uint32_t v_p0 = 0;
23927   uint32_t v_p1 = 0;
23928   uint32_t v_p1_temp = 0;
23929   uint32_t v_num_bits = 0;
23930   uint32_t v_c = 0;
23931   uint32_t v_c32 = 0;
23932   uint32_t v_channel = 0;
23933 
23934   const uint8_t* iop_a_src = NULL;
23935   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23936   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23937   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23938   if (a_src) {
23939     io0_a_src = a_src->data.ptr;
23940     io1_a_src = io0_a_src + a_src->meta.ri;
23941     iop_a_src = io1_a_src;
23942     io2_a_src = io0_a_src + a_src->meta.wi;
23943   }
23944 
23945   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23946   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23947   if ((v_dst_bits_per_pixel & 7) != 0) {
23948     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23949     goto exit;
23950   }
23951   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23952   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23953   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23954   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23955   label__outer__continue:;
23956   while (true) {
23957     while (self->private_impl.f_pending_pad > 0) {
23958       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23959         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23960         goto ok;
23961       }
23962       self->private_impl.f_pending_pad -= 1;
23963       iop_a_src += 1;
23964     }
23965     label__inner__continue:;
23966     while (true) {
23967       if (self->private_impl.f_dst_x == self->private_impl.f_width) {
23968         self->private_impl.f_dst_x = 0;
23969         self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23970         if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23971           if (self->private_impl.f_height > 0) {
23972             self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23973           }
23974           goto label__outer__break;
23975         } else if (self->private_impl.f_pad_per_row != 0) {
23976           self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23977           goto label__outer__continue;
23978         }
23979       }
23980       v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x));
23981       v_p1 = wuffs_base__u32__min(v_p1_temp, 256);
23982       v_p0 = 0;
23983       while (v_p0 < v_p1) {
23984         if (self->private_impl.f_bits_per_pixel == 16) {
23985           if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
23986             goto label__0__break;
23987           }
23988           v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
23989           iop_a_src += 2;
23990         } else {
23991           if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
23992             goto label__0__break;
23993           }
23994           v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23995           iop_a_src += 4;
23996         }
23997         v_channel = 0;
23998         while (v_channel < 4) {
23999           if (self->private_impl.f_channel_num_bits[v_channel] == 0) {
24000             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 0)] = 255;
24001             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 1)] = 255;
24002           } else {
24003             v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]);
24004             v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel]));
24005             while (v_num_bits < 16) {
24006               v_c |= ((uint32_t)(v_c << v_num_bits));
24007               v_num_bits *= 2;
24008             }
24009             v_c >>= (v_num_bits - 16);
24010             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 0)] = ((uint8_t)((255 & (v_c >> 0))));
24011             self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 1)] = ((uint8_t)((255 & (v_c >> 8))));
24012           }
24013           v_channel += 1;
24014         }
24015         v_p0 += 1;
24016       }
24017       label__0__break:;
24018       v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
24019       if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
24020         v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
24021       }
24022       v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
24023       if (v_i >= ((uint64_t)(v_dst.len))) {
24024         goto label__inner__continue;
24025       }
24026       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)));
24027       if (v_n == 0) {
24028         status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
24029         goto ok;
24030       }
24031       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
24032     }
24033   }
24034   label__outer__break:;
24035   status = wuffs_base__make_status(NULL);
24036   goto ok;
24037 
24038   ok:
24039   goto exit;
24040   exit:
24041   if (a_src) {
24042     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24043   }
24044 
24045   return status;
24046 }
24047 
24048 // -------- func bmp.decoder.swizzle_low_bit_depth
24049 
24050 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)24051 wuffs_bmp__decoder__swizzle_low_bit_depth(
24052     wuffs_bmp__decoder* self,
24053     wuffs_base__pixel_buffer* a_dst,
24054     wuffs_base__io_buffer* a_src) {
24055   wuffs_base__status status = wuffs_base__make_status(NULL);
24056 
24057   wuffs_base__pixel_format v_dst_pixfmt = {0};
24058   uint32_t v_dst_bits_per_pixel = 0;
24059   uint64_t v_dst_bytes_per_pixel = 0;
24060   uint64_t v_dst_bytes_per_row = 0;
24061   wuffs_base__slice_u8 v_dst_palette = {0};
24062   wuffs_base__table_u8 v_tab = {0};
24063   wuffs_base__slice_u8 v_dst = {0};
24064   uint64_t v_i = 0;
24065   uint64_t v_n = 0;
24066   uint32_t v_p0 = 0;
24067   uint32_t v_chunk_bits = 0;
24068   uint32_t v_chunk_count = 0;
24069 
24070   const uint8_t* iop_a_src = NULL;
24071   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24072   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24073   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24074   if (a_src) {
24075     io0_a_src = a_src->data.ptr;
24076     io1_a_src = io0_a_src + a_src->meta.ri;
24077     iop_a_src = io1_a_src;
24078     io2_a_src = io0_a_src + a_src->meta.wi;
24079   }
24080 
24081   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
24082   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
24083   if ((v_dst_bits_per_pixel & 7) != 0) {
24084     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
24085     goto exit;
24086   }
24087   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
24088   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
24089   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
24090   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
24091   label__loop__continue:;
24092   while (true) {
24093     if (self->private_impl.f_dst_x == self->private_impl.f_width) {
24094       self->private_impl.f_dst_x = 0;
24095       self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
24096       if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
24097         goto label__loop__break;
24098       }
24099     }
24100     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
24101     if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
24102       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
24103     }
24104     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
24105     if (v_i >= ((uint64_t)(v_dst.len))) {
24106       goto label__loop__continue;
24107     }
24108     v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
24109     v_p0 = 0;
24110     if (self->private_impl.f_bits_per_pixel == 1) {
24111       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31) / 32);
24112       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16);
24113       while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
24114         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
24115         iop_a_src += 4;
24116         self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((1 & (v_chunk_bits >> 31))));
24117         self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((1 & (v_chunk_bits >> 30))));
24118         self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((1 & (v_chunk_bits >> 29))));
24119         self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((1 & (v_chunk_bits >> 28))));
24120         self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((1 & (v_chunk_bits >> 27))));
24121         self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((1 & (v_chunk_bits >> 26))));
24122         self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((1 & (v_chunk_bits >> 25))));
24123         self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((1 & (v_chunk_bits >> 24))));
24124         self->private_data.f_scratch[(v_p0 + 8)] = ((uint8_t)((1 & (v_chunk_bits >> 23))));
24125         self->private_data.f_scratch[(v_p0 + 9)] = ((uint8_t)((1 & (v_chunk_bits >> 22))));
24126         self->private_data.f_scratch[(v_p0 + 10)] = ((uint8_t)((1 & (v_chunk_bits >> 21))));
24127         self->private_data.f_scratch[(v_p0 + 11)] = ((uint8_t)((1 & (v_chunk_bits >> 20))));
24128         self->private_data.f_scratch[(v_p0 + 12)] = ((uint8_t)((1 & (v_chunk_bits >> 19))));
24129         self->private_data.f_scratch[(v_p0 + 13)] = ((uint8_t)((1 & (v_chunk_bits >> 18))));
24130         self->private_data.f_scratch[(v_p0 + 14)] = ((uint8_t)((1 & (v_chunk_bits >> 17))));
24131         self->private_data.f_scratch[(v_p0 + 15)] = ((uint8_t)((1 & (v_chunk_bits >> 16))));
24132         self->private_data.f_scratch[(v_p0 + 16)] = ((uint8_t)((1 & (v_chunk_bits >> 15))));
24133         self->private_data.f_scratch[(v_p0 + 17)] = ((uint8_t)((1 & (v_chunk_bits >> 14))));
24134         self->private_data.f_scratch[(v_p0 + 18)] = ((uint8_t)((1 & (v_chunk_bits >> 13))));
24135         self->private_data.f_scratch[(v_p0 + 19)] = ((uint8_t)((1 & (v_chunk_bits >> 12))));
24136         self->private_data.f_scratch[(v_p0 + 20)] = ((uint8_t)((1 & (v_chunk_bits >> 11))));
24137         self->private_data.f_scratch[(v_p0 + 21)] = ((uint8_t)((1 & (v_chunk_bits >> 10))));
24138         self->private_data.f_scratch[(v_p0 + 22)] = ((uint8_t)((1 & (v_chunk_bits >> 9))));
24139         self->private_data.f_scratch[(v_p0 + 23)] = ((uint8_t)((1 & (v_chunk_bits >> 8))));
24140         self->private_data.f_scratch[(v_p0 + 24)] = ((uint8_t)((1 & (v_chunk_bits >> 7))));
24141         self->private_data.f_scratch[(v_p0 + 25)] = ((uint8_t)((1 & (v_chunk_bits >> 6))));
24142         self->private_data.f_scratch[(v_p0 + 26)] = ((uint8_t)((1 & (v_chunk_bits >> 5))));
24143         self->private_data.f_scratch[(v_p0 + 27)] = ((uint8_t)((1 & (v_chunk_bits >> 4))));
24144         self->private_data.f_scratch[(v_p0 + 28)] = ((uint8_t)((1 & (v_chunk_bits >> 3))));
24145         self->private_data.f_scratch[(v_p0 + 29)] = ((uint8_t)((1 & (v_chunk_bits >> 2))));
24146         self->private_data.f_scratch[(v_p0 + 30)] = ((uint8_t)((1 & (v_chunk_bits >> 1))));
24147         self->private_data.f_scratch[(v_p0 + 31)] = ((uint8_t)((1 & (v_chunk_bits >> 0))));
24148         v_p0 = ((v_p0 & 511) + 32);
24149         v_chunk_count -= 1;
24150       }
24151     } else if (self->private_impl.f_bits_per_pixel == 2) {
24152       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15) / 16);
24153       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32);
24154       while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
24155         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
24156         iop_a_src += 4;
24157         self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((3 & (v_chunk_bits >> 30))));
24158         self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((3 & (v_chunk_bits >> 28))));
24159         self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((3 & (v_chunk_bits >> 26))));
24160         self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((3 & (v_chunk_bits >> 24))));
24161         self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((3 & (v_chunk_bits >> 22))));
24162         self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((3 & (v_chunk_bits >> 20))));
24163         self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((3 & (v_chunk_bits >> 18))));
24164         self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((3 & (v_chunk_bits >> 16))));
24165         self->private_data.f_scratch[(v_p0 + 8)] = ((uint8_t)((3 & (v_chunk_bits >> 14))));
24166         self->private_data.f_scratch[(v_p0 + 9)] = ((uint8_t)((3 & (v_chunk_bits >> 12))));
24167         self->private_data.f_scratch[(v_p0 + 10)] = ((uint8_t)((3 & (v_chunk_bits >> 10))));
24168         self->private_data.f_scratch[(v_p0 + 11)] = ((uint8_t)((3 & (v_chunk_bits >> 8))));
24169         self->private_data.f_scratch[(v_p0 + 12)] = ((uint8_t)((3 & (v_chunk_bits >> 6))));
24170         self->private_data.f_scratch[(v_p0 + 13)] = ((uint8_t)((3 & (v_chunk_bits >> 4))));
24171         self->private_data.f_scratch[(v_p0 + 14)] = ((uint8_t)((3 & (v_chunk_bits >> 2))));
24172         self->private_data.f_scratch[(v_p0 + 15)] = ((uint8_t)((3 & (v_chunk_bits >> 0))));
24173         v_p0 = ((v_p0 & 511) + 16);
24174         v_chunk_count -= 1;
24175       }
24176     } else if (self->private_impl.f_bits_per_pixel == 4) {
24177       v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7) / 8);
24178       v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64);
24179       while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
24180         v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
24181         iop_a_src += 4;
24182         self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((15 & (v_chunk_bits >> 28))));
24183         self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((15 & (v_chunk_bits >> 24))));
24184         self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((15 & (v_chunk_bits >> 20))));
24185         self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((15 & (v_chunk_bits >> 16))));
24186         self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((15 & (v_chunk_bits >> 12))));
24187         self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((15 & (v_chunk_bits >> 8))));
24188         self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((15 & (v_chunk_bits >> 4))));
24189         self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((15 & (v_chunk_bits >> 0))));
24190         v_p0 = ((v_p0 & 511) + 8);
24191         v_chunk_count -= 1;
24192       }
24193     }
24194     v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x));
24195     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));
24196     if (v_n == 0) {
24197       status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
24198       goto ok;
24199     }
24200     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
24201   }
24202   label__loop__break:;
24203   status = wuffs_base__make_status(NULL);
24204   goto ok;
24205 
24206   ok:
24207   goto exit;
24208   exit:
24209   if (a_src) {
24210     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24211   }
24212 
24213   return status;
24214 }
24215 
24216 // -------- func bmp.decoder.frame_dirty_rect
24217 
24218 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_bmp__decoder__frame_dirty_rect(const wuffs_bmp__decoder * self)24219 wuffs_bmp__decoder__frame_dirty_rect(
24220     const wuffs_bmp__decoder* self) {
24221   if (!self) {
24222     return wuffs_base__utility__empty_rect_ie_u32();
24223   }
24224   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24225       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24226     return wuffs_base__utility__empty_rect_ie_u32();
24227   }
24228 
24229   return wuffs_base__utility__make_rect_ie_u32(
24230       0,
24231       0,
24232       self->private_impl.f_width,
24233       self->private_impl.f_height);
24234 }
24235 
24236 // -------- func bmp.decoder.num_animation_loops
24237 
24238 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_bmp__decoder__num_animation_loops(const wuffs_bmp__decoder * self)24239 wuffs_bmp__decoder__num_animation_loops(
24240     const wuffs_bmp__decoder* self) {
24241   if (!self) {
24242     return 0;
24243   }
24244   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24245       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24246     return 0;
24247   }
24248 
24249   return 0;
24250 }
24251 
24252 // -------- func bmp.decoder.num_decoded_frame_configs
24253 
24254 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frame_configs(const wuffs_bmp__decoder * self)24255 wuffs_bmp__decoder__num_decoded_frame_configs(
24256     const wuffs_bmp__decoder* self) {
24257   if (!self) {
24258     return 0;
24259   }
24260   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24261       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24262     return 0;
24263   }
24264 
24265   if (self->private_impl.f_call_sequence > 3) {
24266     return 1;
24267   }
24268   return 0;
24269 }
24270 
24271 // -------- func bmp.decoder.num_decoded_frames
24272 
24273 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frames(const wuffs_bmp__decoder * self)24274 wuffs_bmp__decoder__num_decoded_frames(
24275     const wuffs_bmp__decoder* self) {
24276   if (!self) {
24277     return 0;
24278   }
24279   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24280       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24281     return 0;
24282   }
24283 
24284   if (self->private_impl.f_call_sequence > 4) {
24285     return 1;
24286   }
24287   return 0;
24288 }
24289 
24290 // -------- func bmp.decoder.restart_frame
24291 
24292 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)24293 wuffs_bmp__decoder__restart_frame(
24294     wuffs_bmp__decoder* self,
24295     uint64_t a_index,
24296     uint64_t a_io_position) {
24297   if (!self) {
24298     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24299   }
24300   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24301     return wuffs_base__make_status(
24302         (self->private_impl.magic == WUFFS_BASE__DISABLED)
24303         ? wuffs_base__error__disabled_by_previous_error
24304         : wuffs_base__error__initialize_not_called);
24305   }
24306 
24307   if (self->private_impl.f_call_sequence < 3) {
24308     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
24309   }
24310   if (a_index != 0) {
24311     return wuffs_base__make_status(wuffs_base__error__bad_argument);
24312   }
24313   self->private_impl.f_call_sequence = 3;
24314   self->private_impl.f_frame_config_io_position = a_io_position;
24315   return wuffs_base__make_status(NULL);
24316 }
24317 
24318 // -------- func bmp.decoder.set_report_metadata
24319 
24320 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)24321 wuffs_bmp__decoder__set_report_metadata(
24322     wuffs_bmp__decoder* self,
24323     uint32_t a_fourcc,
24324     bool a_report) {
24325   return wuffs_base__make_empty_struct();
24326 }
24327 
24328 // -------- func bmp.decoder.tell_me_more
24329 
24330 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)24331 wuffs_bmp__decoder__tell_me_more(
24332     wuffs_bmp__decoder* self,
24333     wuffs_base__io_buffer* a_dst,
24334     wuffs_base__more_information* a_minfo,
24335     wuffs_base__io_buffer* a_src) {
24336   if (!self) {
24337     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24338   }
24339   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24340     return wuffs_base__make_status(
24341         (self->private_impl.magic == WUFFS_BASE__DISABLED)
24342         ? wuffs_base__error__disabled_by_previous_error
24343         : wuffs_base__error__initialize_not_called);
24344   }
24345   if (!a_dst || !a_src) {
24346     self->private_impl.magic = WUFFS_BASE__DISABLED;
24347     return wuffs_base__make_status(wuffs_base__error__bad_argument);
24348   }
24349   if ((self->private_impl.active_coroutine != 0) &&
24350       (self->private_impl.active_coroutine != 4)) {
24351     self->private_impl.magic = WUFFS_BASE__DISABLED;
24352     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24353   }
24354   self->private_impl.active_coroutine = 0;
24355   wuffs_base__status status = wuffs_base__make_status(NULL);
24356 
24357   if (self->private_impl.f_io_redirect_fourcc <= 1) {
24358     status = wuffs_base__make_status(wuffs_base__error__no_more_information);
24359     goto exit;
24360   }
24361   if (a_minfo != NULL) {
24362     wuffs_base__more_information__set(a_minfo,
24363         1,
24364         self->private_impl.f_io_redirect_fourcc,
24365         0,
24366         self->private_impl.f_io_redirect_pos,
24367         18446744073709551615u);
24368   }
24369   self->private_impl.f_io_redirect_fourcc = 1;
24370 
24371   goto ok;
24372   ok:
24373   goto exit;
24374   exit:
24375   if (wuffs_base__status__is_error(&status)) {
24376     self->private_impl.magic = WUFFS_BASE__DISABLED;
24377   }
24378   return status;
24379 }
24380 
24381 // -------- func bmp.decoder.workbuf_len
24382 
24383 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_bmp__decoder__workbuf_len(const wuffs_bmp__decoder * self)24384 wuffs_bmp__decoder__workbuf_len(
24385     const wuffs_bmp__decoder* self) {
24386   if (!self) {
24387     return wuffs_base__utility__empty_range_ii_u64();
24388   }
24389   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24390       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24391     return wuffs_base__utility__empty_range_ii_u64();
24392   }
24393 
24394   return wuffs_base__utility__make_range_ii_u64(0, 0);
24395 }
24396 
24397 // -------- func bmp.decoder.read_palette
24398 
24399 static wuffs_base__status
wuffs_bmp__decoder__read_palette(wuffs_bmp__decoder * self,wuffs_base__io_buffer * a_src)24400 wuffs_bmp__decoder__read_palette(
24401     wuffs_bmp__decoder* self,
24402     wuffs_base__io_buffer* a_src) {
24403   wuffs_base__status status = wuffs_base__make_status(NULL);
24404 
24405   uint32_t v_i = 0;
24406   uint32_t v_argb = 0;
24407 
24408   const uint8_t* iop_a_src = NULL;
24409   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24410   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24411   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24412   if (a_src) {
24413     io0_a_src = a_src->data.ptr;
24414     io1_a_src = io0_a_src + a_src->meta.ri;
24415     iop_a_src = io1_a_src;
24416     io2_a_src = io0_a_src + a_src->meta.wi;
24417   }
24418 
24419   uint32_t coro_susp_point = self->private_impl.p_read_palette[0];
24420   if (coro_susp_point) {
24421     v_i = self->private_data.s_read_palette[0].v_i;
24422   }
24423   switch (coro_susp_point) {
24424     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24425 
24426     if (self->private_impl.f_bitmap_info_len == 12) {
24427       while ((v_i < 256) && (self->private_impl.f_padding >= 3)) {
24428         self->private_impl.f_padding -= 3;
24429         {
24430           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
24431           uint32_t t_0;
24432           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
24433             t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
24434             iop_a_src += 3;
24435           } else {
24436             self->private_data.s_read_palette[0].scratch = 0;
24437             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
24438             while (true) {
24439               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24440                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24441                 goto suspend;
24442               }
24443               uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
24444               uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
24445               *scratch <<= 8;
24446               *scratch >>= 8;
24447               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
24448               if (num_bits_0 == 16) {
24449                 t_0 = ((uint32_t)(*scratch));
24450                 break;
24451               }
24452               num_bits_0 += 8;
24453               *scratch |= ((uint64_t)(num_bits_0)) << 56;
24454             }
24455           }
24456           v_argb = t_0;
24457         }
24458         v_argb |= 4278190080;
24459         self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
24460         self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
24461         self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
24462         self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
24463         v_i += 1;
24464       }
24465     } else {
24466       while ((v_i < 256) && (self->private_impl.f_padding >= 4)) {
24467         self->private_impl.f_padding -= 4;
24468         {
24469           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
24470           uint32_t t_1;
24471           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
24472             t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
24473             iop_a_src += 4;
24474           } else {
24475             self->private_data.s_read_palette[0].scratch = 0;
24476             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
24477             while (true) {
24478               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24479                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24480                 goto suspend;
24481               }
24482               uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
24483               uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
24484               *scratch <<= 8;
24485               *scratch >>= 8;
24486               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
24487               if (num_bits_1 == 24) {
24488                 t_1 = ((uint32_t)(*scratch));
24489                 break;
24490               }
24491               num_bits_1 += 8;
24492               *scratch |= ((uint64_t)(num_bits_1)) << 56;
24493             }
24494           }
24495           v_argb = t_1;
24496         }
24497         v_argb |= 4278190080;
24498         self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
24499         self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
24500         self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
24501         self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
24502         v_i += 1;
24503       }
24504     }
24505     while (v_i < 256) {
24506       self->private_data.f_src_palette[((4 * v_i) + 0)] = 0;
24507       self->private_data.f_src_palette[((4 * v_i) + 1)] = 0;
24508       self->private_data.f_src_palette[((4 * v_i) + 2)] = 0;
24509       self->private_data.f_src_palette[((4 * v_i) + 3)] = 255;
24510       v_i += 1;
24511     }
24512 
24513     goto ok;
24514     ok:
24515     self->private_impl.p_read_palette[0] = 0;
24516     goto exit;
24517   }
24518 
24519   goto suspend;
24520   suspend:
24521   self->private_impl.p_read_palette[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
24522   self->private_data.s_read_palette[0].v_i = v_i;
24523 
24524   goto exit;
24525   exit:
24526   if (a_src) {
24527     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24528   }
24529 
24530   return status;
24531 }
24532 
24533 // -------- func bmp.decoder.process_masks
24534 
24535 static wuffs_base__status
wuffs_bmp__decoder__process_masks(wuffs_bmp__decoder * self)24536 wuffs_bmp__decoder__process_masks(
24537     wuffs_bmp__decoder* self) {
24538   wuffs_base__status status = wuffs_base__make_status(NULL);
24539 
24540   uint32_t v_i = 0;
24541   uint32_t v_mask = 0;
24542   uint32_t v_n = 0;
24543 
24544   while (v_i < 4) {
24545     v_mask = self->private_impl.f_channel_masks[v_i];
24546     if (v_mask != 0) {
24547       v_n = 0;
24548       while ((v_mask & 1) == 0) {
24549         v_n += 1;
24550         v_mask >>= 1;
24551       }
24552       self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31)));
24553       v_n = 0;
24554       while ((v_mask & 1) == 1) {
24555         v_n += 1;
24556         v_mask >>= 1;
24557       }
24558       if ((v_mask != 0) || (v_n > 32)) {
24559         status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
24560         goto exit;
24561       }
24562       self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n));
24563     } else if (v_i != 3) {
24564       status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
24565       goto exit;
24566     }
24567     v_i += 1;
24568   }
24569 
24570   goto ok;
24571   ok:
24572   goto exit;
24573   exit:
24574   return status;
24575 }
24576 
24577 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
24578 
24579 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
24580 
24581 // ---------------- Status Codes Implementations
24582 
24583 const char wuffs_cbor__error__bad_input[] = "#cbor: bad input";
24584 const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth";
24585 const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O";
24586 const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length";
24587 
24588 // ---------------- Private Consts
24589 
24590 static const uint32_t
24591 WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
24592   8388612, 8388616, 8388610, 8388609,
24593 };
24594 
24595 static const uint8_t
24596 WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
24597   1, 1, 1, 1, 1, 1, 1, 1,
24598   1, 1, 1, 1, 1, 1, 1, 1,
24599   1, 1, 1, 1, 1, 1, 1, 1,
24600   2, 3, 5, 9, 0, 0, 0, 1,
24601 };
24602 
24603 // ---------------- Private Initializer Prototypes
24604 
24605 // ---------------- Private Function Prototypes
24606 
24607 // ---------------- VTables
24608 
24609 const wuffs_base__token_decoder__func_ptrs
24610 wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = {
24611   (wuffs_base__status(*)(void*,
24612       wuffs_base__token_buffer*,
24613       wuffs_base__io_buffer*,
24614       wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens),
24615   (wuffs_base__empty_struct(*)(void*,
24616       uint32_t,
24617       bool))(&wuffs_cbor__decoder__set_quirk_enabled),
24618   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len),
24619 };
24620 
24621 // ---------------- Initializer Implementations
24622 
24623 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)24624 wuffs_cbor__decoder__initialize(
24625     wuffs_cbor__decoder* self,
24626     size_t sizeof_star_self,
24627     uint64_t wuffs_version,
24628     uint32_t options){
24629   if (!self) {
24630     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24631   }
24632   if (sizeof(*self) != sizeof_star_self) {
24633     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
24634   }
24635   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
24636       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
24637     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
24638   }
24639 
24640   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
24641     // The whole point of this if-check is to detect an uninitialized *self.
24642     // We disable the warning on GCC. Clang-5.0 does not have this warning.
24643 #if !defined(__clang__) && defined(__GNUC__)
24644 #pragma GCC diagnostic push
24645 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
24646 #endif
24647     if (self->private_impl.magic != 0) {
24648       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
24649     }
24650 #if !defined(__clang__) && defined(__GNUC__)
24651 #pragma GCC diagnostic pop
24652 #endif
24653   } else {
24654     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
24655       memset(self, 0, sizeof(*self));
24656       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
24657     } else {
24658       memset(&(self->private_impl), 0, sizeof(self->private_impl));
24659     }
24660   }
24661 
24662   self->private_impl.magic = WUFFS_BASE__MAGIC;
24663   self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
24664       wuffs_base__token_decoder__vtable_name;
24665   self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
24666       (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder);
24667   return wuffs_base__make_status(NULL);
24668 }
24669 
24670 wuffs_cbor__decoder*
wuffs_cbor__decoder__alloc()24671 wuffs_cbor__decoder__alloc() {
24672   wuffs_cbor__decoder* x =
24673       (wuffs_cbor__decoder*)(calloc(sizeof(wuffs_cbor__decoder), 1));
24674   if (!x) {
24675     return NULL;
24676   }
24677   if (wuffs_cbor__decoder__initialize(
24678       x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
24679     free(x);
24680     return NULL;
24681   }
24682   return x;
24683 }
24684 
24685 size_t
sizeof__wuffs_cbor__decoder()24686 sizeof__wuffs_cbor__decoder() {
24687   return sizeof(wuffs_cbor__decoder);
24688 }
24689 
24690 // ---------------- Function Implementations
24691 
24692 // -------- func cbor.decoder.set_quirk_enabled
24693 
24694 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)24695 wuffs_cbor__decoder__set_quirk_enabled(
24696     wuffs_cbor__decoder* self,
24697     uint32_t a_quirk,
24698     bool a_enabled) {
24699   return wuffs_base__make_empty_struct();
24700 }
24701 
24702 // -------- func cbor.decoder.workbuf_len
24703 
24704 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_cbor__decoder__workbuf_len(const wuffs_cbor__decoder * self)24705 wuffs_cbor__decoder__workbuf_len(
24706     const wuffs_cbor__decoder* self) {
24707   if (!self) {
24708     return wuffs_base__utility__empty_range_ii_u64();
24709   }
24710   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24711       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24712     return wuffs_base__utility__empty_range_ii_u64();
24713   }
24714 
24715   return wuffs_base__utility__empty_range_ii_u64();
24716 }
24717 
24718 // -------- func cbor.decoder.decode_tokens
24719 
24720 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)24721 wuffs_cbor__decoder__decode_tokens(
24722     wuffs_cbor__decoder* self,
24723     wuffs_base__token_buffer* a_dst,
24724     wuffs_base__io_buffer* a_src,
24725     wuffs_base__slice_u8 a_workbuf) {
24726   if (!self) {
24727     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24728   }
24729   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24730     return wuffs_base__make_status(
24731         (self->private_impl.magic == WUFFS_BASE__DISABLED)
24732         ? wuffs_base__error__disabled_by_previous_error
24733         : wuffs_base__error__initialize_not_called);
24734   }
24735   if (!a_dst || !a_src) {
24736     self->private_impl.magic = WUFFS_BASE__DISABLED;
24737     return wuffs_base__make_status(wuffs_base__error__bad_argument);
24738   }
24739   if ((self->private_impl.active_coroutine != 0) &&
24740       (self->private_impl.active_coroutine != 1)) {
24741     self->private_impl.magic = WUFFS_BASE__DISABLED;
24742     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24743   }
24744   self->private_impl.active_coroutine = 0;
24745   wuffs_base__status status = wuffs_base__make_status(NULL);
24746 
24747   uint64_t v_string_length = 0;
24748   uint64_t v_n64 = 0;
24749   uint32_t v_depth = 0;
24750   uint32_t v_stack_byte = 0;
24751   uint32_t v_stack_bit = 0;
24752   uint32_t v_stack_val = 0;
24753   uint32_t v_token_length = 0;
24754   uint32_t v_vminor = 0;
24755   uint32_t v_vminor_alt = 0;
24756   uint32_t v_continued = 0;
24757   uint8_t v_c = 0;
24758   uint8_t v_c_major = 0;
24759   uint8_t v_c_minor = 0;
24760   bool v_tagged = false;
24761   uint8_t v_indefinite_string_major_type = 0;
24762 
24763   wuffs_base__token* iop_a_dst = NULL;
24764   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24765   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24766   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24767   if (a_dst) {
24768     io0_a_dst = a_dst->data.ptr;
24769     io1_a_dst = io0_a_dst + a_dst->meta.wi;
24770     iop_a_dst = io1_a_dst;
24771     io2_a_dst = io0_a_dst + a_dst->data.len;
24772     if (a_dst->meta.closed) {
24773       io2_a_dst = iop_a_dst;
24774     }
24775   }
24776   const uint8_t* iop_a_src = NULL;
24777   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24778   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24779   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24780   if (a_src) {
24781     io0_a_src = a_src->data.ptr;
24782     io1_a_src = io0_a_src + a_src->meta.ri;
24783     iop_a_src = io1_a_src;
24784     io2_a_src = io0_a_src + a_src->meta.wi;
24785   }
24786 
24787   uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
24788   if (coro_susp_point) {
24789     v_string_length = self->private_data.s_decode_tokens[0].v_string_length;
24790     v_depth = self->private_data.s_decode_tokens[0].v_depth;
24791     v_token_length = self->private_data.s_decode_tokens[0].v_token_length;
24792     v_tagged = self->private_data.s_decode_tokens[0].v_tagged;
24793     v_indefinite_string_major_type = self->private_data.s_decode_tokens[0].v_indefinite_string_major_type;
24794   }
24795   switch (coro_susp_point) {
24796     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24797 
24798     if (self->private_impl.f_end_of_data) {
24799       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
24800       goto ok;
24801     }
24802     label__outer__continue:;
24803     while (true) {
24804       while (true) {
24805         while (true) {
24806           if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
24807             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24808             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
24809             goto label__outer__continue;
24810           }
24811           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
24812             if (a_src && a_src->meta.closed) {
24813               status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24814               goto exit;
24815             }
24816             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24817             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
24818             goto label__outer__continue;
24819           }
24820           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
24821           if ((v_indefinite_string_major_type != 0) && (v_indefinite_string_major_type != (v_c >> 5))) {
24822             if (v_c != 255) {
24823               status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24824               goto exit;
24825             }
24826             v_vminor = 4194560;
24827             if (v_indefinite_string_major_type == 3) {
24828               v_vminor |= 19;
24829             }
24830             v_indefinite_string_major_type = 0;
24831             iop_a_src += 1;
24832             *iop_a_dst++ = wuffs_base__make_token(
24833                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24834                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24835             goto label__goto_parsed_a_leaf_value__break;
24836           }
24837           iop_a_src += 1;
24838           v_c_major = ((uint8_t)((v_c >> 5)));
24839           v_c_minor = (v_c & 31);
24840           if (v_c_minor < 24) {
24841             v_string_length = ((uint64_t)(v_c_minor));
24842           } else {
24843             while (true) {
24844               if (v_c_minor == 24) {
24845                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 1) {
24846                   v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
24847                   iop_a_src += 1;
24848                   goto label__goto_have_string_length__break;
24849                 }
24850               } else if (v_c_minor == 25) {
24851                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 2) {
24852                   v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
24853                   iop_a_src += 2;
24854                   goto label__goto_have_string_length__break;
24855                 }
24856               } else if (v_c_minor == 26) {
24857                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
24858                   v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
24859                   iop_a_src += 4;
24860                   goto label__goto_have_string_length__break;
24861                 }
24862               } else if (v_c_minor == 27) {
24863                 if (((uint64_t)(io2_a_src - iop_a_src)) >= 8) {
24864                   v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
24865                   iop_a_src += 8;
24866                   goto label__goto_have_string_length__break;
24867                 }
24868               } else {
24869                 v_string_length = 0;
24870                 goto label__goto_have_string_length__break;
24871               }
24872               if (iop_a_src > io1_a_src) {
24873                 iop_a_src--;
24874                 if (a_src && a_src->meta.closed) {
24875                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24876                   goto exit;
24877                 }
24878                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24879                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
24880                 v_c_major = 0;
24881                 v_c_minor = 0;
24882                 goto label__outer__continue;
24883               }
24884               status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
24885               goto exit;
24886             }
24887             label__goto_have_string_length__break:;
24888           }
24889           if (v_c_major == 0) {
24890             if (v_c_minor < 26) {
24891               *iop_a_dst++ = wuffs_base__make_token(
24892                   (((uint64_t)((14680064 | ((uint32_t)((v_string_length & 65535)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24893                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24894               goto label__goto_parsed_a_leaf_value__break;
24895             } else if (v_c_minor < 28) {
24896               *iop_a_dst++ = wuffs_base__make_token(
24897                   (((uint64_t)((14680064 | ((uint32_t)((v_string_length >> 46)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24898                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24899                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24900               *iop_a_dst++ = wuffs_base__make_token(
24901                   (~(v_string_length & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
24902                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24903               goto label__goto_parsed_a_leaf_value__break;
24904             }
24905           } else if (v_c_major == 1) {
24906             if (v_c_minor < 26) {
24907               *iop_a_dst++ = wuffs_base__make_token(
24908                   (((uint64_t)((12582912 | (2097151 - ((uint32_t)((v_string_length & 65535))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24909                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24910               goto label__goto_parsed_a_leaf_value__break;
24911             } else if (v_c_minor < 28) {
24912               if (v_string_length < 9223372036854775808u) {
24913                 *iop_a_dst++ = wuffs_base__make_token(
24914                     (((uint64_t)((12582912 | (2097151 - ((uint32_t)((v_string_length >> 46))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24915                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24916                     (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24917                 *iop_a_dst++ = wuffs_base__make_token(
24918                     (~((18446744073709551615u - v_string_length) & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
24919                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24920               } else {
24921                 *iop_a_dst++ = wuffs_base__make_token(
24922                     (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
24923                     (((uint64_t)(16777216)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24924                     (((uint64_t)(9)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24925               }
24926               goto label__goto_parsed_a_leaf_value__break;
24927             }
24928           } else if (v_c_major == 2) {
24929             if (v_c_minor < 28) {
24930               if (v_string_length == 0) {
24931                 *iop_a_dst++ = wuffs_base__make_token(
24932                     (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24933                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24934                 goto label__goto_parsed_a_leaf_value__break;
24935               }
24936               *iop_a_dst++ = wuffs_base__make_token(
24937                   (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24938                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24939                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24940             } else if (v_c_minor == 31) {
24941               if (v_indefinite_string_major_type != 0) {
24942                 goto label__goto_fail__break;
24943               }
24944               v_indefinite_string_major_type = 2;
24945               *iop_a_dst++ = wuffs_base__make_token(
24946                   (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24947                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24948                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24949               goto label__outer__continue;
24950             } else {
24951               goto label__goto_fail__break;
24952             }
24953             label__0__continue:;
24954             while (true) {
24955               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
24956                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24957                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
24958                 goto label__0__continue;
24959               }
24960               v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src)));
24961               v_token_length = ((uint32_t)((v_n64 & 65535)));
24962               if (v_n64 > 65535) {
24963                 v_token_length = 65535;
24964               } else if (v_token_length <= 0) {
24965                 if (a_src && a_src->meta.closed) {
24966                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24967                   goto exit;
24968                 }
24969                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24970                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
24971                 goto label__0__continue;
24972               }
24973               if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
24974                 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
24975                 goto exit;
24976               }
24977               v_string_length -= ((uint64_t)(v_token_length));
24978               v_continued = 0;
24979               if ((v_string_length > 0) || (v_indefinite_string_major_type > 0)) {
24980                 v_continued = 1;
24981               }
24982               iop_a_src += v_token_length;
24983               *iop_a_dst++ = wuffs_base__make_token(
24984                   (((uint64_t)(4194816)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24985                   (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24986                   (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24987               if (v_string_length > 0) {
24988                 goto label__0__continue;
24989               } else if (v_indefinite_string_major_type > 0) {
24990                 goto label__outer__continue;
24991               }
24992               goto label__goto_parsed_a_leaf_value__break;
24993             }
24994           } else if (v_c_major == 3) {
24995             if (v_c_minor < 28) {
24996               if (v_string_length == 0) {
24997                 *iop_a_dst++ = wuffs_base__make_token(
24998                     (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24999                     (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25000                 goto label__goto_parsed_a_leaf_value__break;
25001               }
25002               *iop_a_dst++ = wuffs_base__make_token(
25003                   (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25004                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25005                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25006             } else if (v_c_minor == 31) {
25007               if (v_indefinite_string_major_type != 0) {
25008                 goto label__goto_fail__break;
25009               }
25010               v_indefinite_string_major_type = 3;
25011               *iop_a_dst++ = wuffs_base__make_token(
25012                   (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25013                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25014                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25015               goto label__outer__continue;
25016             } else {
25017               goto label__goto_fail__break;
25018             }
25019             label__1__continue:;
25020             while (true) {
25021               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
25022                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
25023                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
25024                 goto label__1__continue;
25025               }
25026               v_n64 = wuffs_base__u64__min(v_string_length, 65535);
25027               v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src,
25028                   ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64))))));
25029               v_token_length = ((uint32_t)((v_n64 & 65535)));
25030               if (v_token_length <= 0) {
25031                 if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
25032                   status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
25033                   goto exit;
25034                 }
25035                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
25036                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
25037                 goto label__1__continue;
25038               }
25039               if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
25040                 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
25041                 goto exit;
25042               }
25043               v_string_length -= ((uint64_t)(v_token_length));
25044               v_continued = 0;
25045               if ((v_string_length > 0) || (v_indefinite_string_major_type > 0)) {
25046                 v_continued = 1;
25047               }
25048               iop_a_src += v_token_length;
25049               *iop_a_dst++ = wuffs_base__make_token(
25050                   (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25051                   (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25052                   (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25053               if (v_string_length > 0) {
25054                 goto label__1__continue;
25055               } else if (v_indefinite_string_major_type > 0) {
25056                 goto label__outer__continue;
25057               }
25058               goto label__goto_parsed_a_leaf_value__break;
25059             }
25060           } else if (v_c_major == 4) {
25061             if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0) {
25062               goto label__goto_fail__break;
25063             } else if (v_depth >= 1024) {
25064               v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
25065               while ((v_token_length > 0) && (iop_a_src > io1_a_src)) {
25066                 iop_a_src--;
25067                 v_token_length -= 1;
25068               }
25069               status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
25070               goto exit;
25071             }
25072             v_vminor = 2105361;
25073             v_vminor_alt = 2101282;
25074             if (v_depth > 0) {
25075               v_stack_byte = ((v_depth - 1) / 16);
25076               v_stack_bit = (((v_depth - 1) & 15) * 2);
25077               if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25078                 v_vminor = 2105377;
25079                 v_vminor_alt = 2105378;
25080               } else {
25081                 v_vminor = 2105409;
25082                 v_vminor_alt = 2113570;
25083               }
25084             }
25085             *iop_a_dst++ = wuffs_base__make_token(
25086                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25087                 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25088             if (v_c_minor == 0) {
25089               *iop_a_dst++ = wuffs_base__make_token(
25090                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25091                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25092               goto label__goto_parsed_a_leaf_value__break;
25093             }
25094             v_stack_byte = (v_depth / 16);
25095             v_stack_bit = ((v_depth & 15) * 2);
25096             self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(3)) << v_stack_bit));
25097             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
25098             v_depth += 1;
25099             v_tagged = false;
25100             goto label__outer__continue;
25101           } else if (v_c_major == 5) {
25102             if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0) {
25103               goto label__goto_fail__break;
25104             } else if (v_depth >= 1024) {
25105               v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
25106               while ((v_token_length > 0) && (iop_a_src > io1_a_src)) {
25107                 iop_a_src--;
25108                 v_token_length -= 1;
25109               }
25110               status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
25111               goto exit;
25112             }
25113             v_vminor = 2113553;
25114             v_vminor_alt = 2101314;
25115             if (v_depth > 0) {
25116               v_stack_byte = ((v_depth - 1) / 16);
25117               v_stack_bit = (((v_depth - 1) & 15) * 2);
25118               if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25119                 v_vminor = 2113569;
25120                 v_vminor_alt = 2105410;
25121               } else {
25122                 v_vminor = 2113601;
25123                 v_vminor_alt = 2113602;
25124               }
25125             }
25126             *iop_a_dst++ = wuffs_base__make_token(
25127                 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25128                 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25129             if (v_c_minor == 0) {
25130               *iop_a_dst++ = wuffs_base__make_token(
25131                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25132                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25133               goto label__goto_parsed_a_leaf_value__break;
25134             }
25135             v_stack_byte = (v_depth / 16);
25136             v_stack_bit = ((v_depth & 15) * 2);
25137             self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3)) << v_stack_bit);
25138             self->private_data.f_container_num_remaining[v_depth] = v_string_length;
25139             v_depth += 1;
25140             v_tagged = false;
25141             goto label__outer__continue;
25142           } else if (v_c_major == 6) {
25143             if (v_c_minor >= 28) {
25144               goto label__goto_fail__break;
25145             }
25146             if (v_string_length < 262144) {
25147               *iop_a_dst++ = wuffs_base__make_token(
25148                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25149                   (((uint64_t)((4194304 | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25150                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25151             } else {
25152               *iop_a_dst++ = wuffs_base__make_token(
25153                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25154                   (((uint64_t)((4194304 | ((uint32_t)((v_string_length >> 46)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25155                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25156                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25157               *iop_a_dst++ = wuffs_base__make_token(
25158                   (~(v_string_length & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
25159                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25160             }
25161             v_tagged = true;
25162             goto label__outer__continue;
25163           } else if (v_c_major == 7) {
25164             if (v_c_minor < 20) {
25165               *iop_a_dst++ = wuffs_base__make_token(
25166                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25167                   (((uint64_t)((8388608 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25168                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25169               goto label__goto_parsed_a_leaf_value__break;
25170             } else if (v_c_minor < 24) {
25171               *iop_a_dst++ = wuffs_base__make_token(
25172                   (((uint64_t)(WUFFS_CBOR__LITERALS[(v_c_minor & 3)])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25173                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25174               goto label__goto_parsed_a_leaf_value__break;
25175             } else if (v_c_minor == 24) {
25176               if (v_string_length < 24) {
25177                 if ( ! (iop_a_src > io1_a_src)) {
25178                   status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
25179                   goto exit;
25180                 }
25181                 iop_a_src--;
25182                 goto label__goto_fail__break;
25183               }
25184               *iop_a_dst++ = wuffs_base__make_token(
25185                   (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25186                   (((uint64_t)((8388608 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25187                   (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25188               goto label__goto_parsed_a_leaf_value__break;
25189             } else if (v_c_minor < 28) {
25190               *iop_a_dst++ = wuffs_base__make_token(
25191                   (((uint64_t)(10490113)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25192                   (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25193               goto label__goto_parsed_a_leaf_value__break;
25194             } else if (v_c_minor == 31) {
25195               if (v_tagged || (v_depth <= 0)) {
25196                 goto label__goto_fail__break;
25197               }
25198               v_depth -= 1;
25199               if (self->private_data.f_container_num_remaining[v_depth] != 0) {
25200                 goto label__goto_fail__break;
25201               }
25202               v_stack_byte = (v_depth / 16);
25203               v_stack_bit = ((v_depth & 15) * 2);
25204               v_stack_val = (3 & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit));
25205               if (v_stack_val == 1) {
25206                 goto label__goto_fail__break;
25207               }
25208               if (v_stack_val != 3) {
25209                 v_vminor_alt = 2097186;
25210               } else {
25211                 v_vminor_alt = 2097218;
25212               }
25213               if (v_depth <= 0) {
25214                 v_vminor_alt |= 4096;
25215               } else {
25216                 v_stack_byte = ((v_depth - 1) / 16);
25217                 v_stack_bit = (((v_depth - 1) & 15) * 2);
25218                 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25219                   v_vminor_alt |= 8192;
25220                 } else {
25221                   v_vminor_alt |= 16384;
25222                 }
25223               }
25224               *iop_a_dst++ = wuffs_base__make_token(
25225                   (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25226                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25227               goto label__goto_parsed_a_leaf_value__break;
25228             }
25229           }
25230           goto label__goto_fail__break;
25231         }
25232         label__goto_fail__break:;
25233         if (iop_a_src > io1_a_src) {
25234           iop_a_src--;
25235           status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
25236           goto exit;
25237         }
25238         status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
25239         goto exit;
25240       }
25241       label__goto_parsed_a_leaf_value__break:;
25242       v_tagged = false;
25243       while (v_depth > 0) {
25244         v_stack_byte = ((v_depth - 1) / 16);
25245         v_stack_bit = (((v_depth - 1) & 15) * 2);
25246         self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1)) << (v_stack_bit + 1));
25247         if (1 == (3 & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) {
25248           goto label__outer__continue;
25249         }
25250         if (self->private_data.f_container_num_remaining[(v_depth - 1)] <= 0) {
25251           goto label__outer__continue;
25252         }
25253         self->private_data.f_container_num_remaining[(v_depth - 1)] -= 1;
25254         if (self->private_data.f_container_num_remaining[(v_depth - 1)] > 0) {
25255           goto label__outer__continue;
25256         }
25257         label__2__continue:;
25258         while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
25259           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
25260           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
25261           goto label__2__continue;
25262         }
25263         v_depth -= 1;
25264         v_stack_byte = (v_depth / 16);
25265         v_stack_bit = ((v_depth & 15) * 2);
25266         if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25267           v_vminor_alt = 2097186;
25268         } else {
25269           v_vminor_alt = 2097218;
25270         }
25271         if (v_depth <= 0) {
25272           v_vminor_alt |= 4096;
25273         } else {
25274           v_stack_byte = ((v_depth - 1) / 16);
25275           v_stack_bit = (((v_depth - 1) & 15) * 2);
25276           if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25277             v_vminor_alt |= 8192;
25278           } else {
25279             v_vminor_alt |= 16384;
25280           }
25281         }
25282         *iop_a_dst++ = wuffs_base__make_token(
25283             (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25284             (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25285       }
25286       goto label__outer__break;
25287     }
25288     label__outer__break:;
25289     self->private_impl.f_end_of_data = true;
25290 
25291     ok:
25292     self->private_impl.p_decode_tokens[0] = 0;
25293     goto exit;
25294   }
25295 
25296   goto suspend;
25297   suspend:
25298   self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
25299   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
25300   self->private_data.s_decode_tokens[0].v_string_length = v_string_length;
25301   self->private_data.s_decode_tokens[0].v_depth = v_depth;
25302   self->private_data.s_decode_tokens[0].v_token_length = v_token_length;
25303   self->private_data.s_decode_tokens[0].v_tagged = v_tagged;
25304   self->private_data.s_decode_tokens[0].v_indefinite_string_major_type = v_indefinite_string_major_type;
25305 
25306   goto exit;
25307   exit:
25308   if (a_dst) {
25309     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
25310   }
25311   if (a_src) {
25312     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
25313   }
25314 
25315   if (wuffs_base__status__is_error(&status)) {
25316     self->private_impl.magic = WUFFS_BASE__DISABLED;
25317   }
25318   return status;
25319 }
25320 
25321 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
25322 
25323 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
25324 
25325 // ---------------- Status Codes Implementations
25326 
25327 // ---------------- Private Consts
25328 
25329 static const uint32_t
25330 WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = {
25331   {
25332     0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
25333     249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
25334     498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
25335     325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
25336     997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
25337     901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
25338     651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
25339     671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
25340     1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
25341     2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
25342     1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
25343     1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
25344     1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
25345     1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
25346     1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
25347     1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
25348     3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
25349     3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
25350     4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
25351     4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
25352     3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
25353     3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
25354     3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
25355     3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
25356     2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
25357     2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
25358     2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
25359     2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
25360     2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
25361     2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
25362     3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
25363     3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117,
25364   }, {
25365     0, 421212481, 842424962, 724390851, 1684849924, 2105013317, 1448781702, 1329698503,
25366     3369699848, 3519200073, 4210026634, 3824474571, 2897563404, 3048111693, 2659397006, 2274893007,
25367     1254232657, 1406739216, 2029285587, 1643069842, 783210325, 934667796, 479770071, 92505238,
25368     2182846553, 2600511768, 2955803355, 2838940570, 3866582365, 4285295644, 3561045983, 3445231262,
25369     2508465314, 2359236067, 2813478432, 3198777185, 4058571174, 3908292839, 3286139684, 3670389349,
25370     1566420650, 1145479147, 1869335592, 1987116393, 959540142, 539646703, 185010476, 303839341,
25371     3745920755, 3327985586, 3983561841, 4100678960, 3140154359, 2721170102, 2300350837, 2416418868,
25372     396344571, 243568058, 631889529, 1018359608, 1945336319, 1793607870, 1103436669, 1490954812,
25373     4034481925, 3915546180, 3259968903, 3679722694, 2484439553, 2366552896, 2787371139, 3208174018,
25374     950060301, 565965900, 177645455, 328046286, 1556873225, 1171730760, 1861902987, 2011255754,
25375     3132841300, 2745199637, 2290958294, 2442530455, 3738671184, 3352078609, 3974232786, 4126854035,
25376     1919080284, 1803150877, 1079293406, 1498383519, 370020952, 253043481, 607678682, 1025720731,
25377     1711106983, 2095471334, 1472923941, 1322268772, 26324643, 411738082, 866634785, 717028704,
25378     2904875439, 3024081134, 2668790573, 2248782444, 3376948395, 3495106026, 4219356713, 3798300520,
25379     792689142, 908347575, 487136116, 68299317, 1263779058, 1380486579, 2036719216, 1618931505,
25380     3890672638, 4278043327, 3587215740, 3435896893, 2206873338, 2593195963, 2981909624, 2829542713,
25381     998479947, 580430090, 162921161, 279890824, 1609522511, 1190423566, 1842954189, 1958874764,
25382     4082766403, 3930137346, 3245109441, 3631694208, 2536953671, 2385372678, 2768287173, 3155920004,
25383     1900120602, 1750776667, 1131931800, 1517083097, 355290910, 204897887, 656092572, 1040194781,
25384     3113746450, 2692952403, 2343461520, 2461357009, 3723805974, 3304059991, 4022511508, 4141455061,
25385     2919742697, 3072101800, 2620513899, 2234183466, 3396041197, 3547351212, 4166851439, 3779471918,
25386     1725839073, 2143618976, 1424512099, 1307796770, 45282277, 464110244, 813994343, 698327078,
25387     3838160568, 4259225593, 3606301754, 3488152955, 2158586812, 2578602749, 2996767038, 2877569151,
25388     740041904, 889656817, 506086962, 120682355, 1215357364, 1366020341, 2051441462, 1667084919,
25389     3422213966, 3538019855, 4190942668, 3772220557, 2945847882, 3062702859, 2644537544, 2226864521,
25390     52649286, 439905287, 823476164, 672009861, 1733269570, 2119477507, 1434057408, 1281543041,
25391     2167981343, 2552493150, 3004082077, 2853541596, 3847487515, 4233048410, 3613549209, 3464057816,
25392     1239502615, 1358593622, 2077699477, 1657543892, 764250643, 882293586, 532408465, 111204816,
25393     1585378284, 1197851309, 1816695150, 1968414767, 974272232, 587794345, 136598634, 289367339,
25394     2527558116, 2411481253, 2760973158, 3179948583, 4073438432, 3956313505, 3237863010, 3655790371,
25395     347922877, 229101820, 646611775, 1066513022, 1892689081, 1774917112, 1122387515, 1543337850,
25396     3697634229, 3313392372, 3998419255, 4148705398, 3087642289, 2702352368, 2319436851, 2468674930,
25397   }, {
25398     0, 29518391, 59036782, 38190681, 118073564, 114017003, 76381362, 89069189,
25399     236147128, 265370511, 228034006, 206958561, 152762724, 148411219, 178138378, 190596925,
25400     472294256, 501532999, 530741022, 509615401, 456068012, 451764635, 413917122, 426358261,
25401     305525448, 334993663, 296822438, 275991697, 356276756, 352202787, 381193850, 393929805,
25402     944588512, 965684439, 1003065998, 973863097, 1061482044, 1049003019, 1019230802, 1023561829,
25403     912136024, 933002607, 903529270, 874031361, 827834244, 815125939, 852716522, 856752605,
25404     611050896, 631869351, 669987326, 640506825, 593644876, 580921211, 551983394, 556069653,
25405     712553512, 733666847, 704405574, 675154545, 762387700, 749958851, 787859610, 792175277,
25406     1889177024, 1901651959, 1931368878, 1927033753, 2006131996, 1985040171, 1947726194, 1976933189,
25407     2122964088, 2135668303, 2098006038, 2093965857, 2038461604, 2017599123, 2047123658, 2076625661,
25408     1824272048, 1836991623, 1866005214, 1861914857, 1807058540, 1786244187, 1748062722, 1777547317,
25409     1655668488, 1668093247, 1630251878, 1625932113, 1705433044, 1684323811, 1713505210, 1742760333,
25410     1222101792, 1226154263, 1263738702, 1251046777, 1339974652, 1310460363, 1281013650, 1301863845,
25411     1187289752, 1191637167, 1161842422, 1149379777, 1103966788, 1074747507, 1112139306, 1133218845,
25412     1425107024, 1429406311, 1467333694, 1454888457, 1408811148, 1379576507, 1350309090, 1371438805,
25413     1524775400, 1528845279, 1499917702, 1487177649, 1575719220, 1546255107, 1584350554, 1605185389,
25414     3778354048, 3774312887, 3803303918, 3816007129, 3862737756, 3892238699, 3854067506, 3833203973,
25415     4012263992, 4007927823, 3970080342, 3982554209, 3895452388, 3924658387, 3953866378, 3932773565,
25416     4245928176, 4241609415, 4271336606, 4283762345, 4196012076, 4225268251, 4187931714, 4166823541,
25417     4076923208, 4072833919, 4035198246, 4047918865, 4094247316, 4123732899, 4153251322, 4132437965,
25418     3648544096, 3636082519, 3673983246, 3678331705, 3732010428, 3753090955, 3723829714, 3694611429,
25419     3614117080, 3601426159, 3572488374, 3576541825, 3496125444, 3516976691, 3555094634, 3525581405,
25420     3311336976, 3298595879, 3336186494, 3340255305, 3260503756, 3281337595, 3251864226, 3222399125,
25421     3410866088, 3398419871, 3368647622, 3372945905, 3427010420, 3448139075, 3485520666, 3456284973,
25422     2444203584, 2423127159, 2452308526, 2481530905, 2527477404, 2539934891, 2502093554, 2497740997,
25423     2679949304, 2659102159, 2620920726, 2650438049, 2562027300, 2574714131, 2603727690, 2599670141,
25424     2374579504, 2353749767, 2383274334, 2412743529, 2323684844, 2336421851, 2298759554, 2294686645,
25425     2207933576, 2186809023, 2149495014, 2178734801, 2224278612, 2236720739, 2266437690, 2262135309,
25426     2850214048, 2820717207, 2858812622, 2879680249, 2934667388, 2938704459, 2909776914, 2897069605,
25427     2817622296, 2788420399, 2759153014, 2780249921, 2700618180, 2704950259, 2742877610, 2730399645,
25428     3049550800, 3020298727, 3057690558, 3078802825, 2999835404, 3004150075, 2974355298, 2961925461,
25429     3151438440, 3121956959, 3092510214, 3113327665, 3168701108, 3172786307, 3210370778, 3197646061,
25430   }, {
25431     0, 3099354981, 2852767883, 313896942, 2405603159, 937357362, 627793884, 2648127673,
25432     3316918511, 2097696650, 1874714724, 3607201537, 1255587768, 4067088605, 3772741427, 1482887254,
25433     1343838111, 3903140090, 4195393300, 1118632049, 3749429448, 1741137837, 1970407491, 3452858150,
25434     2511175536, 756094997, 1067759611, 2266550430, 449832999, 2725482306, 2965774508, 142231497,
25435     2687676222, 412010587, 171665333, 2995192016, 793786473, 2548850444, 2237264098, 1038456711,
25436     1703315409, 3711623348, 3482275674, 1999841343, 3940814982, 1381529571, 1089329165, 4166106984,
25437     4029413537, 1217896388, 1512189994, 3802027855, 2135519222, 3354724499, 3577784189, 1845280792,
25438     899665998, 2367928107, 2677414085, 657096608, 3137160985, 37822588, 284462994, 2823350519,
25439     2601801789, 598228824, 824021174, 2309093331, 343330666, 2898962447, 3195996129, 113467524,
25440     1587572946, 3860600759, 4104763481, 1276501820, 3519211397, 1769898208, 2076913422, 3279374443,
25441     3406630818, 1941006535, 1627703081, 3652755532, 1148164341, 4241751952, 3999682686, 1457141531,
25442     247015245, 3053797416, 2763059142, 470583459, 2178658330, 963106687, 735213713, 2473467892,
25443     992409347, 2207944806, 2435792776, 697522413, 3024379988, 217581361, 508405983, 2800865210,
25444     4271038444, 1177467017, 1419450215, 3962007554, 1911572667, 3377213406, 3690561584, 1665525589,
25445     1799331996, 3548628985, 3241568279, 2039091058, 3831314379, 1558270126, 1314193216, 4142438437,
25446     2928380019, 372764438, 75645176, 3158189981, 568925988, 2572515393, 2346768303, 861712586,
25447     3982079547, 1441124702, 1196457648, 4293663189, 1648042348, 3666298377, 3358779879, 1888390786,
25448     686661332, 2421291441, 2196002399, 978858298, 2811169155, 523464422, 226935048, 3040519789,
25449     3175145892, 100435649, 390670639, 2952089162, 841119475, 2325614998, 2553003640, 546822429,
25450     2029308235, 3225988654, 3539796416, 1782671013, 4153826844, 1328167289, 1570739863, 3844338162,
25451     1298864389, 4124540512, 3882013070, 1608431339, 3255406162, 2058742071, 1744848601, 3501990332,
25452     2296328682, 811816591, 584513889, 2590678532, 129869501, 3204563416, 2914283062, 352848211,
25453     494030490, 2781751807, 3078325777, 264757620, 2450577869, 715964072, 941166918, 2158327331,
25454     3636881013, 1618608400, 1926213374, 3396585883, 1470427426, 4011365959, 4255988137, 1158766284,
25455     1984818694, 3471935843, 3695453837, 1693991400, 4180638033, 1100160564, 1395044826, 3952793279,
25456     3019491049, 189112716, 435162722, 2706139399, 1016811966, 2217162459, 2526189877, 774831696,
25457     643086745, 2666061564, 2354934034, 887166583, 2838900430, 294275499, 54519365, 3145957664,
25458     3823145334, 1532818963, 1240029693, 4048895640, 1820460577, 3560857924, 3331051178, 2117577167,
25459     3598663992, 1858283101, 2088143283, 3301633750, 1495127663, 3785470218, 4078182116, 1269332353,
25460     332098007, 2876706482, 3116540252, 25085497, 2628386432, 605395429, 916469259, 2384220526,
25461     2254837415, 1054503362, 745528876, 2496903497, 151290352, 2981684885, 2735556987, 464596510,
25462     1137851976, 4218313005, 3923506883, 1365741990, 3434129695, 1946996346, 1723425172, 3724871409,
25463   }, {
25464     0, 1029712304, 2059424608, 1201699536, 4118849216, 3370159984, 2403399072, 2988497936,
25465     812665793, 219177585, 1253054625, 2010132753, 3320900865, 4170237105, 3207642721, 2186319825,
25466     1625331586, 1568718386, 438355170, 658566482, 2506109250, 2818578674, 4020265506, 3535817618,
25467     1351670851, 1844508147, 709922595, 389064339, 2769320579, 2557498163, 3754961379, 3803185235,
25468     3250663172, 4238411444, 3137436772, 2254525908, 876710340, 153198708, 1317132964, 1944187668,
25469     4054934725, 3436268917, 2339452837, 3054575125, 70369797, 961670069, 2129760613, 1133623509,
25470     2703341702, 2621542710, 3689016294, 3867263574, 1419845190, 1774270454, 778128678, 318858390,
25471     2438067015, 2888948471, 3952189479, 3606153623, 1691440519, 1504803895, 504432359, 594620247,
25472     1492342857, 1704161785, 573770537, 525542041, 2910060169, 2417219385, 3618876905, 3939730521,
25473     1753420680, 1440954936, 306397416, 790849880, 2634265928, 2690882808, 3888375336, 3668168600,
25474     940822475, 91481723, 1121164459, 2142483739, 3448989963, 4042473659, 3075684971, 2318603227,
25475     140739594, 889433530, 1923340138, 1338244826, 4259521226, 3229813626, 2267247018, 3124975642,
25476     2570221389, 2756861693, 3824297005, 3734113693, 1823658381, 1372780605, 376603373, 722643805,
25477     2839690380, 2485261628, 3548540908, 4007806556, 1556257356, 1638052860, 637716780, 459464860,
25478     4191346895, 3300051327, 2199040943, 3195181599, 206718479, 825388991, 1989285231, 1274166495,
25479     3382881038, 4106388158, 3009607790, 2382549470, 1008864718, 21111934, 1189240494, 2072147742,
25480     2984685714, 2357631266, 3408323570, 4131834434, 1147541074, 2030452706, 1051084082, 63335554,
25481     2174155603, 3170292451, 4216760371, 3325460867, 1947622803, 1232499747, 248909555, 867575619,
25482     3506841360, 3966111392, 2881909872, 2527485376, 612794832, 434546784, 1581699760, 1663499008,
25483     3782634705, 3692447073, 2612412337, 2799048193, 351717905, 697754529, 1849071985, 1398190273,
25484     1881644950, 1296545318, 182963446, 931652934, 2242328918, 3100053734, 4284967478, 3255255942,
25485     1079497815, 2100821479, 983009079, 133672583, 3050795671, 2293717799, 3474399735, 4067887175,
25486     281479188, 765927844, 1778867060, 1466397380, 3846680276, 3626469220, 2676489652, 2733102084,
25487     548881365, 500656741, 1517752501, 1729575173, 3577210133, 3898068133, 2952246901, 2459410373,
25488     3910527195, 3564487019, 2480257979, 2931134987, 479546907, 569730987, 1716854139, 1530213579,
25489     3647316762, 3825568426, 2745561210, 2663766474, 753206746, 293940330, 1445287610, 1799716618,
25490     2314567513, 3029685993, 4080348217, 3461678473, 2088098201, 1091956777, 112560889, 1003856713,
25491     3112514712, 2229607720, 3276105720, 4263857736, 1275433560, 1902492648, 918929720, 195422344,
25492     685033439, 364179055, 1377080511, 1869921551, 3713294623, 3761522863, 2811507327, 2599689167,
25493     413436958, 633644462, 1650777982, 1594160846, 3978570462, 3494118254, 2548332990, 2860797966,
25494     1211387997, 1968470509, 854852413, 261368461, 3182753437, 2161434413, 3346310653, 4195650637,
25495     2017729436, 1160000044, 42223868, 1071931724, 2378480988, 2963576044, 4144295484, 3395602316,
25496   }, {
25497     0, 3411858341, 1304994059, 2257875630, 2609988118, 1355649459, 3596215069, 486879416,
25498     3964895853, 655315400, 2711298918, 1791488195, 2009251963, 3164476382, 973758832, 4048990933,
25499     64357019, 3364540734, 1310630800, 2235723829, 2554806413, 1394316072, 3582976390, 517157411,
25500     4018503926, 618222419, 2722963965, 1762783832, 1947517664, 3209171269, 970744811, 4068520014,
25501     128714038, 3438335635, 1248109629, 2167961496, 2621261600, 1466012805, 3522553387, 447296910,
25502     3959392091, 547575038, 2788632144, 1835791861, 1886307661, 3140622056, 1034314822, 4143626211,
25503     75106221, 3475428360, 1236444838, 2196665603, 2682996155, 1421317662, 3525567664, 427767573,
25504     3895035328, 594892389, 2782995659, 1857943406, 1941489622, 3101955187, 1047553757, 4113347960,
25505     257428076, 3288652233, 1116777319, 2311878850, 2496219258, 1603640287, 3640781169, 308099796,
25506     3809183745, 676813732, 2932025610, 1704983215, 2023410199, 3016104370, 894593820, 4262377657,
25507     210634999, 3352484690, 1095150076, 2316991065, 2535410401, 1547934020, 3671583722, 294336591,
25508     3772615322, 729897279, 2903845777, 1716123700, 2068629644, 2953845545, 914647431, 4258839074,
25509     150212442, 3282623743, 1161604689, 2388688372, 2472889676, 1480171241, 3735940167, 368132066,
25510     3836185911, 805002898, 2842635324, 1647574937, 2134298401, 3026852996, 855535146, 4188192143,
25511     186781121, 3229539940, 1189784778, 2377547631, 2427670487, 1542429810, 3715886812, 371670393,
25512     3882979244, 741170185, 2864262823, 1642462466, 2095107514, 3082559007, 824732849, 4201955092,
25513     514856152, 3589064573, 1400419795, 2552522358, 2233554638, 1316849003, 3370776517, 62202976,
25514     4075001525, 968836368, 3207280574, 1954014235, 1769133219, 2720925446, 616199592, 4024870413,
25515     493229635, 3594175974, 1353627464, 2616354029, 2264355925, 1303087088, 3409966430, 6498043,
25516     4046820398, 979978123, 3170710821, 2007099008, 1789187640, 2717386141, 661419827, 3962610838,
25517     421269998, 3527459403, 1423225061, 2676515648, 2190300152, 1238466653, 3477467891, 68755798,
25518     4115633027, 1041448998, 3095868040, 1943789869, 1860096405, 2776760880, 588673182, 3897205563,
25519     449450869, 3516317904, 1459794558, 2623431131, 2170245475, 1242006214, 3432247400, 131015629,
25520     4137259288, 1036337853, 3142660115, 1879958454, 1829294862, 2790523051, 549483013, 3952910752,
25521     300424884, 3669282065, 1545650111, 2541513754, 2323209378, 1092980487, 3350330793, 216870412,
25522     4256931033, 921128828, 2960342482, 2066738807, 1714085583, 2910195050, 736264132, 3770592353,
25523     306060335, 3647131530, 1610005796, 2494197377, 2309971513, 1123257756, 3295149874, 255536279,
25524     4268596802, 892423655, 3013951305, 2029645036, 1711070292, 2929725425, 674528607, 3815288570,
25525     373562242, 3709388839, 1535949449, 2429577516, 2379569556, 1183418929, 3223189663, 188820282,
25526     4195850735, 827017802, 3084859620, 2089020225, 1636228089, 2866415708, 743340786, 3876759895,
25527     361896217, 3738094268, 1482340370, 2466671543, 2382584591, 1163888810, 3284924932, 144124321,
25528     4190215028, 849168593, 3020503679, 2136336858, 1649465698, 2836138695, 798521449, 3838094284,
25529   }, {
25530     0, 2792819636, 2543784233, 837294749, 4098827283, 1379413927, 1674589498, 3316072078,
25531     871321191, 2509784531, 2758827854, 34034938, 3349178996, 1641505216, 1346337629, 4131942633,
25532     1742642382, 3249117050, 4030828007, 1446413907, 2475800797, 904311657, 68069876, 2725880384,
25533     1412551337, 4064729373, 3283010432, 1708771380, 2692675258, 101317902, 937551763, 2442587175,
25534     3485284764, 1774858792, 1478633653, 4266992385, 1005723023, 2642744891, 2892827814, 169477906,
25535     4233263099, 1512406095, 1808623314, 3451546982, 136139752, 2926205020, 2676114113, 972376437,
25536     2825102674, 236236518, 1073525883, 2576072655, 1546420545, 4200303349, 3417542760, 1841601500,
25537     2609703733, 1039917185, 202635804, 2858742184, 1875103526, 3384067218, 4166835727, 1579931067,
25538     1141601657, 3799809741, 3549717584, 1977839588, 2957267306, 372464350, 668680259, 2175552503,
25539     2011446046, 3516084394, 3766168119, 1175200131, 2209029901, 635180217, 338955812, 2990736784,
25540     601221559, 2242044419, 3024812190, 306049834, 3617246628, 1911408144, 1074125965, 3866285881,
25541     272279504, 3058543716, 2275784441, 567459149, 3832906691, 1107462263, 1944752874, 3583875422,
25542     2343980261, 767641425, 472473036, 3126744696, 2147051766, 3649987394, 3899029983, 1309766251,
25543     3092841090, 506333494, 801510315, 2310084639, 1276520081, 3932237093, 3683203000, 2113813516,
25544     3966292011, 1243601823, 2079834370, 3716205238, 405271608, 3192979340, 2411259153, 701492901,
25545     3750207052, 2045810168, 1209569125, 4000285905, 734575199, 2378150379, 3159862134, 438345922,
25546     2283203314, 778166598, 529136603, 3120492655, 2086260449, 3660498261, 3955679176, 1303499900,
25547     3153699989, 495890209, 744928700, 2316418568, 1337360518, 3921775410, 3626602927, 2120129051,
25548     4022892092, 1237286280, 2018993941, 3726666913, 461853231, 3186645403, 2350400262, 711936178,
25549     3693557851, 2052076527, 1270360434, 3989775046, 677911624, 2384402428, 3220639073, 427820757,
25550     1202443118, 3789347034, 3493118535, 1984154099, 3018127229, 362020041, 612099668, 2181885408,
25551     1950653705, 3526596285, 3822816288, 1168934804, 2148251930, 645706414, 395618355, 2984485767,
25552     544559008, 2248295444, 3085590153, 295523645, 3560598451, 1917673479, 1134918298, 3855773998,
25553     328860103, 3052210803, 2214924526, 577903450, 3889505748, 1101147744, 1883911421, 3594338121,
25554     3424493451, 1785369663, 1535282850, 4260726038, 944946072, 2653270060, 2949491377, 163225861,
25555     4294103532, 1501944408, 1752023237, 3457862513, 196998655, 2915761739, 2619532502, 978710370,
25556     2881684293, 229902577, 1012666988, 2586515928, 1603020630, 4193987810, 3356702335, 1852063179,
25557     2553040162, 1046169238, 263412747, 2848217023, 1818454321, 3390333573, 4227627032, 1569420204,
25558     60859927, 2782375331, 2487203646, 843627658, 4159668740, 1368951216, 1617990445, 3322386585,
25559     810543216, 2520310724, 2815490393, 27783917, 3288386659, 1652017111, 1402985802, 4125677310,
25560     1685994201, 3255382381, 4091620336, 1435902020, 2419138250, 910562686, 128847843, 2715354199,
25561     1469150398, 4058414858, 3222168983, 1719234083, 2749255853, 94984985, 876691844, 2453031472,
25562   }, {
25563     0, 3433693342, 1109723005, 2391738339, 2219446010, 1222643300, 3329165703, 180685081,
25564     3555007413, 525277995, 2445286600, 1567235158, 1471092047, 2600801745, 361370162, 3642757804,
25565     2092642603, 2953916853, 1050555990, 4063508168, 4176560081, 878395215, 3134470316, 1987983410,
25566     2942184094, 1676945920, 3984272867, 567356797, 722740324, 3887998202, 1764827929, 2778407815,
25567     4185285206, 903635656, 3142804779, 2012833205, 2101111980, 2979425330, 1058630609, 4088621903,
25568     714308067, 3862526333, 1756790430, 2753330688, 2933487385, 1651734407, 3975966820, 542535930,
25569     2244825981, 1231508451, 3353891840, 188896414, 25648519, 3442302233, 1134713594, 2399689316,
25570     1445480648, 2592229462, 336416693, 3634843435, 3529655858, 516441772, 2420588879, 1559052753,
25571     698204909, 3845636723, 1807271312, 2803025166, 2916600855, 1635634313, 4025666410, 593021940,
25572     4202223960, 919787974, 3093159461, 1962401467, 2117261218, 2996361020, 1008193759, 4038971457,
25573     1428616134, 2576151384, 386135227, 3685348389, 3513580860, 499580322, 2471098945, 1608776415,
25574     2260985971, 1248454893, 3303468814, 139259792, 42591881, 3458459159, 1085071860, 2349261162,
25575     3505103035, 474062885, 2463016902, 1583654744, 1419882049, 2550902495, 377792828, 3660491170,
25576     51297038, 3483679632, 1093385331, 2374089965, 2269427188, 1273935210, 3311514249, 164344343,
25577     2890961296, 1627033870, 4000683757, 585078387, 672833386, 3836780532, 1782552599, 2794821769,
25578     2142603813, 3005188795, 1032883544, 4047146438, 4227826911, 928351297, 3118105506, 1970307900,
25579     1396409818, 2677114180, 287212199, 3719594553, 3614542624, 467372990, 2505346141, 1509854403,
25580     2162073199, 1282711281, 3271268626, 240228748, 76845205, 3359543307, 1186043880, 2317064054,
25581     796964081, 3811226735, 1839575948, 2702160658, 2882189835, 1734392469, 3924802934, 625327592,
25582     4234522436, 818917338, 3191908409, 1927981223, 2016387518, 3028656416, 973776579, 4137723485,
25583     2857232268, 1726474002, 3899187441, 616751215, 772270454, 3803048424, 1814228491, 2693328533,
25584     2041117753, 3036871847, 999160644, 4146592730, 4259508931, 826864221, 3217552830, 1936586016,
25585     3606501031, 442291769, 2496909786, 1484378436, 1388107869, 2652297411, 278519584, 3694387134,
25586     85183762, 3384397196, 1194773103, 2342308593, 2170143720, 1307820918, 3279733909, 265733131,
25587     2057717559, 3054258089, 948125770, 4096344276, 4276898253, 843467091, 3167309488, 1885556270,
25588     2839764098, 1709792284, 3949353983, 667704161, 755585656, 3785577190, 1865176325, 2743489947,
25589     102594076, 3401021058, 1144549729, 2291298815, 2186770662, 1325234296, 3228729243, 215514885,
25590     3589828009, 424832311, 2547870420, 1534552650, 1370645331, 2635621325, 328688686, 3745342640,
25591     2211456353, 1333405183, 3254067740, 224338562, 127544219, 3408931589, 1170156774, 2299866232,
25592     1345666772, 2627681866, 303053225, 3736746295, 3565105198, 416624816, 2522494803, 1525692365,
25593     4285207626, 868291796, 3176010551, 1910772649, 2065767088, 3079346734, 956571085, 4121828691,
25594     747507711, 3760459617, 1856702594, 2717976604, 2831417605, 1684930971, 3940615800, 642451174,
25595   },
25596   {
25597     0, 393942083, 787884166, 965557445, 1575768332, 1251427663, 1931114890, 1684106697,
25598     3151536664, 2896410203, 2502855326, 2186649309, 3862229780, 4048545623, 3368213394, 3753496529,
25599     2898281073, 3149616690, 2184604407, 2504883892, 4046197629, 3864463166, 3755621371, 3366006712,
25600     387506281, 6550570, 971950319, 781573292, 1257550181, 1569695014, 1677892067, 1937345952,
25601     2196865699, 2508887776, 2886183461, 3145514598, 3743273903, 3362179052, 4058774313, 3868258154,
25602     958996667, 777139448, 400492605, 10755198, 1690661303, 1941857780, 1244879153, 1565019506,
25603     775012562, 961205393, 13101140, 398261271, 1943900638, 1688634781, 1563146584, 1246801179,
25604     2515100362, 2190636681, 3139390028, 2892258831, 3355784134, 3749586821, 3874691904, 4052225795,
25605     3734110983, 3387496260, 4033096577, 3877584834, 2206093835, 2483373640, 2911402637, 3136515790,
25606     1699389727, 1915860316, 1270647193, 1556585946, 950464531, 803071056, 374397077, 19647702,
25607     1917993334, 1697207605, 1554278896, 1272937907, 800985210, 952435769, 21510396, 372452543,
25608     3381322606, 3740399405, 3883715560, 4027047851, 2489758306, 2199758369, 3130039012, 2917895847,
25609     1550025124, 1259902439, 1922410786, 1710144865, 26202280, 385139947, 796522542, 939715693,
25610     3887801276, 4039129087, 3377269562, 3728088953, 3126293168, 2905368307, 2493602358, 2212122229,
25611     4037264341, 3889747862, 3730172755, 3375300368, 2907673305, 3124004506, 2209987167, 2495786524,
25612     1266377165, 1543533966, 1703758155, 1928748296, 379007169, 32253058, 945887303, 790236164,
25613     1716846671, 1898845196, 1218652361, 1608006794, 1002000707, 750929152, 357530053, 36990342,
25614     3717046871, 3405166100, 4084959953, 3825245842, 2153902939, 2535122712, 2929187805, 3119304606,
25615     3398779454, 3723384445, 3831720632, 4078468859, 2541294386, 2147616625, 3113171892, 2935238647,
25616     1900929062, 1714877541, 1606142112, 1220599011, 748794154, 1004184937, 39295404, 355241455,
25617     3835986668, 4091516591, 3394415210, 3710500393, 3108557792, 2922629027, 2545875814, 2160455461,
25618     1601970420, 1208431799, 1904871538, 1727077425, 43020792, 367748539, 744905086, 991776061,
25619     1214562461, 1595921630, 1720903707, 1911159896, 361271697, 49513938, 998160663, 738569556,
25620     4089209477, 3838277318, 3712633347, 3392233024, 2924491657, 3106613194, 2158369551, 2547846988,
25621     3100050248, 2948339467, 2519804878, 2169126797, 3844821572, 4065347079, 3420289730, 3701894785,
25622     52404560, 342144275, 770279894, 982687125, 1593045084, 1233708063, 1879431386, 1736363161,
25623     336019769, 58479994, 988899775, 764050940, 1240141877, 1586496630, 1729968307, 1885744368,
25624     2950685473, 3097818978, 2166999975, 2522013668, 4063474221, 3846743662, 3703937707, 3418263272,
25625     976650731, 760059304, 348170605, 62635310, 1742393575, 1889649828, 1227683937, 1582820386,
25626     2179867635, 2526361520, 2937588597, 3093503798, 3691148031, 3413731004, 4076100217, 3851374138,
25627     2532754330, 2173556697, 3087067932, 2944139103, 3407516310, 3697379029, 3857496592, 4070026835,
25628     758014338, 978679233, 64506116, 346250567, 1891774606, 1740186829, 1580472328, 1229917259,
25629   }, {
25630     0, 4022496062, 83218493, 3946298115, 166436986, 3861498692, 220098631, 3806075769,
25631     332873972, 4229245898, 388141257, 4175494135, 440197262, 4127099824, 516501683, 4044053389,
25632     665747944, 3362581206, 593187285, 3432594155, 776282514, 3246869164, 716239279, 3312622225,
25633     880394524, 3686509090, 814485793, 3746462239, 1033003366, 3528460888, 963096923, 3601193573,
25634     1331495888, 2694801646, 1269355501, 2758457555, 1186374570, 2843003028, 1111716759, 2910918825,
25635     1552565028, 3007850522, 1484755737, 3082680359, 1432478558, 3131279456, 1368666979, 3193329757,
25636     1760789048, 2268195078, 1812353541, 2210675003, 1628971586, 2396670332, 1710092927, 2318375233,
25637     2066006732, 2498144754, 2144408305, 2417195471, 1926193846, 2634877320, 1983558283, 2583222709,
25638     2662991776, 1903717534, 2588923805, 1972223139, 2538711002, 2022952164, 2477029351, 2087066841,
25639     2372749140, 1655647338, 2308478825, 1717238871, 2223433518, 1799654416, 2155034387, 1873894445,
25640     3105130056, 1456926070, 3185661557, 1378041163, 2969511474, 1597852940, 3020617231, 1539874097,
25641     2864957116, 1157737858, 2922780289, 1106542015, 2737333958, 1290407416, 2816325371, 1210047941,
25642     3521578096, 1042640718, 3574781005, 986759027, 3624707082, 936300340, 3707335735, 859512585,
25643     3257943172, 770846650, 3334837433, 688390023, 3420185854, 605654976, 3475911875, 552361981,
25644     4132013464, 428600998, 4072428965, 494812827, 4288816610, 274747100, 4216845791, 345349857,
25645     3852387692, 173846098, 3781891409, 245988975, 3967116566, 62328360, 3900749099, 121822741,
25646     3859089665, 164061759, 3807435068, 221426178, 4025395579, 2933317, 3944446278, 81334904,
25647     4124199413, 437265099, 4045904328, 518386422, 4231653775, 335250097, 4174133682, 386814604,
25648     3249244393, 778691543, 3311294676, 714879978, 3359647891, 662848429, 3434477742, 595039120,
25649     3531393053, 1035903779, 3599308832, 961245982, 3684132967, 877986649, 3747788890, 815846244,
25650     2841119441, 1184522735, 2913852140, 1114616274, 2696129195, 1332855189, 2756082326, 1266946472,
25651     3129952805, 1431118107, 3195705880, 1371074854, 3009735263, 1554415969, 3079748194, 1481855324,
25652     2398522169, 1630855175, 2315475716, 1707159610, 2266835779, 1759461501, 2213084030, 1814728768,
25653     2636237773, 1927520499, 2580814832, 1981182158, 2496293815, 2064121993, 2420095882, 2147340468,
25654     2025787041, 2541577631, 2085281436, 2475210146, 1901375195, 2660681189, 1973518054, 2590184920,
25655     1801997909, 2225743211, 1872600680, 2153772374, 1652813359, 2369881361, 1719025170, 2310296876,
25656     1594986313, 2966676599, 1541693300, 3022402634, 1459236659, 3107472397, 1376780046, 3184366640,
25657     1288097725, 2734990467, 1211309952, 2817619134, 1160605639, 2867791097, 1104723962, 2920993988,
25658     937561457, 3626001999, 857201996, 3704993394, 1040821515, 3519792693, 989625654, 3577615880,
25659     607473029, 3421972155, 549494200, 3473077894, 769584639, 3256649409, 690699714, 3337180924,
25660     273452185, 4287555495, 347692196, 4219156378, 430386403, 4133832669, 491977950, 4069562336,
25661     60542061, 3965298515, 124656720, 3903616878, 175139863, 3853649705, 243645482, 3779581716,
25662   }, {
25663     0, 3247366080, 1483520449, 2581751297, 2967040898, 1901571138, 3904227907, 691737987,
25664     3133399365, 2068659845, 3803142276, 589399876, 169513671, 3415493895, 1383475974, 2482566342,
25665     2935407819, 1870142219, 4137319690, 924099274, 506443593, 3751897225, 1178799752, 2278412616,
25666     339027342, 3585866318, 1280941135, 2379694991, 2766951948, 1700956620, 4236308429, 1024339981,
25667     2258407383, 1192382487, 3740284438, 528411094, 910556245, 4157285269, 1848198548, 2946996820,
25668     1012887186, 4258378066, 1681119059, 2780629139, 2357599504, 1292419792, 3572147409, 358906641,
25669     678054684, 3924071644, 1879503581, 2978491677, 2561882270, 1497229150, 3235873119, 22109855,
25670     2460592729, 1395094937, 3401913240, 189516888, 577821147, 3825075739, 2048679962, 3146956762,
25671     3595049455, 398902831, 2384764974, 1336573934, 1720805997, 2803873197, 1056822188, 4285729900,
25672     1821112490, 2902796138, 887570795, 4117339819, 3696397096, 500978920, 2218668777, 1169222953,
25673     2025774372, 3106931428, 550659301, 3780950821, 3362238118, 166293862, 2416645991, 1367722151,
25674     3262987361, 66315169, 2584839584, 1537170016, 1923370979, 3005911075, 717813282, 3947244002,
25675     1356109368, 2438613496, 146288633, 3375820857, 3759007162, 562248314, 3093388411, 2045739963,
25676     3927406461, 731490493, 2994458300, 1945440636, 1523451135, 2604718911, 44219710, 3274466046,
25677     4263662323, 1068272947, 2790189874, 1740649714, 1325080945, 2406874801, 379033776, 3608758128,
25678     1155642294, 2238671990, 479005303, 3708016055, 4097359924, 901128180, 2891217397, 1843045941,
25679     2011248031, 3060787807, 797805662, 3993195422, 3342353949, 112630237, 2673147868, 1591353372,
25680     3441611994, 212601626, 2504944923, 1421914843, 2113644376, 3161815192, 630660761, 3826893145,
25681     3642224980, 412692116, 2172340373, 1089836885, 1775141590, 2822790422, 832715543, 4029474007,
25682     1674842129, 2723860433, 1001957840, 4197873168, 3540870035, 310623315, 2338445906, 1257178514,
25683     4051548744, 821257608, 2836464521, 1755307081, 1101318602, 2150241802, 432566283, 3628511179,
25684     1270766349, 2318435533, 332587724, 3529260300, 4217841807, 988411727, 2735444302, 1652903566,
25685     1602977411, 2651169091, 132630338, 3328776322, 4015131905, 786223809, 3074340032, 1991273216,
25686     3846741958, 616972294, 3173262855, 2091579847, 1435626564, 2485072772, 234706309, 3430124101,
25687     2712218736, 1613231024, 4190475697, 944458353, 292577266, 3506339890, 1226630707, 2291284467,
25688     459984181, 3672380149, 1124496628, 2189994804, 2880683703, 1782407543, 4091479926, 844224694,
25689     257943739, 3469817723, 1462980986, 2529005242, 3213269817, 2114471161, 3890881272, 644152632,
25690     3046902270, 1947391550, 3991973951, 746483711, 88439420, 3301680572, 1563018173, 2628197501,
25691     657826727, 3871046759, 2136545894, 3201811878, 2548879397, 1449267173, 3481299428, 235845156,
25692     2650161890, 1551408418, 3315268387, 68429027, 758067552, 3970035360, 1967360161, 3033356129,
25693     2311284588, 1213053100, 3517963949, 270598509, 958010606, 4170500910, 1635167535, 2700636911,
25694     855672361, 4069415401, 1802256360, 2866995240, 2212099499, 1113008747, 3686091882, 440112042,
25695   }, {
25696     0, 2611301487, 3963330207, 2006897392, 50740095, 2560849680, 4013794784, 1956178319,
25697     101480190, 2645113489, 3929532513, 1905435662, 84561281, 2662269422, 3912356638, 1922342769,
25698     202960380, 2545787283, 3760419683, 2072395532, 253679235, 2495322860, 3810871324, 2021655667,
25699     169122562, 2444351341, 3861841309, 2106214898, 152215677, 2461527058, 3844685538, 2123133581,
25700     405920760, 2207553431, 4094313831, 1873742088, 456646791, 2157096168, 4144791064, 1823027831,
25701     507358470, 2241388905, 4060492697, 1772322806, 490444409, 2258557462, 4043311334, 1789215881,
25702     338245124, 2408348267, 4161972379, 1672996084, 388959611, 2357870868, 4212429796, 1622269835,
25703     304431354, 2306870421, 4263435877, 1706791434, 287538053, 2324051946, 4246267162, 1723705717,
25704     811841520, 2881944479, 3696765295, 1207788800, 862293135, 2831204576, 3747484176, 1157324415,
25705     913293582, 2915732833, 3662962577, 1106318334, 896137841, 2932651550, 3646055662, 1123494017,
25706     1014716940, 2816349795, 3493905555, 1273334012, 1065181555, 2765630748, 3544645612, 1222882179,
25707     980888818, 2714919069, 3595350637, 1307180546, 963712909, 2731826146, 3578431762, 1324336509,
25708     676490248, 3019317351, 3295277719, 1607253752, 726947703, 2968591128, 3345992168, 1556776327,
25709     777919222, 3053147801, 3261432937, 1505806342, 760750473, 3070062054, 3244539670, 1522987897,
25710     608862708, 3220163995, 3362856811, 1406423812, 659339915, 3169449700, 3413582868, 1355966587,
25711     575076106, 3118709605, 3464325525, 1440228858, 557894773, 3135602714, 3447411434, 1457397381,
25712     1623683040, 4217512847, 2365387135, 391757072, 1673614495, 4167309552, 2415577600, 341804655,
25713     1724586270, 4251866481, 2331019137, 290835438, 1707942497, 4268256782, 2314648830, 307490961,
25714     1826587164, 4152020595, 2162433155, 457265388, 1876539747, 4101829900, 2212636668, 407333779,
25715     1792275682, 4051089549, 2263378557, 491595282, 1775619997, 4067460082, 2246988034, 508239213,
25716     2029433880, 3813931127, 2496473735, 258500328, 2079362919, 3763716872, 2546668024, 208559511,
25717     2130363110, 3848244873, 2462145657, 157552662, 2113730969, 3864638966, 2445764358, 174205801,
25718     1961777636, 4014675339, 2564147067, 57707284, 2011718299, 3964481268, 2614361092, 7778411,
25719     1927425818, 3913769845, 2665066885, 92077546, 1910772837, 3930150922, 2648673018, 108709525,
25720     1352980496, 3405878399, 3164554895, 658115296, 1403183983, 3355946752, 3214507504, 607924639,
25721     1453895406, 3440239233, 3130208369, 557218846, 1437504913, 3456883198, 3113552654, 573589345,
25722     1555838444, 3340335491, 2961681267, 723707676, 1606028947, 3290383100, 3011612684, 673504355,
25723     1521500946, 3239382909, 3062619533, 758026722, 1505130605, 3256038402, 3045975794, 774417053,
25724     1217725416, 3543158663, 2762906999, 1057739032, 1267939479, 3493229816, 2812847624, 1007544935,
25725     1318679830, 3577493881, 2728586121, 956803046, 1302285929, 3594125830, 2711933174, 973184153,
25726     1150152212, 3743982203, 2830528651, 856898788, 1200346475, 3694041348, 2880457716, 806684571,
25727     1115789546, 3643069573, 2931426933, 891243034, 1099408277, 3659722746, 2914794762, 907637093,
25728   }, {
25729     0, 3717650821, 1616688459, 3184159950, 3233376918, 489665299, 2699419613, 2104690264,
25730     1510200173, 2274691816, 979330598, 3888758691, 2595928571, 1194090622, 4209380528, 661706037,
25731     3020400346, 1771143007, 3562738577, 164481556, 1958661196, 2837976521, 350386439, 3379863682,
25732     3993269687, 865250354, 2388181244, 1406015865, 784146209, 4079732388, 1323412074, 2474079215,
25733     3011398645, 1860735600, 3542286014, 246687547, 1942430051, 2924607718, 328963112, 3456978349,
25734     3917322392, 887832861, 2300653011, 1421341782, 700772878, 4099025803, 1234716485, 2483986112,
25735     125431087, 3673109674, 1730500708, 3132326369, 3351283641, 441867836, 2812031730, 2047535991,
25736     1568292418, 2163009479, 1025936137, 3769651852, 2646824148, 1079348561, 4255113631, 537475098,
25737     3180171691, 1612400686, 3721471200, 4717925, 2100624189, 2694980280, 493375094, 3237910515,
25738     3884860102, 974691139, 2278750093, 1514417672, 657926224, 4204917205, 1198234907, 2600289438,
25739     160053105, 3558665972, 1775665722, 3024116671, 3375586791, 346391650, 2842683564, 1962488105,
25740     1401545756, 2384412057, 869618007, 3997403346, 2469432970, 1319524111, 4083956673, 788193860,
25741     250862174, 3546612699, 1856990997, 3006903952, 3461001416, 333211981, 2920678787, 1937824774,
25742     1425017139, 2305216694, 883735672, 3912918525, 2487837605, 1239398944, 4095071982, 696455019,
25743     3136584836, 1734518017, 3668494799, 121507914, 2051872274, 2816200599, 437363545, 3347544796,
25744     3774328809, 1029797484, 2158697122, 1564328743, 542033279, 4258798842, 1074950196, 2642717105,
25745     2691310871, 2113731730, 3224801372, 497043929, 1624461185, 3175454212, 9435850, 3709412175,
25746     4201248378, 671035391, 2587181873, 1201904308, 986750188, 3880142185, 1519135143, 2266689570,
25747     342721485, 3388693064, 1949382278, 2846355203, 3570723163, 155332830, 3028835344, 1763607957,
25748     1315852448, 2482538789, 775087595, 4087626862, 2396469814, 1396827059, 4002123645, 857560824,
25749     320106210, 3464673127, 1934154665, 2933785132, 3551331444, 238804465, 3018961215, 1852270778,
25750     1226292623, 2491507722, 692783300, 4108177729, 2309936921, 1412959900, 3924976210, 879016919,
25751     2803091512, 2055541181, 3343875443, 450471158, 1739236014, 3124525867, 133568485, 3663777376,
25752     4245691221, 545702608, 2639048222, 1088059291, 1034514883, 3762268230, 1576387720, 2153979149,
25753     501724348, 3228659001, 2109407735, 2687359090, 3713981994, 13109167, 3171052385, 1620357860,
25754     1206151121, 2591211092, 666423962, 4197321503, 2271022407, 1523307714, 3875649548, 982999433,
25755     2850034278, 1953942499, 3384583981, 338329256, 1767471344, 3033506165, 151375291, 3566408766,
25756     4091789579, 779425934, 2478797888, 1311354309, 861580189, 4006375960, 1392910038, 2391852883,
25757     2929327945, 1930372812, 3469036034, 324244359, 1847629279, 3015068762, 243015828, 3555391761,
25758     4103744548, 688715169, 2496043375, 1229996266, 874727090, 3920994103, 1417671673, 2313759356,
25759     446585235, 3339223062, 2059594968, 2807313757, 3660002053, 129100416, 3128657486, 1743609803,
25760     1084066558, 2634765179, 549535669, 4250396208, 2149900392, 1571961325, 3765982499, 1039043750,
25761   }, {
25762     0, 2635063670, 3782132909, 2086741467, 430739227, 2225303149, 4173482934, 1707977408,
25763     861478454, 2924937024, 3526875803, 1329085421, 720736557, 3086643291, 3415954816, 1452586230,
25764     1722956908, 4223524122, 2279405761, 450042295, 2132718455, 3792785921, 2658170842, 58693292,
25765     1441473114, 3370435372, 3028674295, 696911745, 1279765825, 3511176247, 2905172460, 807831706,
25766     3445913816, 1349228974, 738901109, 2969918723, 3569940419, 1237784245, 900084590, 2829701656,
25767     4265436910, 1664255896, 525574723, 2187084597, 3885099509, 2057177219, 117386584, 2616249390,
25768     2882946228, 920233410, 1253605401, 3619119471, 2994391983, 796207833, 1393823490, 3457937012,
25769     2559531650, 92322804, 2044829231, 3840835417, 2166609305, 472659183, 1615663412, 4249022530,
25770     1102706673, 3702920839, 2698457948, 1037619754, 1477802218, 3306854812, 3111894087, 611605809,
25771     1927342535, 4025419953, 2475568490, 243387420, 1800169180, 4131620778, 2317525617, 388842247,
25772     655084445, 3120835307, 3328511792, 1533734470, 1051149446, 2745738736, 3754524715, 1120297309,
25773     340972971, 2304586973, 4114354438, 1748234352, 234773168, 2431761350, 3968900637, 1906278251,
25774     2363330345, 299003487, 1840466820, 4038896370, 2507210802, 142532932, 1948239007, 3910149609,
25775     3213136159, 579563625, 1592415666, 3286611140, 2787646980, 992477042, 1195825833, 3662232543,
25776     3933188933, 2002801203, 184645608, 2517538462, 4089658462, 1858919720, 313391347, 2409765253,
25777     3644239219, 1144605701, 945318366, 2773977256, 3231326824, 1570095902, 569697989, 3170568115,
25778     2205413346, 511446676, 1646078799, 4279421497, 2598330617, 131105167, 2075239508, 3871229218,
25779     2955604436, 757403810, 1363424633, 3427521551, 2844163791, 881434553, 1223211618, 3588709140,
25780     3854685070, 2026779384, 78583587, 2577462869, 4235025557, 1633861091, 486774840, 2148301134,
25781     3600338360, 1268198606, 938871061, 2868504675, 3476308643, 1379640277, 777684494, 3008718712,
25782     1310168890, 3541595724, 2943964055, 846639841, 1471879201, 3400857943, 3067468940, 735723002,
25783     2102298892, 3762382970, 2619362721, 19901655, 1692534295, 4193118049, 2240594618, 411247564,
25784     681945942, 3047836192, 3385552891, 1422167693, 822682701, 2886124859, 3496468704, 1298661782,
25785     469546336, 2264093718, 4203901389, 1738379451, 38812283, 2673859341, 3812556502, 2117148576,
25786     3268024339, 1606809957, 598006974, 3198893512, 3680933640, 1181316734, 973624229, 2802299603,
25787     4052944421, 1822222163, 285065864, 2381456382, 3896478014, 1966106696, 156323219, 2489232613,
25788     2759337087, 964150537, 1159127250, 3625517476, 3184831332, 551242258, 1555722185, 3249901247,
25789     2535537225, 170842943, 1984954084, 3946848146, 2391651666, 327308324, 1877176831, 4075589769,
25790     263086283, 2460058045, 4005602406, 1942963472, 369291216, 2332888742, 4151061373, 1784924683,
25791     1022852861, 2717425547, 3717839440, 1083595558, 626782694, 3092517008, 3291821387, 1497027645,
25792     1763466407, 4094934481, 2289211402, 360544636, 1890636732, 3988730570, 2447251217, 215086695,
25793     1514488465, 3343557607, 3140191804, 639919946, 1139395978, 3739626748, 2726758695, 1065936977,
25794   }, {
25795     0, 3120290792, 2827399569, 293431929, 2323408227, 864534155, 586863858, 2600537882,
25796     3481914503, 1987188591, 1729068310, 3740575486, 1173727716, 4228805132, 3983743093, 1418249117,
25797     1147313999, 4254680231, 3974377182, 1428157750, 3458136620, 2011505092, 1721256893, 3747844181,
25798     2347455432, 839944224, 594403929, 2593536433, 26687147, 3094146371, 2836498234, 283794642,
25799     2294627998, 826205558, 541298447, 2578994407, 45702141, 3141697557, 2856315500, 331624836,
25800     1196225049, 4273416689, 4023010184, 1446090848, 3442513786, 1959480466, 1706436331, 3696098563,
25801     3433538001, 1968994873, 1679888448, 3722103720, 1188807858, 4280295258, 3999102243, 1470541515,
25802     53374294, 3134568126, 2879970503, 307431215, 2303854645, 816436189, 567589284, 2553242188,
25803     3405478781, 1929420949, 1652411116, 3682996484, 1082596894, 4185703926, 3892424591, 1375368295,
25804     91404282, 3163122706, 2918450795, 336584067, 2400113305, 922028401, 663249672, 2658384096,
25805     2392450098, 929185754, 639587747, 2682555979, 82149713, 3172883129, 2892181696, 362343208,
25806     1091578037, 4176212829, 3918960932, 1349337804, 3412872662, 1922537022, 1676344391, 3658557359,
25807     1111377379, 4224032267, 3937989746, 1396912026, 3359776896, 1908013928, 1623494929, 3644803833,
25808     2377615716, 877417100, 623982837, 2630542109, 130804743, 3190831087, 2941083030, 381060734,
25809     106748588, 3215393092, 2933549885, 388083925, 2350956495, 903570471, 614862430, 2640172470,
25810     3386185259, 1882115523, 1632872378, 3634920530, 1135178568, 4199721120, 3945775833, 1389631793,
25811     1317531835, 4152109907, 3858841898, 1610259138, 3304822232, 2097172016, 1820140617, 3582394273,
25812     2165193788, 955639764, 696815021, 2423477829, 192043359, 2995356343, 2750736590, 437203750,
25813     182808564, 3005133852, 2724453989, 462947725, 2157513367, 962777471, 673168134, 2447663342,
25814     3312231283, 2090301595, 1844056802, 3557935370, 1326499344, 4142603768, 3885397889, 1584245865,
25815     3326266917, 2142836173, 1858371508, 3611272284, 1279175494, 4123357358, 3837270743, 1564721471,
25816     164299426, 2955991370, 2706223923, 414607579, 2209834945, 978107433, 724686416, 2462715320,
25817     2183156074, 1004243586, 715579643, 2472360723, 140260361, 2980573153, 2698675608, 421617264,
25818     1302961645, 4099032581, 3845074044, 1557460884, 3352688782, 2116952934, 1867729183, 3601371895,
25819     2222754758, 1032278062, 754596439, 2499928511, 234942117, 3086693709, 2793824052, 528319708,
25820     1274365761, 4061043881, 3816027856, 1518873912, 3246989858, 2020800970, 1762628531, 3505670235,
25821     3223196809, 2045103969, 1754834200, 3512958704, 1247965674, 4086934018, 3806642299, 1528765331,
25822     261609486, 3060532198, 2802936223, 518697591, 2246819181, 1007707781, 762121468, 2492913428,
25823     213497176, 3041029808, 2755593417, 499441441, 2261110843, 1061030867, 776167850, 2545465922,
25824     3274734047, 2060165687, 1807140942, 3528266662, 1229724860, 4038575956, 3788156205, 1479636677,
25825     1222322711, 4045468159, 3764231046, 1504067694, 3265744756, 2069664924, 1780612837, 3554288909,
25826     2270357136, 1051278712, 802445057, 2519698665, 221152243, 3033880603, 2779263586, 475261322,
25827   }, {
25828     0, 2926088593, 2275419491, 701019378, 3560000647, 2052709654, 1402038756, 4261017717,
25829     1930665807, 3715829470, 4105419308, 1524313021, 2804077512, 155861593, 545453739, 2397726522,
25830     3861331614, 1213181711, 1636244477, 3488582252, 840331801, 2625561480, 3048626042, 467584747,
25831     2503254481, 995897408, 311723186, 3170637091, 1090907478, 4016929991, 3332753461, 1758288292,
25832     390036349, 3109546732, 2426363422, 1056427919, 3272488954, 1835443819, 1152258713, 3938878216,
25833     1680663602, 3393484195, 3817652561, 1306808512, 2954733749, 510998820, 935169494, 2580880455,
25834     4044899811, 1601229938, 1991794816, 3637571857, 623446372, 2336332021, 2726898695, 216120726,
25835     2181814956, 744704829, 95158223, 2881711710, 1446680107, 4166125498, 3516576584, 2146575065,
25836     780072698, 2148951915, 2849952665, 129384968, 4199529085, 1411853292, 2112855838, 3548843663,
25837     1567451573, 4077254692, 3670887638, 1957027143, 2304517426, 657765539, 251396177, 2694091200,
25838     3361327204, 1714510325, 1341779207, 3784408214, 476611811, 2986349938, 2613617024, 899690513,
25839     3142211371, 354600634, 1021997640, 2458051545, 1870338988, 3239283261, 3906682575, 1186180958,
25840     960597383, 2536053782, 3202459876, 277428597, 3983589632, 1125666961, 1792074851, 3300423154,
25841     1246892744, 3829039961, 3455203243, 1671079482, 2657312335, 806080478, 432241452, 3081497277,
25842     3748049689, 1896751752, 1489409658, 4138600427, 190316446, 2772397583, 2365053693, 580864876,
25843     2893360214, 35503559, 735381813, 2243795108, 2017747153, 3593269568, 4293150130, 1368183843,
25844     1560145396, 4069882981, 3680356503, 1966430470, 2295112051, 648294626, 258769936, 2701399425,
25845     804156091, 2173100842, 2823706584, 103204425, 4225711676, 1438101421, 2088704863, 3524758222,
25846     3134903146, 347226875, 1031468553, 2467456920, 1860935661, 3229814396, 3914054286, 1193487135,
25847     3385412645, 1738661300, 1315531078, 3758225623, 502792354, 3012596019, 2589468097, 875607120,
25848     1271043721, 3853125400, 3429020650, 1644831355, 2683558414, 832261023, 408158061, 3057348348,
25849     953223622, 2528745559, 3211865253, 286899508, 3974120769, 1116263632, 1799381026, 3307794867,
25850     2917509143, 59586950, 709201268, 2217549029, 2043995280, 3619452161, 4269064691, 1344032866,
25851     3740677976, 1889445577, 1498812987, 4148069290, 180845535, 2762992206, 2372361916, 588238637,
25852     1921194766, 3706423967, 4112727661, 1531686908, 2796705673, 148555288, 554857194, 2407195515,
25853     26248257, 2952271312, 2251333922, 676868275, 3584149702, 2076793175, 1375858085, 4234771508,
25854     2493785488, 986493953, 319029491, 3178008930, 1083533591, 4009621638, 3342158964, 1767759333,
25855     3887577823, 1239362382, 1612160956, 3464433197, 864482904, 2649647049, 3022443323, 441336490,
25856     1706844275, 3419730402, 3793503504, 1282724993, 2978819316, 535149925, 908921239, 2554697734,
25857     380632892, 3100077741, 2433735263, 1063734222, 3265180603, 1828069930, 1161729752, 3948283721,
25858     2207997677, 770953084, 71007118, 2857626143, 1470763626, 4190274555, 3490330377, 2120394392,
25859     4035494306, 1591758899, 1999168705, 3644880208, 616140069, 2328960180, 2736367686, 225524183,
25860   },
25861 };
25862 
25863 static const uint8_t
25864 WUFFS_CRC32__IEEE_X86_SSE42_K1K2[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25865   212, 43, 68, 84, 1, 0, 0, 0,
25866   150, 21, 228, 198, 1, 0, 0, 0,
25867 };
25868 
25869 static const uint8_t
25870 WUFFS_CRC32__IEEE_X86_SSE42_K3K4[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25871   208, 151, 25, 117, 1, 0, 0, 0,
25872   158, 0, 170, 204, 0, 0, 0, 0,
25873 };
25874 
25875 static const uint8_t
25876 WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25877   36, 97, 205, 99, 1, 0, 0, 0,
25878   0, 0, 0, 0, 0, 0, 0, 0,
25879 };
25880 
25881 static const uint8_t
25882 WUFFS_CRC32__IEEE_X86_SSE42_PXMU[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25883   65, 6, 113, 219, 1, 0, 0, 0,
25884   65, 22, 1, 247, 1, 0, 0, 0,
25885 };
25886 
25887 // ---------------- Private Initializer Prototypes
25888 
25889 // ---------------- Private Function Prototypes
25890 
25891 static wuffs_base__empty_struct
25892 wuffs_crc32__ieee_hasher__up(
25893     wuffs_crc32__ieee_hasher* self,
25894     wuffs_base__slice_u8 a_x);
25895 
25896 static wuffs_base__empty_struct
25897 wuffs_crc32__ieee_hasher__up__choosy_default(
25898     wuffs_crc32__ieee_hasher* self,
25899     wuffs_base__slice_u8 a_x);
25900 
25901 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25902 static wuffs_base__empty_struct
25903 wuffs_crc32__ieee_hasher__up_arm_crc32(
25904     wuffs_crc32__ieee_hasher* self,
25905     wuffs_base__slice_u8 a_x);
25906 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25907 
25908 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25909 static wuffs_base__empty_struct
25910 wuffs_crc32__ieee_hasher__up_x86_avx2(
25911     wuffs_crc32__ieee_hasher* self,
25912     wuffs_base__slice_u8 a_x);
25913 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25914 
25915 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25916 static wuffs_base__empty_struct
25917 wuffs_crc32__ieee_hasher__up_x86_sse42(
25918     wuffs_crc32__ieee_hasher* self,
25919     wuffs_base__slice_u8 a_x);
25920 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25921 
25922 // ---------------- VTables
25923 
25924 const wuffs_base__hasher_u32__func_ptrs
25925 wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
25926   (wuffs_base__empty_struct(*)(void*,
25927       uint32_t,
25928       bool))(&wuffs_crc32__ieee_hasher__set_quirk_enabled),
25929   (uint32_t(*)(void*,
25930       wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32),
25931 };
25932 
25933 // ---------------- Initializer Implementations
25934 
25935 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)25936 wuffs_crc32__ieee_hasher__initialize(
25937     wuffs_crc32__ieee_hasher* self,
25938     size_t sizeof_star_self,
25939     uint64_t wuffs_version,
25940     uint32_t options){
25941   if (!self) {
25942     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
25943   }
25944   if (sizeof(*self) != sizeof_star_self) {
25945     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
25946   }
25947   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
25948       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
25949     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
25950   }
25951 
25952   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
25953     // The whole point of this if-check is to detect an uninitialized *self.
25954     // We disable the warning on GCC. Clang-5.0 does not have this warning.
25955 #if !defined(__clang__) && defined(__GNUC__)
25956 #pragma GCC diagnostic push
25957 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
25958 #endif
25959     if (self->private_impl.magic != 0) {
25960       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
25961     }
25962 #if !defined(__clang__) && defined(__GNUC__)
25963 #pragma GCC diagnostic pop
25964 #endif
25965   } else {
25966     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
25967       memset(self, 0, sizeof(*self));
25968       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
25969     } else {
25970       memset(&(self->private_impl), 0, sizeof(self->private_impl));
25971     }
25972   }
25973 
25974   self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default;
25975 
25976   self->private_impl.magic = WUFFS_BASE__MAGIC;
25977   self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
25978       wuffs_base__hasher_u32__vtable_name;
25979   self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
25980       (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32);
25981   return wuffs_base__make_status(NULL);
25982 }
25983 
25984 wuffs_crc32__ieee_hasher*
wuffs_crc32__ieee_hasher__alloc()25985 wuffs_crc32__ieee_hasher__alloc() {
25986   wuffs_crc32__ieee_hasher* x =
25987       (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
25988   if (!x) {
25989     return NULL;
25990   }
25991   if (wuffs_crc32__ieee_hasher__initialize(
25992       x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
25993     free(x);
25994     return NULL;
25995   }
25996   return x;
25997 }
25998 
25999 size_t
sizeof__wuffs_crc32__ieee_hasher()26000 sizeof__wuffs_crc32__ieee_hasher() {
26001   return sizeof(wuffs_crc32__ieee_hasher);
26002 }
26003 
26004 // ---------------- Function Implementations
26005 
26006 // -------- func crc32.ieee_hasher.set_quirk_enabled
26007 
26008 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)26009 wuffs_crc32__ieee_hasher__set_quirk_enabled(
26010     wuffs_crc32__ieee_hasher* self,
26011     uint32_t a_quirk,
26012     bool a_enabled) {
26013   return wuffs_base__make_empty_struct();
26014 }
26015 
26016 // -------- func crc32.ieee_hasher.update_u32
26017 
26018 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_crc32__ieee_hasher__update_u32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26019 wuffs_crc32__ieee_hasher__update_u32(
26020     wuffs_crc32__ieee_hasher* self,
26021     wuffs_base__slice_u8 a_x) {
26022   if (!self) {
26023     return 0;
26024   }
26025   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26026     return 0;
26027   }
26028 
26029   if (self->private_impl.f_state == 0) {
26030     self->private_impl.choosy_up = (
26031 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
26032         wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 :
26033 #endif
26034 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26035         wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_crc32__ieee_hasher__up_x86_avx2 :
26036 #endif
26037 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26038         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 :
26039 #endif
26040         self->private_impl.choosy_up);
26041   }
26042   wuffs_crc32__ieee_hasher__up(self, a_x);
26043   return self->private_impl.f_state;
26044 }
26045 
26046 // -------- func crc32.ieee_hasher.up
26047 
26048 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26049 wuffs_crc32__ieee_hasher__up(
26050     wuffs_crc32__ieee_hasher* self,
26051     wuffs_base__slice_u8 a_x) {
26052   return (*self->private_impl.choosy_up)(self, a_x);
26053 }
26054 
26055 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up__choosy_default(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26056 wuffs_crc32__ieee_hasher__up__choosy_default(
26057     wuffs_crc32__ieee_hasher* self,
26058     wuffs_base__slice_u8 a_x) {
26059   uint32_t v_s = 0;
26060   wuffs_base__slice_u8 v_p = {0};
26061 
26062   v_s = (4294967295 ^ self->private_impl.f_state);
26063   {
26064     wuffs_base__slice_u8 i_slice_p = a_x;
26065     v_p.ptr = i_slice_p.ptr;
26066     v_p.len = 16;
26067     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
26068     while (v_p.ptr < i_end0_p) {
26069       v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
26070           (((uint32_t)(v_p.ptr[1])) << 8) |
26071           (((uint32_t)(v_p.ptr[2])) << 16) |
26072           (((uint32_t)(v_p.ptr[3])) << 24));
26073       v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
26074           WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
26075           WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
26076           WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
26077           WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
26078           WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
26079           WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
26080           WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
26081           WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
26082           WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
26083           WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
26084           WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
26085           WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
26086           WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
26087           WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
26088           WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
26089       v_p.ptr += 16;
26090       v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
26091           (((uint32_t)(v_p.ptr[1])) << 8) |
26092           (((uint32_t)(v_p.ptr[2])) << 16) |
26093           (((uint32_t)(v_p.ptr[3])) << 24));
26094       v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
26095           WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
26096           WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
26097           WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
26098           WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
26099           WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
26100           WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
26101           WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
26102           WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
26103           WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
26104           WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
26105           WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
26106           WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
26107           WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
26108           WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
26109           WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
26110       v_p.ptr += 16;
26111     }
26112     v_p.len = 16;
26113     uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16);
26114     while (v_p.ptr < i_end1_p) {
26115       v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
26116           (((uint32_t)(v_p.ptr[1])) << 8) |
26117           (((uint32_t)(v_p.ptr[2])) << 16) |
26118           (((uint32_t)(v_p.ptr[3])) << 24));
26119       v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
26120           WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
26121           WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
26122           WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
26123           WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
26124           WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
26125           WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
26126           WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
26127           WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
26128           WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
26129           WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
26130           WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
26131           WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
26132           WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
26133           WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
26134           WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
26135       v_p.ptr += 16;
26136     }
26137     v_p.len = 1;
26138     uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
26139     while (v_p.ptr < i_end2_p) {
26140       v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26141       v_p.ptr += 1;
26142     }
26143     v_p.len = 0;
26144   }
26145   self->private_impl.f_state = (4294967295 ^ v_s);
26146   return wuffs_base__make_empty_struct();
26147 }
26148 
26149 // ‼ WUFFS MULTI-FILE SECTION +arm_crc32
26150 // -------- func crc32.ieee_hasher.up_arm_crc32
26151 
26152 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
26153 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_arm_crc32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26154 wuffs_crc32__ieee_hasher__up_arm_crc32(
26155     wuffs_crc32__ieee_hasher* self,
26156     wuffs_base__slice_u8 a_x) {
26157   wuffs_base__slice_u8 v_p = {0};
26158   uint32_t v_s = 0;
26159 
26160   v_s = (4294967295 ^ self->private_impl.f_state);
26161   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
26162     v_s = __crc32b(v_s, a_x.ptr[0]);
26163     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
26164   }
26165   {
26166     wuffs_base__slice_u8 i_slice_p = a_x;
26167     v_p.ptr = i_slice_p.ptr;
26168     v_p.len = 8;
26169     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128);
26170     while (v_p.ptr < i_end0_p) {
26171       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26172       v_p.ptr += 8;
26173       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26174       v_p.ptr += 8;
26175       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26176       v_p.ptr += 8;
26177       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26178       v_p.ptr += 8;
26179       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26180       v_p.ptr += 8;
26181       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26182       v_p.ptr += 8;
26183       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26184       v_p.ptr += 8;
26185       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26186       v_p.ptr += 8;
26187       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26188       v_p.ptr += 8;
26189       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26190       v_p.ptr += 8;
26191       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26192       v_p.ptr += 8;
26193       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26194       v_p.ptr += 8;
26195       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26196       v_p.ptr += 8;
26197       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26198       v_p.ptr += 8;
26199       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26200       v_p.ptr += 8;
26201       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26202       v_p.ptr += 8;
26203     }
26204     v_p.len = 8;
26205     uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
26206     while (v_p.ptr < i_end1_p) {
26207       v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26208       v_p.ptr += 8;
26209     }
26210     v_p.len = 1;
26211     uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
26212     while (v_p.ptr < i_end2_p) {
26213       v_s = __crc32b(v_s, v_p.ptr[0]);
26214       v_p.ptr += 1;
26215     }
26216     v_p.len = 0;
26217   }
26218   self->private_impl.f_state = (4294967295 ^ v_s);
26219   return wuffs_base__make_empty_struct();
26220 }
26221 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
26222 // ‼ WUFFS MULTI-FILE SECTION -arm_crc32
26223 
26224 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
26225 // -------- func crc32.ieee_hasher.up_x86_avx2
26226 
26227 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26228 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
26229 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_avx2(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26230 wuffs_crc32__ieee_hasher__up_x86_avx2(
26231     wuffs_crc32__ieee_hasher* self,
26232     wuffs_base__slice_u8 a_x) {
26233   uint32_t v_s = 0;
26234   wuffs_base__slice_u8 v_p = {0};
26235   __m128i v_k = {0};
26236   __m128i v_x0 = {0};
26237   __m128i v_x1 = {0};
26238   __m128i v_x2 = {0};
26239   __m128i v_x3 = {0};
26240   __m128i v_y0 = {0};
26241   __m128i v_y1 = {0};
26242   __m128i v_y2 = {0};
26243   __m128i v_y3 = {0};
26244   uint64_t v_tail_index = 0;
26245 
26246   v_s = (4294967295 ^ self->private_impl.f_state);
26247   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
26248     v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ a_x.ptr[0])] ^ (v_s >> 8));
26249     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
26250   }
26251   if (((uint64_t)(a_x.len)) < 64) {
26252     {
26253       wuffs_base__slice_u8 i_slice_p = a_x;
26254       v_p.ptr = i_slice_p.ptr;
26255       v_p.len = 1;
26256       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26257       while (v_p.ptr < i_end0_p) {
26258         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26259         v_p.ptr += 1;
26260       }
26261       v_p.len = 0;
26262     }
26263     self->private_impl.f_state = (4294967295 ^ v_s);
26264     return wuffs_base__make_empty_struct();
26265   }
26266   v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0));
26267   v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16));
26268   v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32));
26269   v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48));
26270   v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
26271   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
26272   {
26273     wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64);
26274     v_p.ptr = i_slice_p.ptr;
26275     v_p.len = 64;
26276     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
26277     while (v_p.ptr < i_end0_p) {
26278       v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26279       v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26280       v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0));
26281       v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0));
26282       v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26283       v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17));
26284       v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17));
26285       v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17));
26286       v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0)));
26287       v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16)));
26288       v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32)));
26289       v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48)));
26290       v_p.ptr += 64;
26291     }
26292     v_p.len = 0;
26293   }
26294   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
26295   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26296   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26297   v_x0 = _mm_xor_si128(v_x0, v_x1);
26298   v_x0 = _mm_xor_si128(v_x0, v_y0);
26299   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26300   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26301   v_x0 = _mm_xor_si128(v_x0, v_x2);
26302   v_x0 = _mm_xor_si128(v_x0, v_y0);
26303   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26304   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26305   v_x0 = _mm_xor_si128(v_x0, v_x3);
26306   v_x0 = _mm_xor_si128(v_x0, v_y0);
26307   v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16));
26308   v_x2 = _mm_set_epi32((int32_t)(0), (int32_t)(4294967295), (int32_t)(0), (int32_t)(4294967295));
26309   v_x0 = _mm_srli_si128(v_x0, (int32_t)(8));
26310   v_x0 = _mm_xor_si128(v_x0, v_x1);
26311   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
26312   v_x1 = _mm_srli_si128(v_x0, (int32_t)(4));
26313   v_x0 = _mm_and_si128(v_x0, v_x2);
26314   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26315   v_x0 = _mm_xor_si128(v_x0, v_x1);
26316   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
26317   v_x1 = _mm_and_si128(v_x0, v_x2);
26318   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16));
26319   v_x1 = _mm_and_si128(v_x1, v_x2);
26320   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26321   v_x0 = _mm_xor_si128(v_x0, v_x1);
26322   v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1))));
26323   v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
26324   if (v_tail_index < ((uint64_t)(a_x.len))) {
26325     {
26326       wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
26327       v_p.ptr = i_slice_p.ptr;
26328       v_p.len = 1;
26329       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26330       while (v_p.ptr < i_end0_p) {
26331         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26332         v_p.ptr += 1;
26333       }
26334       v_p.len = 0;
26335     }
26336   }
26337   self->private_impl.f_state = (4294967295 ^ v_s);
26338   return wuffs_base__make_empty_struct();
26339 }
26340 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26341 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
26342 
26343 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
26344 // -------- func crc32.ieee_hasher.up_x86_sse42
26345 
26346 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26347 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
26348 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_sse42(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26349 wuffs_crc32__ieee_hasher__up_x86_sse42(
26350     wuffs_crc32__ieee_hasher* self,
26351     wuffs_base__slice_u8 a_x) {
26352   uint32_t v_s = 0;
26353   wuffs_base__slice_u8 v_p = {0};
26354   __m128i v_k = {0};
26355   __m128i v_x0 = {0};
26356   __m128i v_x1 = {0};
26357   __m128i v_x2 = {0};
26358   __m128i v_x3 = {0};
26359   __m128i v_y0 = {0};
26360   __m128i v_y1 = {0};
26361   __m128i v_y2 = {0};
26362   __m128i v_y3 = {0};
26363   uint64_t v_tail_index = 0;
26364 
26365   v_s = (4294967295 ^ self->private_impl.f_state);
26366   while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
26367     v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ a_x.ptr[0])] ^ (v_s >> 8));
26368     a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
26369   }
26370   if (((uint64_t)(a_x.len)) < 64) {
26371     {
26372       wuffs_base__slice_u8 i_slice_p = a_x;
26373       v_p.ptr = i_slice_p.ptr;
26374       v_p.len = 1;
26375       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26376       while (v_p.ptr < i_end0_p) {
26377         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26378         v_p.ptr += 1;
26379       }
26380       v_p.len = 0;
26381     }
26382     self->private_impl.f_state = (4294967295 ^ v_s);
26383     return wuffs_base__make_empty_struct();
26384   }
26385   v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0));
26386   v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16));
26387   v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32));
26388   v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48));
26389   v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
26390   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
26391   {
26392     wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64);
26393     v_p.ptr = i_slice_p.ptr;
26394     v_p.len = 64;
26395     uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
26396     while (v_p.ptr < i_end0_p) {
26397       v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26398       v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26399       v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0));
26400       v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0));
26401       v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26402       v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17));
26403       v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17));
26404       v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17));
26405       v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0)));
26406       v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16)));
26407       v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32)));
26408       v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48)));
26409       v_p.ptr += 64;
26410     }
26411     v_p.len = 0;
26412   }
26413   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
26414   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26415   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26416   v_x0 = _mm_xor_si128(v_x0, v_x1);
26417   v_x0 = _mm_xor_si128(v_x0, v_y0);
26418   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26419   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26420   v_x0 = _mm_xor_si128(v_x0, v_x2);
26421   v_x0 = _mm_xor_si128(v_x0, v_y0);
26422   v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26423   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26424   v_x0 = _mm_xor_si128(v_x0, v_x3);
26425   v_x0 = _mm_xor_si128(v_x0, v_y0);
26426   v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16));
26427   v_x2 = _mm_set_epi32((int32_t)(0), (int32_t)(4294967295), (int32_t)(0), (int32_t)(4294967295));
26428   v_x0 = _mm_srli_si128(v_x0, (int32_t)(8));
26429   v_x0 = _mm_xor_si128(v_x0, v_x1);
26430   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
26431   v_x1 = _mm_srli_si128(v_x0, (int32_t)(4));
26432   v_x0 = _mm_and_si128(v_x0, v_x2);
26433   v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26434   v_x0 = _mm_xor_si128(v_x0, v_x1);
26435   v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
26436   v_x1 = _mm_and_si128(v_x0, v_x2);
26437   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16));
26438   v_x1 = _mm_and_si128(v_x1, v_x2);
26439   v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26440   v_x0 = _mm_xor_si128(v_x0, v_x1);
26441   v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1))));
26442   v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
26443   if (v_tail_index < ((uint64_t)(a_x.len))) {
26444     {
26445       wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
26446       v_p.ptr = i_slice_p.ptr;
26447       v_p.len = 1;
26448       uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26449       while (v_p.ptr < i_end0_p) {
26450         v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26451         v_p.ptr += 1;
26452       }
26453       v_p.len = 0;
26454     }
26455   }
26456   self->private_impl.f_state = (4294967295 ^ v_s);
26457   return wuffs_base__make_empty_struct();
26458 }
26459 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26460 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
26461 
26462 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
26463 
26464 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
26465 
26466 // ---------------- Status Codes Implementations
26467 
26468 const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)";
26469 const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)";
26470 const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count";
26471 const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition";
26472 const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code";
26473 const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length";
26474 const char wuffs_deflate__error__bad_block[] = "#deflate: bad block";
26475 const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance";
26476 const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count";
26477 const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count";
26478 const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length";
26479 const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code";
26480 const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes";
26481 const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state";
26482 const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O";
26483 const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance";
26484 const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits";
26485 
26486 // ---------------- Private Consts
26487 
26488 static const uint8_t
26489 WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = {
26490   16, 17, 18, 0, 8, 7, 9, 6,
26491   10, 5, 11, 4, 12, 3, 13, 2,
26492   14, 1, 15,
26493 };
26494 
26495 static const uint8_t
26496 WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
26497   0, 128, 64, 192, 32, 160, 96, 224,
26498   16, 144, 80, 208, 48, 176, 112, 240,
26499   8, 136, 72, 200, 40, 168, 104, 232,
26500   24, 152, 88, 216, 56, 184, 120, 248,
26501   4, 132, 68, 196, 36, 164, 100, 228,
26502   20, 148, 84, 212, 52, 180, 116, 244,
26503   12, 140, 76, 204, 44, 172, 108, 236,
26504   28, 156, 92, 220, 60, 188, 124, 252,
26505   2, 130, 66, 194, 34, 162, 98, 226,
26506   18, 146, 82, 210, 50, 178, 114, 242,
26507   10, 138, 74, 202, 42, 170, 106, 234,
26508   26, 154, 90, 218, 58, 186, 122, 250,
26509   6, 134, 70, 198, 38, 166, 102, 230,
26510   22, 150, 86, 214, 54, 182, 118, 246,
26511   14, 142, 78, 206, 46, 174, 110, 238,
26512   30, 158, 94, 222, 62, 190, 126, 254,
26513   1, 129, 65, 193, 33, 161, 97, 225,
26514   17, 145, 81, 209, 49, 177, 113, 241,
26515   9, 137, 73, 201, 41, 169, 105, 233,
26516   25, 153, 89, 217, 57, 185, 121, 249,
26517   5, 133, 69, 197, 37, 165, 101, 229,
26518   21, 149, 85, 213, 53, 181, 117, 245,
26519   13, 141, 77, 205, 45, 173, 109, 237,
26520   29, 157, 93, 221, 61, 189, 125, 253,
26521   3, 131, 67, 195, 35, 163, 99, 227,
26522   19, 147, 83, 211, 51, 179, 115, 243,
26523   11, 139, 75, 203, 43, 171, 107, 235,
26524   27, 155, 91, 219, 59, 187, 123, 251,
26525   7, 135, 71, 199, 39, 167, 103, 231,
26526   23, 151, 87, 215, 55, 183, 119, 247,
26527   15, 143, 79, 207, 47, 175, 111, 239,
26528   31, 159, 95, 223, 63, 191, 127, 255,
26529 };
26530 
26531 static const uint32_t
26532 WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
26533   1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104, 1073743360, 1073743616,
26534   1073743888, 1073744400, 1073744912, 1073745424, 1073745952, 1073746976, 1073748000, 1073749024,
26535   1073750064, 1073752112, 1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560,
26536   1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728, 134217728, 134217728,
26537 };
26538 
26539 static const uint32_t
26540 WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
26541   1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376, 1073743904, 1073744928,
26542   1073745968, 1073748016, 1073750080, 1073754176, 1073758288, 1073766480, 1073774688, 1073791072,
26543   1073807472, 1073840240, 1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416,
26544   1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488, 134217728, 134217728,
26545 };
26546 
26547 #define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024
26548 
26549 #define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023
26550 
26551 // ---------------- Private Initializer Prototypes
26552 
26553 // ---------------- Private Function Prototypes
26554 
26555 static wuffs_base__status
26556 wuffs_deflate__decoder__decode_blocks(
26557     wuffs_deflate__decoder* self,
26558     wuffs_base__io_buffer* a_dst,
26559     wuffs_base__io_buffer* a_src);
26560 
26561 static wuffs_base__status
26562 wuffs_deflate__decoder__decode_uncompressed(
26563     wuffs_deflate__decoder* self,
26564     wuffs_base__io_buffer* a_dst,
26565     wuffs_base__io_buffer* a_src);
26566 
26567 static wuffs_base__status
26568 wuffs_deflate__decoder__init_fixed_huffman(
26569     wuffs_deflate__decoder* self);
26570 
26571 static wuffs_base__status
26572 wuffs_deflate__decoder__init_dynamic_huffman(
26573     wuffs_deflate__decoder* self,
26574     wuffs_base__io_buffer* a_src);
26575 
26576 static wuffs_base__status
26577 wuffs_deflate__decoder__init_huff(
26578     wuffs_deflate__decoder* self,
26579     uint32_t a_which,
26580     uint32_t a_n_codes0,
26581     uint32_t a_n_codes1,
26582     uint32_t a_base_symbol);
26583 
26584 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26585 static wuffs_base__status
26586 wuffs_deflate__decoder__decode_huffman_bmi2(
26587     wuffs_deflate__decoder* self,
26588     wuffs_base__io_buffer* a_dst,
26589     wuffs_base__io_buffer* a_src);
26590 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26591 
26592 static wuffs_base__status
26593 wuffs_deflate__decoder__decode_huffman_fast32(
26594     wuffs_deflate__decoder* self,
26595     wuffs_base__io_buffer* a_dst,
26596     wuffs_base__io_buffer* a_src);
26597 
26598 static wuffs_base__status
26599 wuffs_deflate__decoder__decode_huffman_fast64(
26600     wuffs_deflate__decoder* self,
26601     wuffs_base__io_buffer* a_dst,
26602     wuffs_base__io_buffer* a_src);
26603 
26604 static wuffs_base__status
26605 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
26606     wuffs_deflate__decoder* self,
26607     wuffs_base__io_buffer* a_dst,
26608     wuffs_base__io_buffer* a_src);
26609 
26610 static wuffs_base__status
26611 wuffs_deflate__decoder__decode_huffman_slow(
26612     wuffs_deflate__decoder* self,
26613     wuffs_base__io_buffer* a_dst,
26614     wuffs_base__io_buffer* a_src);
26615 
26616 // ---------------- VTables
26617 
26618 const wuffs_base__io_transformer__func_ptrs
26619 wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = {
26620   (wuffs_base__empty_struct(*)(void*,
26621       uint32_t,
26622       bool))(&wuffs_deflate__decoder__set_quirk_enabled),
26623   (wuffs_base__status(*)(void*,
26624       wuffs_base__io_buffer*,
26625       wuffs_base__io_buffer*,
26626       wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io),
26627   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len),
26628 };
26629 
26630 // ---------------- Initializer Implementations
26631 
26632 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)26633 wuffs_deflate__decoder__initialize(
26634     wuffs_deflate__decoder* self,
26635     size_t sizeof_star_self,
26636     uint64_t wuffs_version,
26637     uint32_t options){
26638   if (!self) {
26639     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
26640   }
26641   if (sizeof(*self) != sizeof_star_self) {
26642     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
26643   }
26644   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
26645       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
26646     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
26647   }
26648 
26649   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
26650     // The whole point of this if-check is to detect an uninitialized *self.
26651     // We disable the warning on GCC. Clang-5.0 does not have this warning.
26652 #if !defined(__clang__) && defined(__GNUC__)
26653 #pragma GCC diagnostic push
26654 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
26655 #endif
26656     if (self->private_impl.magic != 0) {
26657       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
26658     }
26659 #if !defined(__clang__) && defined(__GNUC__)
26660 #pragma GCC diagnostic pop
26661 #endif
26662   } else {
26663     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
26664       memset(self, 0, sizeof(*self));
26665       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
26666     } else {
26667       memset(&(self->private_impl), 0, sizeof(self->private_impl));
26668     }
26669   }
26670 
26671   self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default;
26672 
26673   self->private_impl.magic = WUFFS_BASE__MAGIC;
26674   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
26675       wuffs_base__io_transformer__vtable_name;
26676   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
26677       (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer);
26678   return wuffs_base__make_status(NULL);
26679 }
26680 
26681 wuffs_deflate__decoder*
wuffs_deflate__decoder__alloc()26682 wuffs_deflate__decoder__alloc() {
26683   wuffs_deflate__decoder* x =
26684       (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
26685   if (!x) {
26686     return NULL;
26687   }
26688   if (wuffs_deflate__decoder__initialize(
26689       x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
26690     free(x);
26691     return NULL;
26692   }
26693   return x;
26694 }
26695 
26696 size_t
sizeof__wuffs_deflate__decoder()26697 sizeof__wuffs_deflate__decoder() {
26698   return sizeof(wuffs_deflate__decoder);
26699 }
26700 
26701 // ---------------- Function Implementations
26702 
26703 // -------- func deflate.decoder.add_history
26704 
26705 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_deflate__decoder__add_history(wuffs_deflate__decoder * self,wuffs_base__slice_u8 a_hist)26706 wuffs_deflate__decoder__add_history(
26707     wuffs_deflate__decoder* self,
26708     wuffs_base__slice_u8 a_hist) {
26709   if (!self) {
26710     return wuffs_base__make_empty_struct();
26711   }
26712   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26713     return wuffs_base__make_empty_struct();
26714   }
26715 
26716   wuffs_base__slice_u8 v_s = {0};
26717   uint64_t v_n_copied = 0;
26718   uint32_t v_already_full = 0;
26719 
26720   v_s = a_hist;
26721   if (((uint64_t)(v_s.len)) >= 32768) {
26722     v_s = wuffs_base__slice_u8__suffix(v_s, 32768);
26723     wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
26724     self->private_impl.f_history_index = 32768;
26725   } else {
26726     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);
26727     if (v_n_copied < ((uint64_t)(v_s.len))) {
26728       v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied);
26729       v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
26730       self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767))) + 32768);
26731     } else {
26732       v_already_full = 0;
26733       if (self->private_impl.f_history_index >= 32768) {
26734         v_already_full = 32768;
26735       }
26736       self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767) + ((uint32_t)((v_n_copied & 32767))) + v_already_full);
26737     }
26738   }
26739   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));
26740   return wuffs_base__make_empty_struct();
26741 }
26742 
26743 // -------- func deflate.decoder.set_quirk_enabled
26744 
26745 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)26746 wuffs_deflate__decoder__set_quirk_enabled(
26747     wuffs_deflate__decoder* self,
26748     uint32_t a_quirk,
26749     bool a_enabled) {
26750   return wuffs_base__make_empty_struct();
26751 }
26752 
26753 // -------- func deflate.decoder.workbuf_len
26754 
26755 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder * self)26756 wuffs_deflate__decoder__workbuf_len(
26757     const wuffs_deflate__decoder* self) {
26758   if (!self) {
26759     return wuffs_base__utility__empty_range_ii_u64();
26760   }
26761   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
26762       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
26763     return wuffs_base__utility__empty_range_ii_u64();
26764   }
26765 
26766   return wuffs_base__utility__make_range_ii_u64(1, 1);
26767 }
26768 
26769 // -------- func deflate.decoder.transform_io
26770 
26771 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)26772 wuffs_deflate__decoder__transform_io(
26773     wuffs_deflate__decoder* self,
26774     wuffs_base__io_buffer* a_dst,
26775     wuffs_base__io_buffer* a_src,
26776     wuffs_base__slice_u8 a_workbuf) {
26777   if (!self) {
26778     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
26779   }
26780   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26781     return wuffs_base__make_status(
26782         (self->private_impl.magic == WUFFS_BASE__DISABLED)
26783         ? wuffs_base__error__disabled_by_previous_error
26784         : wuffs_base__error__initialize_not_called);
26785   }
26786   if (!a_dst || !a_src) {
26787     self->private_impl.magic = WUFFS_BASE__DISABLED;
26788     return wuffs_base__make_status(wuffs_base__error__bad_argument);
26789   }
26790   if ((self->private_impl.active_coroutine != 0) &&
26791       (self->private_impl.active_coroutine != 1)) {
26792     self->private_impl.magic = WUFFS_BASE__DISABLED;
26793     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
26794   }
26795   self->private_impl.active_coroutine = 0;
26796   wuffs_base__status status = wuffs_base__make_status(NULL);
26797 
26798   uint64_t v_mark = 0;
26799   wuffs_base__status v_status = wuffs_base__make_status(NULL);
26800 
26801   uint8_t* iop_a_dst = NULL;
26802   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26803   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26804   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26805   if (a_dst) {
26806     io0_a_dst = a_dst->data.ptr;
26807     io1_a_dst = io0_a_dst + a_dst->meta.wi;
26808     iop_a_dst = io1_a_dst;
26809     io2_a_dst = io0_a_dst + a_dst->data.len;
26810     if (a_dst->meta.closed) {
26811       io2_a_dst = iop_a_dst;
26812     }
26813   }
26814 
26815   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
26816   switch (coro_susp_point) {
26817     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26818 
26819     self->private_impl.choosy_decode_huffman_fast64 = (
26820 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26821         wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 :
26822 #endif
26823         self->private_impl.choosy_decode_huffman_fast64);
26824     while (true) {
26825       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
26826       {
26827         if (a_dst) {
26828           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
26829         }
26830         wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
26831         v_status = t_0;
26832         if (a_dst) {
26833           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
26834         }
26835       }
26836       if ( ! wuffs_base__status__is_suspension(&v_status)) {
26837         status = v_status;
26838         if (wuffs_base__status__is_error(&status)) {
26839           goto exit;
26840         } else if (wuffs_base__status__is_suspension(&status)) {
26841           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
26842           goto exit;
26843         }
26844         goto ok;
26845       }
26846       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))));
26847       wuffs_deflate__decoder__add_history(self, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
26848       status = v_status;
26849       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
26850     }
26851 
26852     ok:
26853     self->private_impl.p_transform_io[0] = 0;
26854     goto exit;
26855   }
26856 
26857   goto suspend;
26858   suspend:
26859   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
26860   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
26861 
26862   goto exit;
26863   exit:
26864   if (a_dst) {
26865     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
26866   }
26867 
26868   if (wuffs_base__status__is_error(&status)) {
26869     self->private_impl.magic = WUFFS_BASE__DISABLED;
26870   }
26871   return status;
26872 }
26873 
26874 // -------- func deflate.decoder.decode_blocks
26875 
26876 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)26877 wuffs_deflate__decoder__decode_blocks(
26878     wuffs_deflate__decoder* self,
26879     wuffs_base__io_buffer* a_dst,
26880     wuffs_base__io_buffer* a_src) {
26881   wuffs_base__status status = wuffs_base__make_status(NULL);
26882 
26883   uint32_t v_final = 0;
26884   uint32_t v_b0 = 0;
26885   uint32_t v_type = 0;
26886   wuffs_base__status v_status = wuffs_base__make_status(NULL);
26887 
26888   const uint8_t* iop_a_src = NULL;
26889   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26890   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26891   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26892   if (a_src) {
26893     io0_a_src = a_src->data.ptr;
26894     io1_a_src = io0_a_src + a_src->meta.ri;
26895     iop_a_src = io1_a_src;
26896     io2_a_src = io0_a_src + a_src->meta.wi;
26897   }
26898 
26899   uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0];
26900   if (coro_susp_point) {
26901     v_final = self->private_data.s_decode_blocks[0].v_final;
26902   }
26903   switch (coro_susp_point) {
26904     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26905 
26906     label__outer__continue:;
26907     while (v_final == 0) {
26908       while (self->private_impl.f_n_bits < 3) {
26909         {
26910           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
26911           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26912             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26913             goto suspend;
26914           }
26915           uint32_t t_0 = *iop_a_src++;
26916           v_b0 = t_0;
26917         }
26918         self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3));
26919         self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3) + 8);
26920       }
26921       v_final = (self->private_impl.f_bits & 1);
26922       v_type = ((self->private_impl.f_bits >> 1) & 3);
26923       self->private_impl.f_bits >>= 3;
26924       self->private_impl.f_n_bits -= 3;
26925       if (v_type == 0) {
26926         if (a_src) {
26927           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26928         }
26929         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
26930         status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
26931         if (a_src) {
26932           iop_a_src = a_src->data.ptr + a_src->meta.ri;
26933         }
26934         if (status.repr) {
26935           goto suspend;
26936         }
26937         goto label__outer__continue;
26938       } else if (v_type == 1) {
26939         v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
26940         if ( ! wuffs_base__status__is_ok(&v_status)) {
26941           status = v_status;
26942           if (wuffs_base__status__is_error(&status)) {
26943             goto exit;
26944           } else if (wuffs_base__status__is_suspension(&status)) {
26945             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
26946             goto exit;
26947           }
26948           goto ok;
26949         }
26950       } else if (v_type == 2) {
26951         if (a_src) {
26952           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26953         }
26954         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
26955         status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
26956         if (a_src) {
26957           iop_a_src = a_src->data.ptr + a_src->meta.ri;
26958         }
26959         if (status.repr) {
26960           goto suspend;
26961         }
26962       } else {
26963         status = wuffs_base__make_status(wuffs_deflate__error__bad_block);
26964         goto exit;
26965       }
26966       self->private_impl.f_end_of_block = false;
26967       while (true) {
26968         if (sizeof(void*) == 4) {
26969           if (a_src) {
26970             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26971           }
26972           v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src);
26973           if (a_src) {
26974             iop_a_src = a_src->data.ptr + a_src->meta.ri;
26975           }
26976         } else {
26977           if (a_src) {
26978             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26979           }
26980           v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src);
26981           if (a_src) {
26982             iop_a_src = a_src->data.ptr + a_src->meta.ri;
26983           }
26984         }
26985         if (wuffs_base__status__is_error(&v_status)) {
26986           status = v_status;
26987           goto exit;
26988         }
26989         if (self->private_impl.f_end_of_block) {
26990           goto label__outer__continue;
26991         }
26992         if (a_src) {
26993           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26994         }
26995         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
26996         status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
26997         if (a_src) {
26998           iop_a_src = a_src->data.ptr + a_src->meta.ri;
26999         }
27000         if (status.repr) {
27001           goto suspend;
27002         }
27003         if (self->private_impl.f_end_of_block) {
27004           goto label__outer__continue;
27005         }
27006       }
27007     }
27008 
27009     ok:
27010     self->private_impl.p_decode_blocks[0] = 0;
27011     goto exit;
27012   }
27013 
27014   goto suspend;
27015   suspend:
27016   self->private_impl.p_decode_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
27017   self->private_data.s_decode_blocks[0].v_final = v_final;
27018 
27019   goto exit;
27020   exit:
27021   if (a_src) {
27022     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27023   }
27024 
27025   return status;
27026 }
27027 
27028 // -------- func deflate.decoder.decode_uncompressed
27029 
27030 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)27031 wuffs_deflate__decoder__decode_uncompressed(
27032     wuffs_deflate__decoder* self,
27033     wuffs_base__io_buffer* a_dst,
27034     wuffs_base__io_buffer* a_src) {
27035   wuffs_base__status status = wuffs_base__make_status(NULL);
27036 
27037   uint32_t v_length = 0;
27038   uint32_t v_n_copied = 0;
27039 
27040   uint8_t* iop_a_dst = NULL;
27041   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27042   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27043   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27044   if (a_dst) {
27045     io0_a_dst = a_dst->data.ptr;
27046     io1_a_dst = io0_a_dst + a_dst->meta.wi;
27047     iop_a_dst = io1_a_dst;
27048     io2_a_dst = io0_a_dst + a_dst->data.len;
27049     if (a_dst->meta.closed) {
27050       io2_a_dst = iop_a_dst;
27051     }
27052   }
27053   const uint8_t* iop_a_src = NULL;
27054   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27055   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27056   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27057   if (a_src) {
27058     io0_a_src = a_src->data.ptr;
27059     io1_a_src = io0_a_src + a_src->meta.ri;
27060     iop_a_src = io1_a_src;
27061     io2_a_src = io0_a_src + a_src->meta.wi;
27062   }
27063 
27064   uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0];
27065   if (coro_susp_point) {
27066     v_length = self->private_data.s_decode_uncompressed[0].v_length;
27067   }
27068   switch (coro_susp_point) {
27069     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
27070 
27071     if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27072       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27073       goto exit;
27074     }
27075     self->private_impl.f_n_bits = 0;
27076     self->private_impl.f_bits = 0;
27077     {
27078       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
27079       uint32_t t_0;
27080       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
27081         t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
27082         iop_a_src += 4;
27083       } else {
27084         self->private_data.s_decode_uncompressed[0].scratch = 0;
27085         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
27086         while (true) {
27087           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27088             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27089             goto suspend;
27090           }
27091           uint64_t* scratch = &self->private_data.s_decode_uncompressed[0].scratch;
27092           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
27093           *scratch <<= 8;
27094           *scratch >>= 8;
27095           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
27096           if (num_bits_0 == 24) {
27097             t_0 = ((uint32_t)(*scratch));
27098             break;
27099           }
27100           num_bits_0 += 8;
27101           *scratch |= ((uint64_t)(num_bits_0)) << 56;
27102         }
27103       }
27104       v_length = t_0;
27105     }
27106     if ((((v_length) & 0xFFFF) + ((v_length) >> (32 - (16)))) != 65535) {
27107       status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length);
27108       goto exit;
27109     }
27110     v_length = ((v_length) & 0xFFFF);
27111     while (true) {
27112       v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_reader(
27113           &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
27114       if (v_length <= v_n_copied) {
27115         status = wuffs_base__make_status(NULL);
27116         goto ok;
27117       }
27118       v_length -= v_n_copied;
27119       if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0) {
27120         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
27121         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
27122       } else {
27123         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27124         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
27125       }
27126     }
27127 
27128     ok:
27129     self->private_impl.p_decode_uncompressed[0] = 0;
27130     goto exit;
27131   }
27132 
27133   goto suspend;
27134   suspend:
27135   self->private_impl.p_decode_uncompressed[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
27136   self->private_data.s_decode_uncompressed[0].v_length = v_length;
27137 
27138   goto exit;
27139   exit:
27140   if (a_dst) {
27141     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
27142   }
27143   if (a_src) {
27144     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27145   }
27146 
27147   return status;
27148 }
27149 
27150 // -------- func deflate.decoder.init_fixed_huffman
27151 
27152 static wuffs_base__status
wuffs_deflate__decoder__init_fixed_huffman(wuffs_deflate__decoder * self)27153 wuffs_deflate__decoder__init_fixed_huffman(
27154     wuffs_deflate__decoder* self) {
27155   uint32_t v_i = 0;
27156   wuffs_base__status v_status = wuffs_base__make_status(NULL);
27157 
27158   while (v_i < 144) {
27159     self->private_data.f_code_lengths[v_i] = 8;
27160     v_i += 1;
27161   }
27162   while (v_i < 256) {
27163     self->private_data.f_code_lengths[v_i] = 9;
27164     v_i += 1;
27165   }
27166   while (v_i < 280) {
27167     self->private_data.f_code_lengths[v_i] = 7;
27168     v_i += 1;
27169   }
27170   while (v_i < 288) {
27171     self->private_data.f_code_lengths[v_i] = 8;
27172     v_i += 1;
27173   }
27174   while (v_i < 320) {
27175     self->private_data.f_code_lengths[v_i] = 5;
27176     v_i += 1;
27177   }
27178   v_status = wuffs_deflate__decoder__init_huff(self,
27179       0,
27180       0,
27181       288,
27182       257);
27183   if (wuffs_base__status__is_error(&v_status)) {
27184     return v_status;
27185   }
27186   v_status = wuffs_deflate__decoder__init_huff(self,
27187       1,
27188       288,
27189       320,
27190       0);
27191   if (wuffs_base__status__is_error(&v_status)) {
27192     return v_status;
27193   }
27194   return wuffs_base__make_status(NULL);
27195 }
27196 
27197 // -------- func deflate.decoder.init_dynamic_huffman
27198 
27199 static wuffs_base__status
wuffs_deflate__decoder__init_dynamic_huffman(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_src)27200 wuffs_deflate__decoder__init_dynamic_huffman(
27201     wuffs_deflate__decoder* self,
27202     wuffs_base__io_buffer* a_src) {
27203   wuffs_base__status status = wuffs_base__make_status(NULL);
27204 
27205   uint32_t v_bits = 0;
27206   uint32_t v_n_bits = 0;
27207   uint32_t v_b0 = 0;
27208   uint32_t v_n_lit = 0;
27209   uint32_t v_n_dist = 0;
27210   uint32_t v_n_clen = 0;
27211   uint32_t v_i = 0;
27212   uint32_t v_b1 = 0;
27213   wuffs_base__status v_status = wuffs_base__make_status(NULL);
27214   uint32_t v_mask = 0;
27215   uint32_t v_table_entry = 0;
27216   uint32_t v_table_entry_n_bits = 0;
27217   uint32_t v_b2 = 0;
27218   uint32_t v_n_extra_bits = 0;
27219   uint8_t v_rep_symbol = 0;
27220   uint32_t v_rep_count = 0;
27221   uint32_t v_b3 = 0;
27222 
27223   const uint8_t* iop_a_src = NULL;
27224   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27225   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27226   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27227   if (a_src) {
27228     io0_a_src = a_src->data.ptr;
27229     io1_a_src = io0_a_src + a_src->meta.ri;
27230     iop_a_src = io1_a_src;
27231     io2_a_src = io0_a_src + a_src->meta.wi;
27232   }
27233 
27234   uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0];
27235   if (coro_susp_point) {
27236     v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits;
27237     v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits;
27238     v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit;
27239     v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist;
27240     v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen;
27241     v_i = self->private_data.s_init_dynamic_huffman[0].v_i;
27242     v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask;
27243     v_table_entry = self->private_data.s_init_dynamic_huffman[0].v_table_entry;
27244     v_n_extra_bits = self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits;
27245     v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol;
27246     v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count;
27247   }
27248   switch (coro_susp_point) {
27249     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
27250 
27251     v_bits = self->private_impl.f_bits;
27252     v_n_bits = self->private_impl.f_n_bits;
27253     while (v_n_bits < 14) {
27254       {
27255         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
27256         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27257           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27258           goto suspend;
27259         }
27260         uint32_t t_0 = *iop_a_src++;
27261         v_b0 = t_0;
27262       }
27263       v_bits |= (v_b0 << v_n_bits);
27264       v_n_bits += 8;
27265     }
27266     v_n_lit = (((v_bits) & 0x1F) + 257);
27267     if (v_n_lit > 286) {
27268       status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count);
27269       goto exit;
27270     }
27271     v_bits >>= 5;
27272     v_n_dist = (((v_bits) & 0x1F) + 1);
27273     if (v_n_dist > 30) {
27274       status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count);
27275       goto exit;
27276     }
27277     v_bits >>= 5;
27278     v_n_clen = (((v_bits) & 0xF) + 4);
27279     v_bits >>= 4;
27280     v_n_bits -= 14;
27281     v_i = 0;
27282     while (v_i < v_n_clen) {
27283       while (v_n_bits < 3) {
27284         {
27285           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
27286           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27287             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27288             goto suspend;
27289           }
27290           uint32_t t_1 = *iop_a_src++;
27291           v_b1 = t_1;
27292         }
27293         v_bits |= (v_b1 << v_n_bits);
27294         v_n_bits += 8;
27295       }
27296       self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7)));
27297       v_bits >>= 3;
27298       v_n_bits -= 3;
27299       v_i += 1;
27300     }
27301     while (v_i < 19) {
27302       self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0;
27303       v_i += 1;
27304     }
27305     v_status = wuffs_deflate__decoder__init_huff(self,
27306         0,
27307         0,
27308         19,
27309         4095);
27310     if (wuffs_base__status__is_error(&v_status)) {
27311       status = v_status;
27312       goto exit;
27313     }
27314     v_mask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27315     v_i = 0;
27316     label__0__continue:;
27317     while (v_i < (v_n_lit + v_n_dist)) {
27318       while (true) {
27319         v_table_entry = self->private_data.f_huffs[0][(v_bits & v_mask)];
27320         v_table_entry_n_bits = (v_table_entry & 15);
27321         if (v_n_bits >= v_table_entry_n_bits) {
27322           v_bits >>= v_table_entry_n_bits;
27323           v_n_bits -= v_table_entry_n_bits;
27324           goto label__1__break;
27325         }
27326         {
27327           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
27328           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27329             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27330             goto suspend;
27331           }
27332           uint32_t t_2 = *iop_a_src++;
27333           v_b2 = t_2;
27334         }
27335         v_bits |= (v_b2 << v_n_bits);
27336         v_n_bits += 8;
27337       }
27338       label__1__break:;
27339       if ((v_table_entry >> 24) != 128) {
27340         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27341         goto exit;
27342       }
27343       v_table_entry = ((v_table_entry >> 8) & 255);
27344       if (v_table_entry < 16) {
27345         self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
27346         v_i += 1;
27347         goto label__0__continue;
27348       }
27349       v_n_extra_bits = 0;
27350       v_rep_symbol = 0;
27351       v_rep_count = 0;
27352       if (v_table_entry == 16) {
27353         v_n_extra_bits = 2;
27354         if (v_i <= 0) {
27355           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition);
27356           goto exit;
27357         }
27358         v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1)] & 15);
27359         v_rep_count = 3;
27360       } else if (v_table_entry == 17) {
27361         v_n_extra_bits = 3;
27362         v_rep_symbol = 0;
27363         v_rep_count = 3;
27364       } else if (v_table_entry == 18) {
27365         v_n_extra_bits = 7;
27366         v_rep_symbol = 0;
27367         v_rep_count = 11;
27368       } else {
27369         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27370         goto exit;
27371       }
27372       while (v_n_bits < v_n_extra_bits) {
27373         {
27374           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
27375           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27376             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27377             goto suspend;
27378           }
27379           uint32_t t_3 = *iop_a_src++;
27380           v_b3 = t_3;
27381         }
27382         v_bits |= (v_b3 << v_n_bits);
27383         v_n_bits += 8;
27384       }
27385       v_rep_count += ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits));
27386       v_bits >>= v_n_extra_bits;
27387       v_n_bits -= v_n_extra_bits;
27388       while (v_rep_count > 0) {
27389         if (v_i >= (v_n_lit + v_n_dist)) {
27390           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
27391           goto exit;
27392         }
27393         self->private_data.f_code_lengths[v_i] = v_rep_symbol;
27394         v_i += 1;
27395         v_rep_count -= 1;
27396       }
27397     }
27398     if (v_i != (v_n_lit + v_n_dist)) {
27399       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
27400       goto exit;
27401     }
27402     if (self->private_data.f_code_lengths[256] == 0) {
27403       status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code);
27404       goto exit;
27405     }
27406     v_status = wuffs_deflate__decoder__init_huff(self,
27407         0,
27408         0,
27409         v_n_lit,
27410         257);
27411     if (wuffs_base__status__is_error(&v_status)) {
27412       status = v_status;
27413       goto exit;
27414     }
27415     v_status = wuffs_deflate__decoder__init_huff(self,
27416         1,
27417         v_n_lit,
27418         (v_n_lit + v_n_dist),
27419         0);
27420     if (wuffs_base__status__is_error(&v_status)) {
27421       status = v_status;
27422       goto exit;
27423     }
27424     self->private_impl.f_bits = v_bits;
27425     self->private_impl.f_n_bits = v_n_bits;
27426 
27427     goto ok;
27428     ok:
27429     self->private_impl.p_init_dynamic_huffman[0] = 0;
27430     goto exit;
27431   }
27432 
27433   goto suspend;
27434   suspend:
27435   self->private_impl.p_init_dynamic_huffman[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
27436   self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits;
27437   self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits;
27438   self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit;
27439   self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist;
27440   self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen;
27441   self->private_data.s_init_dynamic_huffman[0].v_i = v_i;
27442   self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask;
27443   self->private_data.s_init_dynamic_huffman[0].v_table_entry = v_table_entry;
27444   self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits;
27445   self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol;
27446   self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count;
27447 
27448   goto exit;
27449   exit:
27450   if (a_src) {
27451     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27452   }
27453 
27454   return status;
27455 }
27456 
27457 // -------- func deflate.decoder.init_huff
27458 
27459 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)27460 wuffs_deflate__decoder__init_huff(
27461     wuffs_deflate__decoder* self,
27462     uint32_t a_which,
27463     uint32_t a_n_codes0,
27464     uint32_t a_n_codes1,
27465     uint32_t a_base_symbol) {
27466   uint16_t v_counts[16] = {0};
27467   uint32_t v_i = 0;
27468   uint32_t v_remaining = 0;
27469   uint16_t v_offsets[16] = {0};
27470   uint32_t v_n_symbols = 0;
27471   uint32_t v_count = 0;
27472   uint16_t v_symbols[320] = {0};
27473   uint32_t v_min_cl = 0;
27474   uint32_t v_max_cl = 0;
27475   uint32_t v_initial_high_bits = 0;
27476   uint32_t v_prev_cl = 0;
27477   uint32_t v_prev_redirect_key = 0;
27478   uint32_t v_top = 0;
27479   uint32_t v_next_top = 0;
27480   uint32_t v_code = 0;
27481   uint32_t v_key = 0;
27482   uint32_t v_value = 0;
27483   uint32_t v_cl = 0;
27484   uint32_t v_redirect_key = 0;
27485   uint32_t v_j = 0;
27486   uint32_t v_reversed_key = 0;
27487   uint32_t v_symbol = 0;
27488   uint32_t v_high_bits = 0;
27489   uint32_t v_delta = 0;
27490 
27491   v_i = a_n_codes0;
27492   while (v_i < a_n_codes1) {
27493     if (v_counts[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
27494       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27495     }
27496 #if defined(__GNUC__)
27497 #pragma GCC diagnostic push
27498 #pragma GCC diagnostic ignored "-Wconversion"
27499 #endif
27500     v_counts[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
27501 #if defined(__GNUC__)
27502 #pragma GCC diagnostic pop
27503 #endif
27504     v_i += 1;
27505   }
27506   if ((((uint32_t)(v_counts[0])) + a_n_codes0) == a_n_codes1) {
27507     return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
27508   }
27509   v_remaining = 1;
27510   v_i = 1;
27511   while (v_i <= 15) {
27512     if (v_remaining > 1073741824) {
27513       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27514     }
27515     v_remaining <<= 1;
27516     if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
27517       return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed);
27518     }
27519     v_remaining -= ((uint32_t)(v_counts[v_i]));
27520     v_i += 1;
27521   }
27522   if (v_remaining != 0) {
27523     if ((a_which == 1) && (v_counts[1] == 1) && ((((uint32_t)(v_counts[0])) + a_n_codes0 + 1) == a_n_codes1)) {
27524       v_i = 0;
27525       while (v_i <= 29) {
27526         if (self->private_data.f_code_lengths[(a_n_codes0 + v_i)] == 1) {
27527           self->private_impl.f_n_huffs_bits[1] = 1;
27528           self->private_data.f_huffs[1][0] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[v_i] | 1);
27529           self->private_data.f_huffs[1][1] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31] | 1);
27530           return wuffs_base__make_status(NULL);
27531         }
27532         v_i += 1;
27533       }
27534     }
27535     return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
27536   }
27537   v_i = 1;
27538   while (v_i <= 15) {
27539     v_offsets[v_i] = ((uint16_t)(v_n_symbols));
27540     v_count = ((uint32_t)(v_counts[v_i]));
27541     if (v_n_symbols > (320 - v_count)) {
27542       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27543     }
27544     v_n_symbols = (v_n_symbols + v_count);
27545     v_i += 1;
27546   }
27547   if (v_n_symbols > 288) {
27548     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27549   }
27550   v_i = a_n_codes0;
27551   while (v_i < a_n_codes1) {
27552     if (v_i < a_n_codes0) {
27553       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27554     }
27555     if (self->private_data.f_code_lengths[v_i] != 0) {
27556       if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
27557         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27558       }
27559       v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15)]] = ((uint16_t)((v_i - a_n_codes0)));
27560 #if defined(__GNUC__)
27561 #pragma GCC diagnostic push
27562 #pragma GCC diagnostic ignored "-Wconversion"
27563 #endif
27564       v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
27565 #if defined(__GNUC__)
27566 #pragma GCC diagnostic pop
27567 #endif
27568     }
27569     v_i += 1;
27570   }
27571   v_min_cl = 1;
27572   while (true) {
27573     if (v_counts[v_min_cl] != 0) {
27574       goto label__0__break;
27575     }
27576     if (v_min_cl >= 9) {
27577       return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length);
27578     }
27579     v_min_cl += 1;
27580   }
27581   label__0__break:;
27582   v_max_cl = 15;
27583   while (true) {
27584     if (v_counts[v_max_cl] != 0) {
27585       goto label__1__break;
27586     }
27587     if (v_max_cl <= 1) {
27588       return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
27589     }
27590     v_max_cl -= 1;
27591   }
27592   label__1__break:;
27593   if (v_max_cl <= 9) {
27594     self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
27595   } else {
27596     self->private_impl.f_n_huffs_bits[a_which] = 9;
27597   }
27598   v_i = 0;
27599   if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15])))) {
27600     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27601   }
27602   if ((a_n_codes0 + ((uint32_t)(v_symbols[0]))) >= 320) {
27603     return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27604   }
27605   v_initial_high_bits = 512;
27606   if (v_max_cl < 9) {
27607     v_initial_high_bits = (((uint32_t)(1)) << v_max_cl);
27608   }
27609   v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0])))] & 15)));
27610   v_prev_redirect_key = 4294967295;
27611   v_top = 0;
27612   v_next_top = 512;
27613   v_code = 0;
27614   v_key = 0;
27615   v_value = 0;
27616   while (true) {
27617     if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320) {
27618       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27619     }
27620     v_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15)));
27621     if (v_cl > v_prev_cl) {
27622       v_code <<= (v_cl - v_prev_cl);
27623       if (v_code >= 32768) {
27624         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27625       }
27626     }
27627     v_prev_cl = v_cl;
27628     v_key = v_code;
27629     if (v_cl > 9) {
27630       v_cl -= 9;
27631       v_redirect_key = ((v_key >> v_cl) & 511);
27632       v_key = ((v_key) & WUFFS_BASE__LOW_BITS_MASK__U32(v_cl));
27633       if (v_prev_redirect_key != v_redirect_key) {
27634         v_prev_redirect_key = v_redirect_key;
27635         v_remaining = (((uint32_t)(1)) << v_cl);
27636         v_j = v_prev_cl;
27637         while (v_j <= 15) {
27638           if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
27639             goto label__2__break;
27640           }
27641           v_remaining -= ((uint32_t)(v_counts[v_j]));
27642           if (v_remaining > 1073741824) {
27643             return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27644           }
27645           v_remaining <<= 1;
27646           v_j += 1;
27647         }
27648         label__2__break:;
27649         if ((v_j <= 9) || (15 < v_j)) {
27650           return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27651         }
27652         v_j -= 9;
27653         v_initial_high_bits = (((uint32_t)(1)) << v_j);
27654         v_top = v_next_top;
27655         if ((v_top + (((uint32_t)(1)) << v_j)) > 1024) {
27656           return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27657         }
27658         v_next_top = (v_top + (((uint32_t)(1)) << v_j));
27659         v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1)])) | ((v_redirect_key & 1) << 8));
27660         self->private_data.f_huffs[a_which][v_redirect_key] = (268435465 | (v_top << 8) | (v_j << 4));
27661       }
27662     }
27663     if ((v_key >= 512) || (v_counts[v_prev_cl] <= 0)) {
27664       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27665     }
27666 #if defined(__GNUC__)
27667 #pragma GCC diagnostic push
27668 #pragma GCC diagnostic ignored "-Wconversion"
27669 #endif
27670     v_counts[v_prev_cl] -= 1;
27671 #if defined(__GNUC__)
27672 #pragma GCC diagnostic pop
27673 #endif
27674     v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1)])) | ((v_key & 1) << 8));
27675     v_reversed_key >>= (9 - v_cl);
27676     v_symbol = ((uint32_t)(v_symbols[v_i]));
27677     if (v_symbol == 256) {
27678       v_value = (536870912 | v_cl);
27679     } else if ((v_symbol < 256) && (a_which == 0)) {
27680       v_value = (2147483648 | (v_symbol << 8) | v_cl);
27681     } else if (v_symbol >= a_base_symbol) {
27682       v_symbol -= a_base_symbol;
27683       if (a_which == 0) {
27684         v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
27685       } else {
27686         v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
27687       }
27688     } else {
27689       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27690     }
27691     v_high_bits = v_initial_high_bits;
27692     v_delta = (((uint32_t)(1)) << v_cl);
27693     while (v_high_bits >= v_delta) {
27694       v_high_bits -= v_delta;
27695       if ((v_top + ((v_high_bits | v_reversed_key) & 511)) >= 1024) {
27696         return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27697       }
27698       self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511))] = v_value;
27699     }
27700     v_i += 1;
27701     if (v_i >= v_n_symbols) {
27702       goto label__3__break;
27703     }
27704     v_code += 1;
27705     if (v_code >= 32768) {
27706       return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27707     }
27708   }
27709   label__3__break:;
27710   return wuffs_base__make_status(NULL);
27711 }
27712 
27713 // ‼ WUFFS MULTI-FILE SECTION +x86_bmi2
27714 // -------- func deflate.decoder.decode_huffman_bmi2
27715 
27716 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27717 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2")
27718 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)27719 wuffs_deflate__decoder__decode_huffman_bmi2(
27720     wuffs_deflate__decoder* self,
27721     wuffs_base__io_buffer* a_dst,
27722     wuffs_base__io_buffer* a_src) {
27723   wuffs_base__status status = wuffs_base__make_status(NULL);
27724 
27725   uint64_t v_bits = 0;
27726   uint32_t v_n_bits = 0;
27727   uint32_t v_table_entry = 0;
27728   uint32_t v_table_entry_n_bits = 0;
27729   uint64_t v_lmask = 0;
27730   uint64_t v_dmask = 0;
27731   uint32_t v_redir_top = 0;
27732   uint32_t v_redir_mask = 0;
27733   uint32_t v_length = 0;
27734   uint32_t v_dist_minus_1 = 0;
27735   uint32_t v_hlen = 0;
27736   uint32_t v_hdist = 0;
27737   uint32_t v_hdist_adjustment = 0;
27738 
27739   uint8_t* iop_a_dst = NULL;
27740   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27741   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27742   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27743   if (a_dst) {
27744     io0_a_dst = a_dst->data.ptr;
27745     io1_a_dst = io0_a_dst + a_dst->meta.wi;
27746     iop_a_dst = io1_a_dst;
27747     io2_a_dst = io0_a_dst + a_dst->data.len;
27748     if (a_dst->meta.closed) {
27749       io2_a_dst = iop_a_dst;
27750     }
27751   }
27752   const uint8_t* iop_a_src = NULL;
27753   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27754   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27755   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27756   if (a_src) {
27757     io0_a_src = a_src->data.ptr;
27758     io1_a_src = io0_a_src + a_src->meta.ri;
27759     iop_a_src = io1_a_src;
27760     io2_a_src = io0_a_src + a_src->meta.wi;
27761   }
27762 
27763   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27764     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27765     goto exit;
27766   }
27767   v_bits = ((uint64_t)(self->private_impl.f_bits));
27768   v_n_bits = self->private_impl.f_n_bits;
27769   v_lmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27770   v_dmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27771   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
27772     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
27773     goto exit;
27774   }
27775   v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
27776   label__loop__continue:;
27777   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8)) {
27778     v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63)));
27779     iop_a_src += ((63 - (v_n_bits & 63)) >> 3);
27780     v_n_bits |= 56;
27781     v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
27782     v_table_entry_n_bits = (v_table_entry & 15);
27783     v_bits >>= v_table_entry_n_bits;
27784     v_n_bits -= v_table_entry_n_bits;
27785     if ((v_table_entry >> 31) != 0) {
27786       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27787       goto label__loop__continue;
27788     } else if ((v_table_entry >> 30) != 0) {
27789     } else if ((v_table_entry >> 29) != 0) {
27790       self->private_impl.f_end_of_block = true;
27791       goto label__loop__break;
27792     } else if ((v_table_entry >> 28) != 0) {
27793       v_redir_top = ((v_table_entry >> 8) & 65535);
27794       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27795       v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27796       v_table_entry_n_bits = (v_table_entry & 15);
27797       v_bits >>= v_table_entry_n_bits;
27798       v_n_bits -= v_table_entry_n_bits;
27799       if ((v_table_entry >> 31) != 0) {
27800         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27801         goto label__loop__continue;
27802       } else if ((v_table_entry >> 30) != 0) {
27803       } else if ((v_table_entry >> 29) != 0) {
27804         self->private_impl.f_end_of_block = true;
27805         goto label__loop__break;
27806       } else if ((v_table_entry >> 28) != 0) {
27807         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27808         goto exit;
27809       } else if ((v_table_entry >> 27) != 0) {
27810         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27811         goto exit;
27812       } else {
27813         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27814         goto exit;
27815       }
27816     } else if ((v_table_entry >> 27) != 0) {
27817       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27818       goto exit;
27819     } else {
27820       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27821       goto exit;
27822     }
27823     v_length = (((v_table_entry >> 8) & 255) + 3);
27824     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27825     if (v_table_entry_n_bits > 0) {
27826       v_length = (((v_length + 253 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255) + 3);
27827       v_bits >>= v_table_entry_n_bits;
27828       v_n_bits -= v_table_entry_n_bits;
27829     }
27830     v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
27831     v_table_entry_n_bits = (v_table_entry & 15);
27832     v_bits >>= v_table_entry_n_bits;
27833     v_n_bits -= v_table_entry_n_bits;
27834     if ((v_table_entry >> 28) == 1) {
27835       v_redir_top = ((v_table_entry >> 8) & 65535);
27836       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27837       v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27838       v_table_entry_n_bits = (v_table_entry & 15);
27839       v_bits >>= v_table_entry_n_bits;
27840       v_n_bits -= v_table_entry_n_bits;
27841     }
27842     if ((v_table_entry >> 24) != 64) {
27843       if ((v_table_entry >> 24) == 8) {
27844         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27845         goto exit;
27846       }
27847       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27848       goto exit;
27849     }
27850     v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
27851     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27852     v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767);
27853     v_bits >>= v_table_entry_n_bits;
27854     v_n_bits -= v_table_entry_n_bits;
27855     while (true) {
27856       if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
27857         v_hlen = 0;
27858         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
27859         if (v_length > v_hdist) {
27860           v_length -= v_hdist;
27861           v_hlen = v_hdist;
27862         } else {
27863           v_hlen = v_length;
27864           v_length = 0;
27865         }
27866         v_hdist += v_hdist_adjustment;
27867         if (self->private_impl.f_history_index < v_hdist) {
27868           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
27869           goto exit;
27870         }
27871         wuffs_base__io_writer__limited_copy_u32_from_slice(
27872             &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), ((self->private_impl.f_history_index - v_hdist) & 32767)));
27873         if (v_length == 0) {
27874           goto label__loop__continue;
27875         }
27876         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)))) {
27877           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
27878           goto exit;
27879         }
27880       }
27881       if ((v_dist_minus_1 + 1) >= 8) {
27882         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
27883             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27884       } else if ((v_dist_minus_1 + 1) == 1) {
27885         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
27886             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27887       } else {
27888         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
27889             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27890       }
27891       goto label__0__break;
27892     }
27893     label__0__break:;
27894   }
27895   label__loop__break:;
27896   if (v_n_bits > 63) {
27897     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27898     goto exit;
27899   }
27900   while (v_n_bits >= 8) {
27901     v_n_bits -= 8;
27902     if (iop_a_src > io1_a_src) {
27903       iop_a_src--;
27904     } else {
27905       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
27906       goto exit;
27907     }
27908   }
27909   self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1)) << v_n_bits) - 1))));
27910   self->private_impl.f_n_bits = v_n_bits;
27911   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
27912     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27913     goto exit;
27914   }
27915   goto exit;
27916   exit:
27917   if (a_dst) {
27918     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
27919   }
27920   if (a_src) {
27921     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27922   }
27923 
27924   return status;
27925 }
27926 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27927 // ‼ WUFFS MULTI-FILE SECTION -x86_bmi2
27928 
27929 // -------- func deflate.decoder.decode_huffman_fast32
27930 
27931 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)27932 wuffs_deflate__decoder__decode_huffman_fast32(
27933     wuffs_deflate__decoder* self,
27934     wuffs_base__io_buffer* a_dst,
27935     wuffs_base__io_buffer* a_src) {
27936   wuffs_base__status status = wuffs_base__make_status(NULL);
27937 
27938   uint32_t v_bits = 0;
27939   uint32_t v_n_bits = 0;
27940   uint32_t v_table_entry = 0;
27941   uint32_t v_table_entry_n_bits = 0;
27942   uint32_t v_lmask = 0;
27943   uint32_t v_dmask = 0;
27944   uint32_t v_redir_top = 0;
27945   uint32_t v_redir_mask = 0;
27946   uint32_t v_length = 0;
27947   uint32_t v_dist_minus_1 = 0;
27948   uint32_t v_hlen = 0;
27949   uint32_t v_hdist = 0;
27950   uint32_t v_hdist_adjustment = 0;
27951 
27952   uint8_t* iop_a_dst = NULL;
27953   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27954   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27955   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27956   if (a_dst) {
27957     io0_a_dst = a_dst->data.ptr;
27958     io1_a_dst = io0_a_dst + a_dst->meta.wi;
27959     iop_a_dst = io1_a_dst;
27960     io2_a_dst = io0_a_dst + a_dst->data.len;
27961     if (a_dst->meta.closed) {
27962       io2_a_dst = iop_a_dst;
27963     }
27964   }
27965   const uint8_t* iop_a_src = NULL;
27966   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27967   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27968   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27969   if (a_src) {
27970     io0_a_src = a_src->data.ptr;
27971     io1_a_src = io0_a_src + a_src->meta.ri;
27972     iop_a_src = io1_a_src;
27973     io2_a_src = io0_a_src + a_src->meta.wi;
27974   }
27975 
27976   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27977     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27978     goto exit;
27979   }
27980   v_bits = self->private_impl.f_bits;
27981   v_n_bits = self->private_impl.f_n_bits;
27982   v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27983   v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27984   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
27985     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
27986     goto exit;
27987   }
27988   v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
27989   label__loop__continue:;
27990   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12)) {
27991     if (v_n_bits < 15) {
27992       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27993       iop_a_src += 1;
27994       v_n_bits += 8;
27995       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27996       iop_a_src += 1;
27997       v_n_bits += 8;
27998     } else {
27999     }
28000     v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
28001     v_table_entry_n_bits = (v_table_entry & 15);
28002     v_bits >>= v_table_entry_n_bits;
28003     v_n_bits -= v_table_entry_n_bits;
28004     if ((v_table_entry >> 31) != 0) {
28005       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28006       goto label__loop__continue;
28007     } else if ((v_table_entry >> 30) != 0) {
28008     } else if ((v_table_entry >> 29) != 0) {
28009       self->private_impl.f_end_of_block = true;
28010       goto label__loop__break;
28011     } else if ((v_table_entry >> 28) != 0) {
28012       if (v_n_bits < 15) {
28013         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28014         iop_a_src += 1;
28015         v_n_bits += 8;
28016         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28017         iop_a_src += 1;
28018         v_n_bits += 8;
28019       } else {
28020       }
28021       v_redir_top = ((v_table_entry >> 8) & 65535);
28022       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28023       v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28024       v_table_entry_n_bits = (v_table_entry & 15);
28025       v_bits >>= v_table_entry_n_bits;
28026       v_n_bits -= v_table_entry_n_bits;
28027       if ((v_table_entry >> 31) != 0) {
28028         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28029         goto label__loop__continue;
28030       } else if ((v_table_entry >> 30) != 0) {
28031       } else if ((v_table_entry >> 29) != 0) {
28032         self->private_impl.f_end_of_block = true;
28033         goto label__loop__break;
28034       } else if ((v_table_entry >> 28) != 0) {
28035         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28036         goto exit;
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     } else if ((v_table_entry >> 27) != 0) {
28045       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28046       goto exit;
28047     } else {
28048       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28049       goto exit;
28050     }
28051     v_length = (((v_table_entry >> 8) & 255) + 3);
28052     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28053     if (v_table_entry_n_bits > 0) {
28054       if (v_n_bits < 15) {
28055         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28056         iop_a_src += 1;
28057         v_n_bits += 8;
28058         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28059         iop_a_src += 1;
28060         v_n_bits += 8;
28061       } else {
28062       }
28063       v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
28064       v_bits >>= v_table_entry_n_bits;
28065       v_n_bits -= v_table_entry_n_bits;
28066     } else {
28067     }
28068     if (v_n_bits < 15) {
28069       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28070       iop_a_src += 1;
28071       v_n_bits += 8;
28072       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28073       iop_a_src += 1;
28074       v_n_bits += 8;
28075     } else {
28076     }
28077     v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
28078     v_table_entry_n_bits = (v_table_entry & 15);
28079     v_bits >>= v_table_entry_n_bits;
28080     v_n_bits -= v_table_entry_n_bits;
28081     if ((v_table_entry >> 28) == 1) {
28082       if (v_n_bits < 15) {
28083         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28084         iop_a_src += 1;
28085         v_n_bits += 8;
28086         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28087         iop_a_src += 1;
28088         v_n_bits += 8;
28089       } else {
28090       }
28091       v_redir_top = ((v_table_entry >> 8) & 65535);
28092       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28093       v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28094       v_table_entry_n_bits = (v_table_entry & 15);
28095       v_bits >>= v_table_entry_n_bits;
28096       v_n_bits -= v_table_entry_n_bits;
28097     } else {
28098     }
28099     if ((v_table_entry >> 24) != 64) {
28100       if ((v_table_entry >> 24) == 8) {
28101         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28102         goto exit;
28103       }
28104       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28105       goto exit;
28106     }
28107     v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
28108     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28109     if (v_n_bits < v_table_entry_n_bits) {
28110       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28111       iop_a_src += 1;
28112       v_n_bits += 8;
28113       v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28114       iop_a_src += 1;
28115       v_n_bits += 8;
28116     }
28117     v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
28118     v_bits >>= v_table_entry_n_bits;
28119     v_n_bits -= v_table_entry_n_bits;
28120     while (true) {
28121       if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
28122         v_hlen = 0;
28123         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
28124         if (v_length > v_hdist) {
28125           v_length -= v_hdist;
28126           v_hlen = v_hdist;
28127         } else {
28128           v_hlen = v_length;
28129           v_length = 0;
28130         }
28131         v_hdist += v_hdist_adjustment;
28132         if (self->private_impl.f_history_index < v_hdist) {
28133           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
28134           goto exit;
28135         }
28136         wuffs_base__io_writer__limited_copy_u32_from_slice(
28137             &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), ((self->private_impl.f_history_index - v_hdist) & 32767)));
28138         if (v_length == 0) {
28139           goto label__loop__continue;
28140         }
28141         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)))) {
28142           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
28143           goto exit;
28144         }
28145       }
28146       if ((v_dist_minus_1 + 1) >= 8) {
28147         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
28148             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28149       } else {
28150         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
28151             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28152       }
28153       goto label__0__break;
28154     }
28155     label__0__break:;
28156   }
28157   label__loop__break:;
28158   while (v_n_bits >= 8) {
28159     v_n_bits -= 8;
28160     if (iop_a_src > io1_a_src) {
28161       iop_a_src--;
28162     } else {
28163       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
28164       goto exit;
28165     }
28166   }
28167   self->private_impl.f_bits = (v_bits & ((((uint32_t)(1)) << v_n_bits) - 1));
28168   self->private_impl.f_n_bits = v_n_bits;
28169   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
28170     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28171     goto exit;
28172   }
28173   goto exit;
28174   exit:
28175   if (a_dst) {
28176     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28177   }
28178   if (a_src) {
28179     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28180   }
28181 
28182   return status;
28183 }
28184 
28185 // -------- func deflate.decoder.decode_huffman_fast64
28186 
28187 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)28188 wuffs_deflate__decoder__decode_huffman_fast64(
28189     wuffs_deflate__decoder* self,
28190     wuffs_base__io_buffer* a_dst,
28191     wuffs_base__io_buffer* a_src) {
28192   return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src);
28193 }
28194 
28195 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)28196 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
28197     wuffs_deflate__decoder* self,
28198     wuffs_base__io_buffer* a_dst,
28199     wuffs_base__io_buffer* a_src) {
28200   wuffs_base__status status = wuffs_base__make_status(NULL);
28201 
28202   uint64_t v_bits = 0;
28203   uint32_t v_n_bits = 0;
28204   uint32_t v_table_entry = 0;
28205   uint32_t v_table_entry_n_bits = 0;
28206   uint64_t v_lmask = 0;
28207   uint64_t v_dmask = 0;
28208   uint32_t v_redir_top = 0;
28209   uint32_t v_redir_mask = 0;
28210   uint32_t v_length = 0;
28211   uint32_t v_dist_minus_1 = 0;
28212   uint32_t v_hlen = 0;
28213   uint32_t v_hdist = 0;
28214   uint32_t v_hdist_adjustment = 0;
28215 
28216   uint8_t* iop_a_dst = NULL;
28217   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28218   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28219   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28220   if (a_dst) {
28221     io0_a_dst = a_dst->data.ptr;
28222     io1_a_dst = io0_a_dst + a_dst->meta.wi;
28223     iop_a_dst = io1_a_dst;
28224     io2_a_dst = io0_a_dst + a_dst->data.len;
28225     if (a_dst->meta.closed) {
28226       io2_a_dst = iop_a_dst;
28227     }
28228   }
28229   const uint8_t* iop_a_src = NULL;
28230   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28231   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28232   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28233   if (a_src) {
28234     io0_a_src = a_src->data.ptr;
28235     io1_a_src = io0_a_src + a_src->meta.ri;
28236     iop_a_src = io1_a_src;
28237     io2_a_src = io0_a_src + a_src->meta.wi;
28238   }
28239 
28240   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
28241     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28242     goto exit;
28243   }
28244   v_bits = ((uint64_t)(self->private_impl.f_bits));
28245   v_n_bits = self->private_impl.f_n_bits;
28246   v_lmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
28247   v_dmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
28248   if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
28249     status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
28250     goto exit;
28251   }
28252   v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
28253   label__loop__continue:;
28254   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8)) {
28255     v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63)));
28256     iop_a_src += ((63 - (v_n_bits & 63)) >> 3);
28257     v_n_bits |= 56;
28258     v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
28259     v_table_entry_n_bits = (v_table_entry & 15);
28260     v_bits >>= v_table_entry_n_bits;
28261     v_n_bits -= v_table_entry_n_bits;
28262     if ((v_table_entry >> 31) != 0) {
28263       (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28264       goto label__loop__continue;
28265     } else if ((v_table_entry >> 30) != 0) {
28266     } else if ((v_table_entry >> 29) != 0) {
28267       self->private_impl.f_end_of_block = true;
28268       goto label__loop__break;
28269     } else if ((v_table_entry >> 28) != 0) {
28270       v_redir_top = ((v_table_entry >> 8) & 65535);
28271       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28272       v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
28273       v_table_entry_n_bits = (v_table_entry & 15);
28274       v_bits >>= v_table_entry_n_bits;
28275       v_n_bits -= v_table_entry_n_bits;
28276       if ((v_table_entry >> 31) != 0) {
28277         (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28278         goto label__loop__continue;
28279       } else if ((v_table_entry >> 30) != 0) {
28280       } else if ((v_table_entry >> 29) != 0) {
28281         self->private_impl.f_end_of_block = true;
28282         goto label__loop__break;
28283       } else if ((v_table_entry >> 28) != 0) {
28284         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28285         goto exit;
28286       } else if ((v_table_entry >> 27) != 0) {
28287         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28288         goto exit;
28289       } else {
28290         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28291         goto exit;
28292       }
28293     } else if ((v_table_entry >> 27) != 0) {
28294       status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28295       goto exit;
28296     } else {
28297       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28298       goto exit;
28299     }
28300     v_length = (((v_table_entry >> 8) & 255) + 3);
28301     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28302     if (v_table_entry_n_bits > 0) {
28303       v_length = (((v_length + 253 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255) + 3);
28304       v_bits >>= v_table_entry_n_bits;
28305       v_n_bits -= v_table_entry_n_bits;
28306     }
28307     v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
28308     v_table_entry_n_bits = (v_table_entry & 15);
28309     v_bits >>= v_table_entry_n_bits;
28310     v_n_bits -= v_table_entry_n_bits;
28311     if ((v_table_entry >> 28) == 1) {
28312       v_redir_top = ((v_table_entry >> 8) & 65535);
28313       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28314       v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
28315       v_table_entry_n_bits = (v_table_entry & 15);
28316       v_bits >>= v_table_entry_n_bits;
28317       v_n_bits -= v_table_entry_n_bits;
28318     }
28319     if ((v_table_entry >> 24) != 64) {
28320       if ((v_table_entry >> 24) == 8) {
28321         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28322         goto exit;
28323       }
28324       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28325       goto exit;
28326     }
28327     v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
28328     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28329     v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767);
28330     v_bits >>= v_table_entry_n_bits;
28331     v_n_bits -= v_table_entry_n_bits;
28332     while (true) {
28333       if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
28334         v_hlen = 0;
28335         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
28336         if (v_length > v_hdist) {
28337           v_length -= v_hdist;
28338           v_hlen = v_hdist;
28339         } else {
28340           v_hlen = v_length;
28341           v_length = 0;
28342         }
28343         v_hdist += v_hdist_adjustment;
28344         if (self->private_impl.f_history_index < v_hdist) {
28345           status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
28346           goto exit;
28347         }
28348         wuffs_base__io_writer__limited_copy_u32_from_slice(
28349             &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), ((self->private_impl.f_history_index - v_hdist) & 32767)));
28350         if (v_length == 0) {
28351           goto label__loop__continue;
28352         }
28353         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)))) {
28354           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
28355           goto exit;
28356         }
28357       }
28358       if ((v_dist_minus_1 + 1) >= 8) {
28359         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
28360             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28361       } else if ((v_dist_minus_1 + 1) == 1) {
28362         wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
28363             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28364       } else {
28365         wuffs_base__io_writer__limited_copy_u32_from_history_fast(
28366             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28367       }
28368       goto label__0__break;
28369     }
28370     label__0__break:;
28371   }
28372   label__loop__break:;
28373   if (v_n_bits > 63) {
28374     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28375     goto exit;
28376   }
28377   while (v_n_bits >= 8) {
28378     v_n_bits -= 8;
28379     if (iop_a_src > io1_a_src) {
28380       iop_a_src--;
28381     } else {
28382       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
28383       goto exit;
28384     }
28385   }
28386   self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1)) << v_n_bits) - 1))));
28387   self->private_impl.f_n_bits = v_n_bits;
28388   if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
28389     status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28390     goto exit;
28391   }
28392   goto exit;
28393   exit:
28394   if (a_dst) {
28395     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28396   }
28397   if (a_src) {
28398     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28399   }
28400 
28401   return status;
28402 }
28403 
28404 // -------- func deflate.decoder.decode_huffman_slow
28405 
28406 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)28407 wuffs_deflate__decoder__decode_huffman_slow(
28408     wuffs_deflate__decoder* self,
28409     wuffs_base__io_buffer* a_dst,
28410     wuffs_base__io_buffer* a_src) {
28411   wuffs_base__status status = wuffs_base__make_status(NULL);
28412 
28413   uint32_t v_bits = 0;
28414   uint32_t v_n_bits = 0;
28415   uint32_t v_table_entry = 0;
28416   uint32_t v_table_entry_n_bits = 0;
28417   uint32_t v_lmask = 0;
28418   uint32_t v_dmask = 0;
28419   uint32_t v_b0 = 0;
28420   uint32_t v_redir_top = 0;
28421   uint32_t v_redir_mask = 0;
28422   uint32_t v_b1 = 0;
28423   uint32_t v_length = 0;
28424   uint32_t v_b2 = 0;
28425   uint32_t v_b3 = 0;
28426   uint32_t v_b4 = 0;
28427   uint32_t v_dist_minus_1 = 0;
28428   uint32_t v_b5 = 0;
28429   uint32_t v_n_copied = 0;
28430   uint32_t v_hlen = 0;
28431   uint32_t v_hdist = 0;
28432 
28433   uint8_t* iop_a_dst = NULL;
28434   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28435   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28436   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28437   if (a_dst) {
28438     io0_a_dst = a_dst->data.ptr;
28439     io1_a_dst = io0_a_dst + a_dst->meta.wi;
28440     iop_a_dst = io1_a_dst;
28441     io2_a_dst = io0_a_dst + a_dst->data.len;
28442     if (a_dst->meta.closed) {
28443       io2_a_dst = iop_a_dst;
28444     }
28445   }
28446   const uint8_t* iop_a_src = NULL;
28447   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28448   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28449   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28450   if (a_src) {
28451     io0_a_src = a_src->data.ptr;
28452     io1_a_src = io0_a_src + a_src->meta.ri;
28453     iop_a_src = io1_a_src;
28454     io2_a_src = io0_a_src + a_src->meta.wi;
28455   }
28456 
28457   uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
28458   if (coro_susp_point) {
28459     v_bits = self->private_data.s_decode_huffman_slow[0].v_bits;
28460     v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits;
28461     v_table_entry = self->private_data.s_decode_huffman_slow[0].v_table_entry;
28462     v_table_entry_n_bits = self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits;
28463     v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask;
28464     v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask;
28465     v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top;
28466     v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask;
28467     v_length = self->private_data.s_decode_huffman_slow[0].v_length;
28468     v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1;
28469     v_hlen = self->private_data.s_decode_huffman_slow[0].v_hlen;
28470   }
28471   switch (coro_susp_point) {
28472     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28473 
28474     if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
28475       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28476       goto exit;
28477     }
28478     v_bits = self->private_impl.f_bits;
28479     v_n_bits = self->private_impl.f_n_bits;
28480     v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
28481     v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
28482     label__loop__continue:;
28483     while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
28484       while (true) {
28485         v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
28486         v_table_entry_n_bits = (v_table_entry & 15);
28487         if (v_n_bits >= v_table_entry_n_bits) {
28488           v_bits >>= v_table_entry_n_bits;
28489           v_n_bits -= v_table_entry_n_bits;
28490           goto label__0__break;
28491         }
28492         {
28493           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
28494           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28495             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28496             goto suspend;
28497           }
28498           uint32_t t_0 = *iop_a_src++;
28499           v_b0 = t_0;
28500         }
28501         v_bits |= (v_b0 << v_n_bits);
28502         v_n_bits += 8;
28503       }
28504       label__0__break:;
28505       if ((v_table_entry >> 31) != 0) {
28506         self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
28507         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
28508         if (iop_a_dst == io2_a_dst) {
28509           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28510           goto suspend;
28511         }
28512         *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
28513         goto label__loop__continue;
28514       } else if ((v_table_entry >> 30) != 0) {
28515       } else if ((v_table_entry >> 29) != 0) {
28516         self->private_impl.f_end_of_block = true;
28517         goto label__loop__break;
28518       } else if ((v_table_entry >> 28) != 0) {
28519         v_redir_top = ((v_table_entry >> 8) & 65535);
28520         v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28521         while (true) {
28522           v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28523           v_table_entry_n_bits = (v_table_entry & 15);
28524           if (v_n_bits >= v_table_entry_n_bits) {
28525             v_bits >>= v_table_entry_n_bits;
28526             v_n_bits -= v_table_entry_n_bits;
28527             goto label__1__break;
28528           }
28529           {
28530             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
28531             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28532               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28533               goto suspend;
28534             }
28535             uint32_t t_1 = *iop_a_src++;
28536             v_b1 = t_1;
28537           }
28538           v_bits |= (v_b1 << v_n_bits);
28539           v_n_bits += 8;
28540         }
28541         label__1__break:;
28542         if ((v_table_entry >> 31) != 0) {
28543           self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
28544           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
28545           if (iop_a_dst == io2_a_dst) {
28546             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28547             goto suspend;
28548           }
28549           *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
28550           goto label__loop__continue;
28551         } else if ((v_table_entry >> 30) != 0) {
28552         } else if ((v_table_entry >> 29) != 0) {
28553           self->private_impl.f_end_of_block = true;
28554           goto label__loop__break;
28555         } else if ((v_table_entry >> 28) != 0) {
28556           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28557           goto exit;
28558         } else if ((v_table_entry >> 27) != 0) {
28559           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28560           goto exit;
28561         } else {
28562           status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28563           goto exit;
28564         }
28565       } else if ((v_table_entry >> 27) != 0) {
28566         status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28567         goto exit;
28568       } else {
28569         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28570         goto exit;
28571       }
28572       v_length = (((v_table_entry >> 8) & 255) + 3);
28573       v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28574       if (v_table_entry_n_bits > 0) {
28575         while (v_n_bits < v_table_entry_n_bits) {
28576           {
28577             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
28578             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28579               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28580               goto suspend;
28581             }
28582             uint32_t t_2 = *iop_a_src++;
28583             v_b2 = t_2;
28584           }
28585           v_bits |= (v_b2 << v_n_bits);
28586           v_n_bits += 8;
28587         }
28588         v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
28589         v_bits >>= v_table_entry_n_bits;
28590         v_n_bits -= v_table_entry_n_bits;
28591       }
28592       while (true) {
28593         v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
28594         v_table_entry_n_bits = (v_table_entry & 15);
28595         if (v_n_bits >= v_table_entry_n_bits) {
28596           v_bits >>= v_table_entry_n_bits;
28597           v_n_bits -= v_table_entry_n_bits;
28598           goto label__2__break;
28599         }
28600         {
28601           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
28602           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28603             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28604             goto suspend;
28605           }
28606           uint32_t t_3 = *iop_a_src++;
28607           v_b3 = t_3;
28608         }
28609         v_bits |= (v_b3 << v_n_bits);
28610         v_n_bits += 8;
28611       }
28612       label__2__break:;
28613       if ((v_table_entry >> 28) == 1) {
28614         v_redir_top = ((v_table_entry >> 8) & 65535);
28615         v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28616         while (true) {
28617           v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28618           v_table_entry_n_bits = (v_table_entry & 15);
28619           if (v_n_bits >= v_table_entry_n_bits) {
28620             v_bits >>= v_table_entry_n_bits;
28621             v_n_bits -= v_table_entry_n_bits;
28622             goto label__3__break;
28623           }
28624           {
28625             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
28626             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28627               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28628               goto suspend;
28629             }
28630             uint32_t t_4 = *iop_a_src++;
28631             v_b4 = t_4;
28632           }
28633           v_bits |= (v_b4 << v_n_bits);
28634           v_n_bits += 8;
28635         }
28636         label__3__break:;
28637       }
28638       if ((v_table_entry >> 24) != 64) {
28639         if ((v_table_entry >> 24) == 8) {
28640           status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28641           goto exit;
28642         }
28643         status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28644         goto exit;
28645       }
28646       v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
28647       v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28648       if (v_table_entry_n_bits > 0) {
28649         while (v_n_bits < v_table_entry_n_bits) {
28650           {
28651             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
28652             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28653               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28654               goto suspend;
28655             }
28656             uint32_t t_5 = *iop_a_src++;
28657             v_b5 = t_5;
28658           }
28659           v_bits |= (v_b5 << v_n_bits);
28660           v_n_bits += 8;
28661         }
28662         v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
28663         v_bits >>= v_table_entry_n_bits;
28664         v_n_bits -= v_table_entry_n_bits;
28665       }
28666       label__inner__continue:;
28667       while (true) {
28668         if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
28669           v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
28670           if (v_hdist < v_length) {
28671             v_hlen = v_hdist;
28672           } else {
28673             v_hlen = v_length;
28674           }
28675           v_hdist += ((uint32_t)((((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0))) & 4294967295)));
28676           if (self->private_impl.f_history_index < v_hdist) {
28677             status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
28678             goto exit;
28679           }
28680           v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
28681               &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), ((self->private_impl.f_history_index - v_hdist) & 32767)));
28682           if (v_n_copied < v_hlen) {
28683             v_length -= v_n_copied;
28684             status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28685             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
28686             goto label__inner__continue;
28687           }
28688           v_length -= v_hlen;
28689           if (v_length == 0) {
28690             goto label__loop__continue;
28691           }
28692         }
28693         v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_history(
28694             &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28695         if (v_length <= v_n_copied) {
28696           goto label__loop__continue;
28697         }
28698         v_length -= v_n_copied;
28699         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28700         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
28701       }
28702     }
28703     label__loop__break:;
28704     self->private_impl.f_bits = v_bits;
28705     self->private_impl.f_n_bits = v_n_bits;
28706     if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
28707       status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28708       goto exit;
28709     }
28710 
28711     ok:
28712     self->private_impl.p_decode_huffman_slow[0] = 0;
28713     goto exit;
28714   }
28715 
28716   goto suspend;
28717   suspend:
28718   self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28719   self->private_data.s_decode_huffman_slow[0].v_bits = v_bits;
28720   self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits;
28721   self->private_data.s_decode_huffman_slow[0].v_table_entry = v_table_entry;
28722   self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits = v_table_entry_n_bits;
28723   self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask;
28724   self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask;
28725   self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top;
28726   self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask;
28727   self->private_data.s_decode_huffman_slow[0].v_length = v_length;
28728   self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1;
28729   self->private_data.s_decode_huffman_slow[0].v_hlen = v_hlen;
28730 
28731   goto exit;
28732   exit:
28733   if (a_dst) {
28734     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28735   }
28736   if (a_src) {
28737     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28738   }
28739 
28740   return status;
28741 }
28742 
28743 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
28744 
28745 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
28746 
28747 // ---------------- Status Codes Implementations
28748 
28749 const char wuffs_lzw__error__bad_code[] = "#lzw: bad code";
28750 const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O";
28751 
28752 // ---------------- Private Consts
28753 
28754 // ---------------- Private Initializer Prototypes
28755 
28756 // ---------------- Private Function Prototypes
28757 
28758 static wuffs_base__empty_struct
28759 wuffs_lzw__decoder__read_from(
28760     wuffs_lzw__decoder* self,
28761     wuffs_base__io_buffer* a_src);
28762 
28763 static wuffs_base__status
28764 wuffs_lzw__decoder__write_to(
28765     wuffs_lzw__decoder* self,
28766     wuffs_base__io_buffer* a_dst);
28767 
28768 // ---------------- VTables
28769 
28770 const wuffs_base__io_transformer__func_ptrs
28771 wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = {
28772   (wuffs_base__empty_struct(*)(void*,
28773       uint32_t,
28774       bool))(&wuffs_lzw__decoder__set_quirk_enabled),
28775   (wuffs_base__status(*)(void*,
28776       wuffs_base__io_buffer*,
28777       wuffs_base__io_buffer*,
28778       wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io),
28779   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len),
28780 };
28781 
28782 // ---------------- Initializer Implementations
28783 
28784 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)28785 wuffs_lzw__decoder__initialize(
28786     wuffs_lzw__decoder* self,
28787     size_t sizeof_star_self,
28788     uint64_t wuffs_version,
28789     uint32_t options){
28790   if (!self) {
28791     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28792   }
28793   if (sizeof(*self) != sizeof_star_self) {
28794     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
28795   }
28796   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
28797       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
28798     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
28799   }
28800 
28801   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
28802     // The whole point of this if-check is to detect an uninitialized *self.
28803     // We disable the warning on GCC. Clang-5.0 does not have this warning.
28804 #if !defined(__clang__) && defined(__GNUC__)
28805 #pragma GCC diagnostic push
28806 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
28807 #endif
28808     if (self->private_impl.magic != 0) {
28809       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
28810     }
28811 #if !defined(__clang__) && defined(__GNUC__)
28812 #pragma GCC diagnostic pop
28813 #endif
28814   } else {
28815     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
28816       memset(self, 0, sizeof(*self));
28817       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
28818     } else {
28819       memset(&(self->private_impl), 0, sizeof(self->private_impl));
28820     }
28821   }
28822 
28823   self->private_impl.magic = WUFFS_BASE__MAGIC;
28824   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
28825       wuffs_base__io_transformer__vtable_name;
28826   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
28827       (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer);
28828   return wuffs_base__make_status(NULL);
28829 }
28830 
28831 wuffs_lzw__decoder*
wuffs_lzw__decoder__alloc()28832 wuffs_lzw__decoder__alloc() {
28833   wuffs_lzw__decoder* x =
28834       (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
28835   if (!x) {
28836     return NULL;
28837   }
28838   if (wuffs_lzw__decoder__initialize(
28839       x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
28840     free(x);
28841     return NULL;
28842   }
28843   return x;
28844 }
28845 
28846 size_t
sizeof__wuffs_lzw__decoder()28847 sizeof__wuffs_lzw__decoder() {
28848   return sizeof(wuffs_lzw__decoder);
28849 }
28850 
28851 // ---------------- Function Implementations
28852 
28853 // -------- func lzw.decoder.set_quirk_enabled
28854 
28855 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)28856 wuffs_lzw__decoder__set_quirk_enabled(
28857     wuffs_lzw__decoder* self,
28858     uint32_t a_quirk,
28859     bool a_enabled) {
28860   return wuffs_base__make_empty_struct();
28861 }
28862 
28863 // -------- func lzw.decoder.set_literal_width
28864 
28865 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_lzw__decoder__set_literal_width(wuffs_lzw__decoder * self,uint32_t a_lw)28866 wuffs_lzw__decoder__set_literal_width(
28867     wuffs_lzw__decoder* self,
28868     uint32_t a_lw) {
28869   if (!self) {
28870     return wuffs_base__make_empty_struct();
28871   }
28872   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28873     return wuffs_base__make_empty_struct();
28874   }
28875   if (a_lw > 8) {
28876     self->private_impl.magic = WUFFS_BASE__DISABLED;
28877     return wuffs_base__make_empty_struct();
28878   }
28879 
28880   self->private_impl.f_set_literal_width_arg = (a_lw + 1);
28881   return wuffs_base__make_empty_struct();
28882 }
28883 
28884 // -------- func lzw.decoder.workbuf_len
28885 
28886 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder * self)28887 wuffs_lzw__decoder__workbuf_len(
28888     const wuffs_lzw__decoder* self) {
28889   if (!self) {
28890     return wuffs_base__utility__empty_range_ii_u64();
28891   }
28892   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
28893       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
28894     return wuffs_base__utility__empty_range_ii_u64();
28895   }
28896 
28897   return wuffs_base__utility__make_range_ii_u64(0, 0);
28898 }
28899 
28900 // -------- func lzw.decoder.transform_io
28901 
28902 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)28903 wuffs_lzw__decoder__transform_io(
28904     wuffs_lzw__decoder* self,
28905     wuffs_base__io_buffer* a_dst,
28906     wuffs_base__io_buffer* a_src,
28907     wuffs_base__slice_u8 a_workbuf) {
28908   if (!self) {
28909     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28910   }
28911   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28912     return wuffs_base__make_status(
28913         (self->private_impl.magic == WUFFS_BASE__DISABLED)
28914         ? wuffs_base__error__disabled_by_previous_error
28915         : wuffs_base__error__initialize_not_called);
28916   }
28917   if (!a_dst || !a_src) {
28918     self->private_impl.magic = WUFFS_BASE__DISABLED;
28919     return wuffs_base__make_status(wuffs_base__error__bad_argument);
28920   }
28921   if ((self->private_impl.active_coroutine != 0) &&
28922       (self->private_impl.active_coroutine != 1)) {
28923     self->private_impl.magic = WUFFS_BASE__DISABLED;
28924     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
28925   }
28926   self->private_impl.active_coroutine = 0;
28927   wuffs_base__status status = wuffs_base__make_status(NULL);
28928 
28929   uint32_t v_i = 0;
28930 
28931   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
28932   switch (coro_susp_point) {
28933     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28934 
28935     self->private_impl.f_literal_width = 8;
28936     if (self->private_impl.f_set_literal_width_arg > 0) {
28937       self->private_impl.f_literal_width = (self->private_impl.f_set_literal_width_arg - 1);
28938     }
28939     self->private_impl.f_clear_code = (((uint32_t)(1)) << self->private_impl.f_literal_width);
28940     self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1);
28941     self->private_impl.f_save_code = self->private_impl.f_end_code;
28942     self->private_impl.f_prev_code = self->private_impl.f_end_code;
28943     self->private_impl.f_width = (self->private_impl.f_literal_width + 1);
28944     self->private_impl.f_bits = 0;
28945     self->private_impl.f_n_bits = 0;
28946     self->private_impl.f_output_ri = 0;
28947     self->private_impl.f_output_wi = 0;
28948     v_i = 0;
28949     while (v_i < self->private_impl.f_clear_code) {
28950       self->private_data.f_lm1s[v_i] = 0;
28951       self->private_data.f_suffixes[v_i][0] = ((uint8_t)(v_i));
28952       v_i += 1;
28953     }
28954     label__0__continue:;
28955     while (true) {
28956       wuffs_lzw__decoder__read_from(self, a_src);
28957       if (self->private_impl.f_output_wi > 0) {
28958         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
28959         status = wuffs_lzw__decoder__write_to(self, a_dst);
28960         if (status.repr) {
28961           goto suspend;
28962         }
28963       }
28964       if (self->private_impl.f_read_from_return_value == 0) {
28965         goto label__0__break;
28966       } else if (self->private_impl.f_read_from_return_value == 1) {
28967         goto label__0__continue;
28968       } else if (self->private_impl.f_read_from_return_value == 2) {
28969         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28970         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
28971       } else if (self->private_impl.f_read_from_return_value == 3) {
28972         status = wuffs_base__make_status(wuffs_lzw__error__bad_code);
28973         goto exit;
28974       } else {
28975         status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
28976         goto exit;
28977       }
28978     }
28979     label__0__break:;
28980 
28981     ok:
28982     self->private_impl.p_transform_io[0] = 0;
28983     goto exit;
28984   }
28985 
28986   goto suspend;
28987   suspend:
28988   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28989   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
28990 
28991   goto exit;
28992   exit:
28993   if (wuffs_base__status__is_error(&status)) {
28994     self->private_impl.magic = WUFFS_BASE__DISABLED;
28995   }
28996   return status;
28997 }
28998 
28999 // -------- func lzw.decoder.read_from
29000 
29001 static wuffs_base__empty_struct
wuffs_lzw__decoder__read_from(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_src)29002 wuffs_lzw__decoder__read_from(
29003     wuffs_lzw__decoder* self,
29004     wuffs_base__io_buffer* a_src) {
29005   uint32_t v_clear_code = 0;
29006   uint32_t v_end_code = 0;
29007   uint32_t v_save_code = 0;
29008   uint32_t v_prev_code = 0;
29009   uint32_t v_width = 0;
29010   uint32_t v_bits = 0;
29011   uint32_t v_n_bits = 0;
29012   uint32_t v_output_wi = 0;
29013   uint32_t v_code = 0;
29014   uint32_t v_c = 0;
29015   uint32_t v_o = 0;
29016   uint32_t v_steps = 0;
29017   uint8_t v_first_byte = 0;
29018   uint16_t v_lm1_b = 0;
29019   uint16_t v_lm1_a = 0;
29020 
29021   const uint8_t* iop_a_src = NULL;
29022   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29023   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29024   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29025   if (a_src) {
29026     io0_a_src = a_src->data.ptr;
29027     io1_a_src = io0_a_src + a_src->meta.ri;
29028     iop_a_src = io1_a_src;
29029     io2_a_src = io0_a_src + a_src->meta.wi;
29030   }
29031 
29032   v_clear_code = self->private_impl.f_clear_code;
29033   v_end_code = self->private_impl.f_end_code;
29034   v_save_code = self->private_impl.f_save_code;
29035   v_prev_code = self->private_impl.f_prev_code;
29036   v_width = self->private_impl.f_width;
29037   v_bits = self->private_impl.f_bits;
29038   v_n_bits = self->private_impl.f_n_bits;
29039   v_output_wi = self->private_impl.f_output_wi;
29040   while (true) {
29041     if (v_n_bits < v_width) {
29042       if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
29043         v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
29044         iop_a_src += ((31 - v_n_bits) >> 3);
29045         v_n_bits |= 24;
29046       } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29047         self->private_impl.f_read_from_return_value = 2;
29048         goto label__0__break;
29049       } else {
29050         v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
29051         iop_a_src += 1;
29052         v_n_bits += 8;
29053         if (v_n_bits >= v_width) {
29054         } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29055           self->private_impl.f_read_from_return_value = 2;
29056           goto label__0__break;
29057         } else {
29058           v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
29059           iop_a_src += 1;
29060           v_n_bits += 8;
29061           if (v_n_bits < v_width) {
29062             self->private_impl.f_read_from_return_value = 4;
29063             goto label__0__break;
29064           }
29065         }
29066       }
29067     }
29068     v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
29069     v_bits >>= v_width;
29070     v_n_bits -= v_width;
29071     if (v_code < v_clear_code) {
29072       self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
29073       v_output_wi = ((v_output_wi + 1) & 8191);
29074       if (v_save_code <= 4095) {
29075         v_lm1_a = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1)) & 4095);
29076         self->private_data.f_lm1s[v_save_code] = v_lm1_a;
29077         if ((v_lm1_a % 8) != 0) {
29078           self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
29079           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]));
29080           self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8)] = ((uint8_t)(v_code));
29081         } else {
29082           self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
29083           self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_code));
29084         }
29085         v_save_code += 1;
29086         if (v_width < 12) {
29087           v_width += (1 & (v_save_code >> v_width));
29088         }
29089         v_prev_code = v_code;
29090       }
29091     } else if (v_code <= v_end_code) {
29092       if (v_code == v_end_code) {
29093         self->private_impl.f_read_from_return_value = 0;
29094         goto label__0__break;
29095       }
29096       v_save_code = v_end_code;
29097       v_prev_code = v_end_code;
29098       v_width = (self->private_impl.f_literal_width + 1);
29099     } else if (v_code <= v_save_code) {
29100       v_c = v_code;
29101       if (v_code == v_save_code) {
29102         v_c = v_prev_code;
29103       }
29104       v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288)) & 8191);
29105       v_output_wi = ((v_output_wi + 1 + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191);
29106       v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3);
29107       while (true) {
29108         memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8);
29109         if (v_steps <= 0) {
29110           goto label__1__break;
29111         }
29112         v_steps -= 1;
29113         v_o = (((uint32_t)(v_o - 8)) & 8191);
29114         v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
29115       }
29116       label__1__break:;
29117       v_first_byte = self->private_data.f_suffixes[v_c][0];
29118       if (v_code == v_save_code) {
29119         self->private_data.f_output[v_output_wi] = v_first_byte;
29120         v_output_wi = ((v_output_wi + 1) & 8191);
29121       }
29122       if (v_save_code <= 4095) {
29123         v_lm1_b = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1)) & 4095);
29124         self->private_data.f_lm1s[v_save_code] = v_lm1_b;
29125         if ((v_lm1_b % 8) != 0) {
29126           self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
29127           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]));
29128           self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8)] = v_first_byte;
29129         } else {
29130           self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
29131           self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_first_byte));
29132         }
29133         v_save_code += 1;
29134         if (v_width < 12) {
29135           v_width += (1 & (v_save_code >> v_width));
29136         }
29137         v_prev_code = v_code;
29138       }
29139     } else {
29140       self->private_impl.f_read_from_return_value = 3;
29141       goto label__0__break;
29142     }
29143     if (v_output_wi > 4095) {
29144       self->private_impl.f_read_from_return_value = 1;
29145       goto label__0__break;
29146     }
29147   }
29148   label__0__break:;
29149   if (self->private_impl.f_read_from_return_value != 2) {
29150     while (v_n_bits >= 8) {
29151       v_n_bits -= 8;
29152       if (iop_a_src > io1_a_src) {
29153         iop_a_src--;
29154       } else {
29155         self->private_impl.f_read_from_return_value = 4;
29156         goto label__2__break;
29157       }
29158     }
29159     label__2__break:;
29160   }
29161   self->private_impl.f_save_code = v_save_code;
29162   self->private_impl.f_prev_code = v_prev_code;
29163   self->private_impl.f_width = v_width;
29164   self->private_impl.f_bits = v_bits;
29165   self->private_impl.f_n_bits = v_n_bits;
29166   self->private_impl.f_output_wi = v_output_wi;
29167   if (a_src) {
29168     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29169   }
29170 
29171   return wuffs_base__make_empty_struct();
29172 }
29173 
29174 // -------- func lzw.decoder.write_to
29175 
29176 static wuffs_base__status
wuffs_lzw__decoder__write_to(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst)29177 wuffs_lzw__decoder__write_to(
29178     wuffs_lzw__decoder* self,
29179     wuffs_base__io_buffer* a_dst) {
29180   wuffs_base__status status = wuffs_base__make_status(NULL);
29181 
29182   wuffs_base__slice_u8 v_s = {0};
29183   uint64_t v_n = 0;
29184 
29185   uint8_t* iop_a_dst = NULL;
29186   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29187   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29188   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29189   if (a_dst) {
29190     io0_a_dst = a_dst->data.ptr;
29191     io1_a_dst = io0_a_dst + a_dst->meta.wi;
29192     iop_a_dst = io1_a_dst;
29193     io2_a_dst = io0_a_dst + a_dst->data.len;
29194     if (a_dst->meta.closed) {
29195       io2_a_dst = iop_a_dst;
29196     }
29197   }
29198 
29199   uint32_t coro_susp_point = self->private_impl.p_write_to[0];
29200   switch (coro_susp_point) {
29201     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29202 
29203     while (self->private_impl.f_output_wi > 0) {
29204       if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
29205         status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
29206         goto exit;
29207       }
29208       v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
29209           8199),
29210           self->private_impl.f_output_ri,
29211           self->private_impl.f_output_wi);
29212       v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s);
29213       if (v_n == ((uint64_t)(v_s.len))) {
29214         self->private_impl.f_output_ri = 0;
29215         self->private_impl.f_output_wi = 0;
29216         status = wuffs_base__make_status(NULL);
29217         goto ok;
29218       }
29219       self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)((v_n & 4294967295))))) & 8191);
29220       status = wuffs_base__make_status(wuffs_base__suspension__short_write);
29221       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
29222     }
29223 
29224     ok:
29225     self->private_impl.p_write_to[0] = 0;
29226     goto exit;
29227   }
29228 
29229   goto suspend;
29230   suspend:
29231   self->private_impl.p_write_to[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29232 
29233   goto exit;
29234   exit:
29235   if (a_dst) {
29236     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
29237   }
29238 
29239   return status;
29240 }
29241 
29242 // -------- func lzw.decoder.flush
29243 
29244 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
wuffs_lzw__decoder__flush(wuffs_lzw__decoder * self)29245 wuffs_lzw__decoder__flush(
29246     wuffs_lzw__decoder* self) {
29247   if (!self) {
29248     return wuffs_base__make_slice_u8(NULL, 0);
29249   }
29250   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29251     return wuffs_base__make_slice_u8(NULL, 0);
29252   }
29253 
29254   wuffs_base__slice_u8 v_s = {0};
29255 
29256   if (self->private_impl.f_output_ri <= self->private_impl.f_output_wi) {
29257     v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
29258         8199),
29259         self->private_impl.f_output_ri,
29260         self->private_impl.f_output_wi);
29261   }
29262   self->private_impl.f_output_ri = 0;
29263   self->private_impl.f_output_wi = 0;
29264   return v_s;
29265 }
29266 
29267 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
29268 
29269 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
29270 
29271 // ---------------- Status Codes Implementations
29272 
29273 const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label";
29274 const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size";
29275 const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control";
29276 const char wuffs_gif__error__bad_header[] = "#gif: bad header";
29277 const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width";
29278 const char wuffs_gif__error__bad_palette[] = "#gif: bad palette";
29279 const char wuffs_gif__error__internal_error_inconsistent_ri_wi[] = "#gif: internal error: inconsistent ri/wi";
29280 
29281 // ---------------- Private Consts
29282 
29283 static const uint32_t
29284 WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
29285   4294967295, 1, 2, 4, 0,
29286 };
29287 
29288 static const uint8_t
29289 WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
29290   1, 2, 4, 8, 8,
29291 };
29292 
29293 static const uint8_t
29294 WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
29295   0, 1, 2, 4, 8,
29296 };
29297 
29298 static const uint8_t
29299 WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29300   65, 78, 73, 77, 69, 88, 84, 83,
29301   49, 46, 48,
29302 };
29303 
29304 static const uint8_t
29305 WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29306   78, 69, 84, 83, 67, 65, 80, 69,
29307   50, 46, 48,
29308 };
29309 
29310 static const uint8_t
29311 WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29312   73, 67, 67, 82, 71, 66, 71, 49,
29313   48, 49, 50,
29314 };
29315 
29316 static const uint8_t
29317 WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29318   88, 77, 80, 32, 68, 97, 116, 97,
29319   88, 77, 80,
29320 };
29321 
29322 #define WUFFS_GIF__QUIRKS_BASE 1041635328
29323 
29324 #define WUFFS_GIF__QUIRKS_COUNT 7
29325 
29326 // ---------------- Private Initializer Prototypes
29327 
29328 // ---------------- Private Function Prototypes
29329 
29330 static wuffs_base__status
29331 wuffs_gif__decoder__skip_frame(
29332     wuffs_gif__decoder* self,
29333     wuffs_base__io_buffer* a_src);
29334 
29335 static wuffs_base__empty_struct
29336 wuffs_gif__decoder__reset_gc(
29337     wuffs_gif__decoder* self);
29338 
29339 static wuffs_base__status
29340 wuffs_gif__decoder__decode_up_to_id_part1(
29341     wuffs_gif__decoder* self,
29342     wuffs_base__io_buffer* a_src);
29343 
29344 static wuffs_base__status
29345 wuffs_gif__decoder__decode_header(
29346     wuffs_gif__decoder* self,
29347     wuffs_base__io_buffer* a_src);
29348 
29349 static wuffs_base__status
29350 wuffs_gif__decoder__decode_lsd(
29351     wuffs_gif__decoder* self,
29352     wuffs_base__io_buffer* a_src);
29353 
29354 static wuffs_base__status
29355 wuffs_gif__decoder__decode_extension(
29356     wuffs_gif__decoder* self,
29357     wuffs_base__io_buffer* a_src);
29358 
29359 static wuffs_base__status
29360 wuffs_gif__decoder__skip_blocks(
29361     wuffs_gif__decoder* self,
29362     wuffs_base__io_buffer* a_src);
29363 
29364 static wuffs_base__status
29365 wuffs_gif__decoder__decode_ae(
29366     wuffs_gif__decoder* self,
29367     wuffs_base__io_buffer* a_src);
29368 
29369 static wuffs_base__status
29370 wuffs_gif__decoder__decode_gc(
29371     wuffs_gif__decoder* self,
29372     wuffs_base__io_buffer* a_src);
29373 
29374 static wuffs_base__status
29375 wuffs_gif__decoder__decode_id_part0(
29376     wuffs_gif__decoder* self,
29377     wuffs_base__io_buffer* a_src);
29378 
29379 static wuffs_base__status
29380 wuffs_gif__decoder__decode_id_part1(
29381     wuffs_gif__decoder* self,
29382     wuffs_base__pixel_buffer* a_dst,
29383     wuffs_base__io_buffer* a_src,
29384     wuffs_base__pixel_blend a_blend);
29385 
29386 static wuffs_base__status
29387 wuffs_gif__decoder__decode_id_part2(
29388     wuffs_gif__decoder* self,
29389     wuffs_base__pixel_buffer* a_dst,
29390     wuffs_base__io_buffer* a_src,
29391     wuffs_base__slice_u8 a_workbuf);
29392 
29393 static wuffs_base__status
29394 wuffs_gif__decoder__copy_to_image_buffer(
29395     wuffs_gif__decoder* self,
29396     wuffs_base__pixel_buffer* a_pb,
29397     wuffs_base__slice_u8 a_src);
29398 
29399 // ---------------- VTables
29400 
29401 const wuffs_base__image_decoder__func_ptrs
29402 wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = {
29403   (wuffs_base__status(*)(void*,
29404       wuffs_base__pixel_buffer*,
29405       wuffs_base__io_buffer*,
29406       wuffs_base__pixel_blend,
29407       wuffs_base__slice_u8,
29408       wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame),
29409   (wuffs_base__status(*)(void*,
29410       wuffs_base__frame_config*,
29411       wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config),
29412   (wuffs_base__status(*)(void*,
29413       wuffs_base__image_config*,
29414       wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config),
29415   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect),
29416   (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops),
29417   (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs),
29418   (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames),
29419   (wuffs_base__status(*)(void*,
29420       uint64_t,
29421       uint64_t))(&wuffs_gif__decoder__restart_frame),
29422   (wuffs_base__empty_struct(*)(void*,
29423       uint32_t,
29424       bool))(&wuffs_gif__decoder__set_quirk_enabled),
29425   (wuffs_base__empty_struct(*)(void*,
29426       uint32_t,
29427       bool))(&wuffs_gif__decoder__set_report_metadata),
29428   (wuffs_base__status(*)(void*,
29429       wuffs_base__io_buffer*,
29430       wuffs_base__more_information*,
29431       wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more),
29432   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len),
29433 };
29434 
29435 // ---------------- Initializer Implementations
29436 
29437 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)29438 wuffs_gif__decoder__initialize(
29439     wuffs_gif__decoder* self,
29440     size_t sizeof_star_self,
29441     uint64_t wuffs_version,
29442     uint32_t options){
29443   if (!self) {
29444     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29445   }
29446   if (sizeof(*self) != sizeof_star_self) {
29447     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
29448   }
29449   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
29450       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
29451     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
29452   }
29453 
29454   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
29455     // The whole point of this if-check is to detect an uninitialized *self.
29456     // We disable the warning on GCC. Clang-5.0 does not have this warning.
29457 #if !defined(__clang__) && defined(__GNUC__)
29458 #pragma GCC diagnostic push
29459 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
29460 #endif
29461     if (self->private_impl.magic != 0) {
29462       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
29463     }
29464 #if !defined(__clang__) && defined(__GNUC__)
29465 #pragma GCC diagnostic pop
29466 #endif
29467   } else {
29468     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
29469       memset(self, 0, sizeof(*self));
29470       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
29471     } else {
29472       memset(&(self->private_impl), 0, sizeof(self->private_impl));
29473     }
29474   }
29475 
29476   {
29477     wuffs_base__status z = wuffs_lzw__decoder__initialize(
29478         &self->private_data.f_lzw, sizeof(self->private_data.f_lzw), WUFFS_VERSION, options);
29479     if (z.repr) {
29480       return z;
29481     }
29482   }
29483   self->private_impl.magic = WUFFS_BASE__MAGIC;
29484   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
29485       wuffs_base__image_decoder__vtable_name;
29486   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
29487       (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder);
29488   return wuffs_base__make_status(NULL);
29489 }
29490 
29491 wuffs_gif__decoder*
wuffs_gif__decoder__alloc()29492 wuffs_gif__decoder__alloc() {
29493   wuffs_gif__decoder* x =
29494       (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
29495   if (!x) {
29496     return NULL;
29497   }
29498   if (wuffs_gif__decoder__initialize(
29499       x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
29500     free(x);
29501     return NULL;
29502   }
29503   return x;
29504 }
29505 
29506 size_t
sizeof__wuffs_gif__decoder()29507 sizeof__wuffs_gif__decoder() {
29508   return sizeof(wuffs_gif__decoder);
29509 }
29510 
29511 // ---------------- Function Implementations
29512 
29513 // -------- func gif.decoder.set_quirk_enabled
29514 
29515 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)29516 wuffs_gif__decoder__set_quirk_enabled(
29517     wuffs_gif__decoder* self,
29518     uint32_t a_quirk,
29519     bool a_enabled) {
29520   if (!self) {
29521     return wuffs_base__make_empty_struct();
29522   }
29523   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29524     return wuffs_base__make_empty_struct();
29525   }
29526 
29527   if ((self->private_impl.f_call_sequence == 0) && (a_quirk >= 1041635328)) {
29528     a_quirk -= 1041635328;
29529     if (a_quirk < 7) {
29530       self->private_impl.f_quirks[a_quirk] = a_enabled;
29531     }
29532   }
29533   return wuffs_base__make_empty_struct();
29534 }
29535 
29536 // -------- func gif.decoder.decode_image_config
29537 
29538 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)29539 wuffs_gif__decoder__decode_image_config(
29540     wuffs_gif__decoder* self,
29541     wuffs_base__image_config* a_dst,
29542     wuffs_base__io_buffer* a_src) {
29543   if (!self) {
29544     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29545   }
29546   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29547     return wuffs_base__make_status(
29548         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29549         ? wuffs_base__error__disabled_by_previous_error
29550         : wuffs_base__error__initialize_not_called);
29551   }
29552   if (!a_src) {
29553     self->private_impl.magic = WUFFS_BASE__DISABLED;
29554     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29555   }
29556   if ((self->private_impl.active_coroutine != 0) &&
29557       (self->private_impl.active_coroutine != 1)) {
29558     self->private_impl.magic = WUFFS_BASE__DISABLED;
29559     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29560   }
29561   self->private_impl.active_coroutine = 0;
29562   wuffs_base__status status = wuffs_base__make_status(NULL);
29563 
29564   bool v_ffio = false;
29565 
29566   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
29567   switch (coro_susp_point) {
29568     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29569 
29570     if (self->private_impl.f_call_sequence == 0) {
29571       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29572       status = wuffs_gif__decoder__decode_header(self, a_src);
29573       if (status.repr) {
29574         goto suspend;
29575       }
29576       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29577       status = wuffs_gif__decoder__decode_lsd(self, a_src);
29578       if (status.repr) {
29579         goto suspend;
29580       }
29581     } else if (self->private_impl.f_call_sequence != 2) {
29582       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29583       goto exit;
29584     }
29585     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
29586     status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
29587     if (status.repr) {
29588       goto suspend;
29589     }
29590     v_ffio =  ! self->private_impl.f_gc_has_transparent_index;
29591     if ( ! self->private_impl.f_quirks[2]) {
29592       v_ffio = (v_ffio &&
29593           (self->private_impl.f_frame_rect_x0 == 0) &&
29594           (self->private_impl.f_frame_rect_y0 == 0) &&
29595           (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
29596           (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
29597     } else if (v_ffio) {
29598       self->private_impl.f_black_color_u32_argb_premul = 4278190080;
29599     }
29600     if (self->private_impl.f_background_color_u32_argb_premul == 77) {
29601       self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
29602     }
29603     if (a_dst != NULL) {
29604       wuffs_base__image_config__set(
29605           a_dst,
29606           2198077448,
29607           0,
29608           self->private_impl.f_width,
29609           self->private_impl.f_height,
29610           self->private_impl.f_frame_config_io_position,
29611           v_ffio);
29612     }
29613     self->private_impl.f_call_sequence = 3;
29614 
29615     goto ok;
29616     ok:
29617     self->private_impl.p_decode_image_config[0] = 0;
29618     goto exit;
29619   }
29620 
29621   goto suspend;
29622   suspend:
29623   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29624   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
29625 
29626   goto exit;
29627   exit:
29628   if (wuffs_base__status__is_error(&status)) {
29629     self->private_impl.magic = WUFFS_BASE__DISABLED;
29630   }
29631   return status;
29632 }
29633 
29634 // -------- func gif.decoder.set_report_metadata
29635 
29636 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)29637 wuffs_gif__decoder__set_report_metadata(
29638     wuffs_gif__decoder* self,
29639     uint32_t a_fourcc,
29640     bool a_report) {
29641   if (!self) {
29642     return wuffs_base__make_empty_struct();
29643   }
29644   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29645     return wuffs_base__make_empty_struct();
29646   }
29647 
29648   if (a_fourcc == 1229144912) {
29649     self->private_impl.f_report_metadata_iccp = a_report;
29650   } else if (a_fourcc == 1481461792) {
29651     self->private_impl.f_report_metadata_xmp = a_report;
29652   }
29653   return wuffs_base__make_empty_struct();
29654 }
29655 
29656 // -------- func gif.decoder.tell_me_more
29657 
29658 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)29659 wuffs_gif__decoder__tell_me_more(
29660     wuffs_gif__decoder* self,
29661     wuffs_base__io_buffer* a_dst,
29662     wuffs_base__more_information* a_minfo,
29663     wuffs_base__io_buffer* a_src) {
29664   if (!self) {
29665     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29666   }
29667   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29668     return wuffs_base__make_status(
29669         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29670         ? wuffs_base__error__disabled_by_previous_error
29671         : wuffs_base__error__initialize_not_called);
29672   }
29673   if (!a_dst || !a_src) {
29674     self->private_impl.magic = WUFFS_BASE__DISABLED;
29675     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29676   }
29677   if ((self->private_impl.active_coroutine != 0) &&
29678       (self->private_impl.active_coroutine != 2)) {
29679     self->private_impl.magic = WUFFS_BASE__DISABLED;
29680     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29681   }
29682   self->private_impl.active_coroutine = 0;
29683   wuffs_base__status status = wuffs_base__make_status(NULL);
29684 
29685   uint64_t v_chunk_length = 0;
29686 
29687   const uint8_t* iop_a_src = NULL;
29688   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29689   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29690   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29691   if (a_src) {
29692     io0_a_src = a_src->data.ptr;
29693     io1_a_src = io0_a_src + a_src->meta.ri;
29694     iop_a_src = io1_a_src;
29695     io2_a_src = io0_a_src + a_src->meta.wi;
29696   }
29697 
29698   uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
29699   switch (coro_susp_point) {
29700     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29701 
29702     if (self->private_impl.f_call_sequence != 1) {
29703       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29704       goto exit;
29705     }
29706     if (self->private_impl.f_metadata_fourcc == 0) {
29707       status = wuffs_base__make_status(wuffs_base__error__no_more_information);
29708       goto exit;
29709     }
29710     while (true) {
29711       label__0__continue:;
29712       while (true) {
29713         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) {
29714           if (a_minfo != NULL) {
29715             wuffs_base__more_information__set(a_minfo,
29716                 2,
29717                 0,
29718                 self->private_impl.f_metadata_io_position,
29719                 0,
29720                 0);
29721           }
29722           status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
29723           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
29724           goto label__0__continue;
29725         }
29726         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29727           if (a_minfo != NULL) {
29728             wuffs_base__more_information__set(a_minfo,
29729                 0,
29730                 0,
29731                 0,
29732                 0,
29733                 0);
29734           }
29735           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29736           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
29737           goto label__0__continue;
29738         }
29739         goto label__0__break;
29740       }
29741       label__0__break:;
29742       v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
29743       if (v_chunk_length <= 0) {
29744         iop_a_src += 1;
29745         goto label__1__break;
29746       }
29747       if (self->private_impl.f_metadata_fourcc == 1481461792) {
29748         v_chunk_length += 1;
29749       } else {
29750         iop_a_src += 1;
29751       }
29752       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);
29753       if (a_minfo != NULL) {
29754         wuffs_base__more_information__set(a_minfo,
29755             3,
29756             self->private_impl.f_metadata_fourcc,
29757             0,
29758             wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))),
29759             self->private_impl.f_metadata_io_position);
29760       }
29761       status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
29762       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
29763     }
29764     label__1__break:;
29765     if (a_minfo != NULL) {
29766       wuffs_base__more_information__set(a_minfo,
29767           3,
29768           self->private_impl.f_metadata_fourcc,
29769           0,
29770           self->private_impl.f_metadata_io_position,
29771           self->private_impl.f_metadata_io_position);
29772     }
29773     self->private_impl.f_call_sequence = 2;
29774     self->private_impl.f_metadata_fourcc = 0;
29775     self->private_impl.f_metadata_io_position = 0;
29776     status = wuffs_base__make_status(NULL);
29777     goto ok;
29778 
29779     ok:
29780     self->private_impl.p_tell_me_more[0] = 0;
29781     goto exit;
29782   }
29783 
29784   goto suspend;
29785   suspend:
29786   self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29787   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
29788 
29789   goto exit;
29790   exit:
29791   if (a_src) {
29792     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29793   }
29794 
29795   if (wuffs_base__status__is_error(&status)) {
29796     self->private_impl.magic = WUFFS_BASE__DISABLED;
29797   }
29798   return status;
29799 }
29800 
29801 // -------- func gif.decoder.num_animation_loops
29802 
29803 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder * self)29804 wuffs_gif__decoder__num_animation_loops(
29805     const wuffs_gif__decoder* self) {
29806   if (!self) {
29807     return 0;
29808   }
29809   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29810       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29811     return 0;
29812   }
29813 
29814   if (self->private_impl.f_seen_num_animation_loops_value) {
29815     return self->private_impl.f_num_animation_loops_value;
29816   }
29817   if (self->private_impl.f_num_decoded_frame_configs_value > 1) {
29818     return 1;
29819   }
29820   return 0;
29821 }
29822 
29823 // -------- func gif.decoder.num_decoded_frame_configs
29824 
29825 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder * self)29826 wuffs_gif__decoder__num_decoded_frame_configs(
29827     const wuffs_gif__decoder* self) {
29828   if (!self) {
29829     return 0;
29830   }
29831   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29832       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29833     return 0;
29834   }
29835 
29836   return self->private_impl.f_num_decoded_frame_configs_value;
29837 }
29838 
29839 // -------- func gif.decoder.num_decoded_frames
29840 
29841 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder * self)29842 wuffs_gif__decoder__num_decoded_frames(
29843     const wuffs_gif__decoder* self) {
29844   if (!self) {
29845     return 0;
29846   }
29847   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29848       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29849     return 0;
29850   }
29851 
29852   return self->private_impl.f_num_decoded_frames_value;
29853 }
29854 
29855 // -------- func gif.decoder.frame_dirty_rect
29856 
29857 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder * self)29858 wuffs_gif__decoder__frame_dirty_rect(
29859     const wuffs_gif__decoder* self) {
29860   if (!self) {
29861     return wuffs_base__utility__empty_rect_ie_u32();
29862   }
29863   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29864       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29865     return wuffs_base__utility__empty_rect_ie_u32();
29866   }
29867 
29868   return wuffs_base__utility__make_rect_ie_u32(
29869       wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
29870       wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
29871       wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
29872       wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height));
29873 }
29874 
29875 // -------- func gif.decoder.workbuf_len
29876 
29877 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder * self)29878 wuffs_gif__decoder__workbuf_len(
29879     const wuffs_gif__decoder* self) {
29880   if (!self) {
29881     return wuffs_base__utility__empty_range_ii_u64();
29882   }
29883   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29884       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29885     return wuffs_base__utility__empty_range_ii_u64();
29886   }
29887 
29888   return wuffs_base__utility__make_range_ii_u64(0, 0);
29889 }
29890 
29891 // -------- func gif.decoder.restart_frame
29892 
29893 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)29894 wuffs_gif__decoder__restart_frame(
29895     wuffs_gif__decoder* self,
29896     uint64_t a_index,
29897     uint64_t a_io_position) {
29898   if (!self) {
29899     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29900   }
29901   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29902     return wuffs_base__make_status(
29903         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29904         ? wuffs_base__error__disabled_by_previous_error
29905         : wuffs_base__error__initialize_not_called);
29906   }
29907 
29908   if (self->private_impl.f_call_sequence < 3) {
29909     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29910   }
29911   self->private_impl.f_delayed_num_decoded_frames = false;
29912   self->private_impl.f_end_of_data = false;
29913   self->private_impl.f_restarted = true;
29914   self->private_impl.f_frame_config_io_position = a_io_position;
29915   self->private_impl.f_num_decoded_frame_configs_value = a_index;
29916   self->private_impl.f_num_decoded_frames_value = a_index;
29917   wuffs_gif__decoder__reset_gc(self);
29918   return wuffs_base__make_status(NULL);
29919 }
29920 
29921 // -------- func gif.decoder.decode_frame_config
29922 
29923 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)29924 wuffs_gif__decoder__decode_frame_config(
29925     wuffs_gif__decoder* self,
29926     wuffs_base__frame_config* a_dst,
29927     wuffs_base__io_buffer* a_src) {
29928   if (!self) {
29929     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29930   }
29931   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29932     return wuffs_base__make_status(
29933         (self->private_impl.magic == WUFFS_BASE__DISABLED)
29934         ? wuffs_base__error__disabled_by_previous_error
29935         : wuffs_base__error__initialize_not_called);
29936   }
29937   if (!a_src) {
29938     self->private_impl.magic = WUFFS_BASE__DISABLED;
29939     return wuffs_base__make_status(wuffs_base__error__bad_argument);
29940   }
29941   if ((self->private_impl.active_coroutine != 0) &&
29942       (self->private_impl.active_coroutine != 3)) {
29943     self->private_impl.magic = WUFFS_BASE__DISABLED;
29944     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29945   }
29946   self->private_impl.active_coroutine = 0;
29947   wuffs_base__status status = wuffs_base__make_status(NULL);
29948 
29949   uint32_t v_background_color = 0;
29950   uint8_t v_flags = 0;
29951 
29952   const uint8_t* iop_a_src = NULL;
29953   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29954   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29955   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29956   if (a_src) {
29957     io0_a_src = a_src->data.ptr;
29958     io1_a_src = io0_a_src + a_src->meta.ri;
29959     iop_a_src = io1_a_src;
29960     io2_a_src = io0_a_src + a_src->meta.wi;
29961   }
29962 
29963   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
29964   if (coro_susp_point) {
29965     v_background_color = self->private_data.s_decode_frame_config[0].v_background_color;
29966   }
29967   switch (coro_susp_point) {
29968     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29969 
29970     self->private_impl.f_ignore_metadata = true;
29971     self->private_impl.f_dirty_max_excl_y = 0;
29972     if ( ! self->private_impl.f_end_of_data) {
29973       if (self->private_impl.f_call_sequence == 0) {
29974         if (a_src) {
29975           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29976         }
29977         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29978         status = wuffs_gif__decoder__decode_image_config(self, NULL, a_src);
29979         if (a_src) {
29980           iop_a_src = a_src->data.ptr + a_src->meta.ri;
29981         }
29982         if (status.repr) {
29983           goto suspend;
29984         }
29985       } else if (self->private_impl.f_call_sequence != 3) {
29986         if (self->private_impl.f_call_sequence == 4) {
29987           if (a_src) {
29988             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29989           }
29990           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29991           status = wuffs_gif__decoder__skip_frame(self, a_src);
29992           if (a_src) {
29993             iop_a_src = a_src->data.ptr + a_src->meta.ri;
29994           }
29995           if (status.repr) {
29996             goto suspend;
29997           }
29998         }
29999         if (a_src) {
30000           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30001         }
30002         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30003         status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
30004         if (a_src) {
30005           iop_a_src = a_src->data.ptr + a_src->meta.ri;
30006         }
30007         if (status.repr) {
30008           goto suspend;
30009         }
30010       }
30011     }
30012     if (self->private_impl.f_end_of_data) {
30013       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
30014       goto ok;
30015     }
30016     v_background_color = self->private_impl.f_black_color_u32_argb_premul;
30017     if ( ! self->private_impl.f_gc_has_transparent_index) {
30018       v_background_color = self->private_impl.f_background_color_u32_argb_premul;
30019       if (self->private_impl.f_quirks[1] && (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
30020         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
30021           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30022           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
30023         }
30024         v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
30025         if ((v_flags & 128) != 0) {
30026           v_background_color = self->private_impl.f_black_color_u32_argb_premul;
30027         }
30028       }
30029     }
30030     if (a_dst != NULL) {
30031       wuffs_base__frame_config__set(
30032           a_dst,
30033           wuffs_base__utility__make_rect_ie_u32(
30034           wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
30035           wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
30036           wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
30037           wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
30038           ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
30039           self->private_impl.f_num_decoded_frame_configs_value,
30040           self->private_impl.f_frame_config_io_position,
30041           self->private_impl.f_gc_disposal,
30042           ! self->private_impl.f_gc_has_transparent_index,
30043           false,
30044           v_background_color);
30045     }
30046     wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
30047     self->private_impl.f_call_sequence = 4;
30048 
30049     ok:
30050     self->private_impl.p_decode_frame_config[0] = 0;
30051     goto exit;
30052   }
30053 
30054   goto suspend;
30055   suspend:
30056   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30057   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
30058   self->private_data.s_decode_frame_config[0].v_background_color = v_background_color;
30059 
30060   goto exit;
30061   exit:
30062   if (a_src) {
30063     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30064   }
30065 
30066   if (wuffs_base__status__is_error(&status)) {
30067     self->private_impl.magic = WUFFS_BASE__DISABLED;
30068   }
30069   return status;
30070 }
30071 
30072 // -------- func gif.decoder.skip_frame
30073 
30074 static wuffs_base__status
wuffs_gif__decoder__skip_frame(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30075 wuffs_gif__decoder__skip_frame(
30076     wuffs_gif__decoder* self,
30077     wuffs_base__io_buffer* a_src) {
30078   wuffs_base__status status = wuffs_base__make_status(NULL);
30079 
30080   uint8_t v_flags = 0;
30081   uint8_t v_lw = 0;
30082 
30083   const uint8_t* iop_a_src = NULL;
30084   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30085   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30086   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30087   if (a_src) {
30088     io0_a_src = a_src->data.ptr;
30089     io1_a_src = io0_a_src + a_src->meta.ri;
30090     iop_a_src = io1_a_src;
30091     io2_a_src = io0_a_src + a_src->meta.wi;
30092   }
30093 
30094   uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
30095   switch (coro_susp_point) {
30096     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30097 
30098     {
30099       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30100       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30101         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30102         goto suspend;
30103       }
30104       uint8_t t_0 = *iop_a_src++;
30105       v_flags = t_0;
30106     }
30107     if ((v_flags & 128) != 0) {
30108       self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3)) << (1 + (v_flags & 7)));
30109       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30110       if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30111         self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30112         iop_a_src = io2_a_src;
30113         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30114         goto suspend;
30115       }
30116       iop_a_src += self->private_data.s_skip_frame[0].scratch;
30117     }
30118     {
30119       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30120       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30121         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30122         goto suspend;
30123       }
30124       uint8_t t_1 = *iop_a_src++;
30125       v_lw = t_1;
30126     }
30127     if (v_lw > 8) {
30128       status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
30129       goto exit;
30130     }
30131     if (a_src) {
30132       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30133     }
30134     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30135     status = wuffs_gif__decoder__skip_blocks(self, a_src);
30136     if (a_src) {
30137       iop_a_src = a_src->data.ptr + a_src->meta.ri;
30138     }
30139     if (status.repr) {
30140       goto suspend;
30141     }
30142     if (self->private_impl.f_quirks[0]) {
30143       self->private_impl.f_delayed_num_decoded_frames = true;
30144     } else {
30145       wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30146     }
30147     wuffs_gif__decoder__reset_gc(self);
30148 
30149     goto ok;
30150     ok:
30151     self->private_impl.p_skip_frame[0] = 0;
30152     goto exit;
30153   }
30154 
30155   goto suspend;
30156   suspend:
30157   self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30158 
30159   goto exit;
30160   exit:
30161   if (a_src) {
30162     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30163   }
30164 
30165   return status;
30166 }
30167 
30168 // -------- func gif.decoder.decode_frame
30169 
30170 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)30171 wuffs_gif__decoder__decode_frame(
30172     wuffs_gif__decoder* self,
30173     wuffs_base__pixel_buffer* a_dst,
30174     wuffs_base__io_buffer* a_src,
30175     wuffs_base__pixel_blend a_blend,
30176     wuffs_base__slice_u8 a_workbuf,
30177     wuffs_base__decode_frame_options* a_opts) {
30178   if (!self) {
30179     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30180   }
30181   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30182     return wuffs_base__make_status(
30183         (self->private_impl.magic == WUFFS_BASE__DISABLED)
30184         ? wuffs_base__error__disabled_by_previous_error
30185         : wuffs_base__error__initialize_not_called);
30186   }
30187   if (!a_dst || !a_src) {
30188     self->private_impl.magic = WUFFS_BASE__DISABLED;
30189     return wuffs_base__make_status(wuffs_base__error__bad_argument);
30190   }
30191   if ((self->private_impl.active_coroutine != 0) &&
30192       (self->private_impl.active_coroutine != 4)) {
30193     self->private_impl.magic = WUFFS_BASE__DISABLED;
30194     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
30195   }
30196   self->private_impl.active_coroutine = 0;
30197   wuffs_base__status status = wuffs_base__make_status(NULL);
30198 
30199   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
30200   switch (coro_susp_point) {
30201     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30202 
30203     self->private_impl.f_ignore_metadata = true;
30204     if (self->private_impl.f_call_sequence != 4) {
30205       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30206       status = wuffs_gif__decoder__decode_frame_config(self, NULL, a_src);
30207       if (status.repr) {
30208         goto suspend;
30209       }
30210     }
30211     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))) {
30212       status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size);
30213       goto exit;
30214     }
30215     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30216     status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
30217     if (status.repr) {
30218       goto suspend;
30219     }
30220     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30221     status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
30222     if (status.repr) {
30223       goto suspend;
30224     }
30225     wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30226     wuffs_gif__decoder__reset_gc(self);
30227 
30228     goto ok;
30229     ok:
30230     self->private_impl.p_decode_frame[0] = 0;
30231     goto exit;
30232   }
30233 
30234   goto suspend;
30235   suspend:
30236   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30237   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
30238 
30239   goto exit;
30240   exit:
30241   if (wuffs_base__status__is_error(&status)) {
30242     self->private_impl.magic = WUFFS_BASE__DISABLED;
30243   }
30244   return status;
30245 }
30246 
30247 // -------- func gif.decoder.reset_gc
30248 
30249 static wuffs_base__empty_struct
wuffs_gif__decoder__reset_gc(wuffs_gif__decoder * self)30250 wuffs_gif__decoder__reset_gc(
30251     wuffs_gif__decoder* self) {
30252   self->private_impl.f_call_sequence = 5;
30253   self->private_impl.f_gc_has_transparent_index = false;
30254   self->private_impl.f_gc_transparent_index = 0;
30255   self->private_impl.f_gc_disposal = 0;
30256   self->private_impl.f_gc_duration = 0;
30257   return wuffs_base__make_empty_struct();
30258 }
30259 
30260 // -------- func gif.decoder.decode_up_to_id_part1
30261 
30262 static wuffs_base__status
wuffs_gif__decoder__decode_up_to_id_part1(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30263 wuffs_gif__decoder__decode_up_to_id_part1(
30264     wuffs_gif__decoder* self,
30265     wuffs_base__io_buffer* a_src) {
30266   wuffs_base__status status = wuffs_base__make_status(NULL);
30267 
30268   uint8_t v_block_type = 0;
30269 
30270   const uint8_t* iop_a_src = NULL;
30271   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30272   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30273   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30274   if (a_src) {
30275     io0_a_src = a_src->data.ptr;
30276     io1_a_src = io0_a_src + a_src->meta.ri;
30277     iop_a_src = io1_a_src;
30278     io2_a_src = io0_a_src + a_src->meta.wi;
30279   }
30280 
30281   uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
30282   switch (coro_susp_point) {
30283     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30284 
30285     if ( ! self->private_impl.f_restarted) {
30286       if (self->private_impl.f_call_sequence != 2) {
30287         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)));
30288       }
30289     } 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)))) {
30290       status = wuffs_base__make_status(wuffs_base__error__bad_restart);
30291       goto exit;
30292     } else {
30293       self->private_impl.f_restarted = false;
30294     }
30295     while (true) {
30296       {
30297         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30298         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30299           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30300           goto suspend;
30301         }
30302         uint8_t t_0 = *iop_a_src++;
30303         v_block_type = t_0;
30304       }
30305       if (v_block_type == 33) {
30306         if (a_src) {
30307           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30308         }
30309         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30310         status = wuffs_gif__decoder__decode_extension(self, a_src);
30311         if (a_src) {
30312           iop_a_src = a_src->data.ptr + a_src->meta.ri;
30313         }
30314         if (status.repr) {
30315           goto suspend;
30316         }
30317       } else if (v_block_type == 44) {
30318         if (self->private_impl.f_delayed_num_decoded_frames) {
30319           self->private_impl.f_delayed_num_decoded_frames = false;
30320           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30321         }
30322         if (a_src) {
30323           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30324         }
30325         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30326         status = wuffs_gif__decoder__decode_id_part0(self, a_src);
30327         if (a_src) {
30328           iop_a_src = a_src->data.ptr + a_src->meta.ri;
30329         }
30330         if (status.repr) {
30331           goto suspend;
30332         }
30333         goto label__0__break;
30334       } else {
30335         if (self->private_impl.f_delayed_num_decoded_frames) {
30336           self->private_impl.f_delayed_num_decoded_frames = false;
30337           wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30338         }
30339         self->private_impl.f_end_of_data = true;
30340         goto label__0__break;
30341       }
30342     }
30343     label__0__break:;
30344 
30345     goto ok;
30346     ok:
30347     self->private_impl.p_decode_up_to_id_part1[0] = 0;
30348     goto exit;
30349   }
30350 
30351   goto suspend;
30352   suspend:
30353   self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30354 
30355   goto exit;
30356   exit:
30357   if (a_src) {
30358     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30359   }
30360 
30361   return status;
30362 }
30363 
30364 // -------- func gif.decoder.decode_header
30365 
30366 static wuffs_base__status
wuffs_gif__decoder__decode_header(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30367 wuffs_gif__decoder__decode_header(
30368     wuffs_gif__decoder* self,
30369     wuffs_base__io_buffer* a_src) {
30370   wuffs_base__status status = wuffs_base__make_status(NULL);
30371 
30372   uint8_t v_c[6] = {0};
30373   uint32_t v_i = 0;
30374 
30375   const uint8_t* iop_a_src = NULL;
30376   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30377   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30378   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30379   if (a_src) {
30380     io0_a_src = a_src->data.ptr;
30381     io1_a_src = io0_a_src + a_src->meta.ri;
30382     iop_a_src = io1_a_src;
30383     io2_a_src = io0_a_src + a_src->meta.wi;
30384   }
30385 
30386   uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
30387   if (coro_susp_point) {
30388     memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
30389     v_i = self->private_data.s_decode_header[0].v_i;
30390   }
30391   switch (coro_susp_point) {
30392     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30393 
30394     while (v_i < 6) {
30395       {
30396         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30397         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30398           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30399           goto suspend;
30400         }
30401         uint8_t t_0 = *iop_a_src++;
30402         v_c[v_i] = t_0;
30403       }
30404       v_i += 1;
30405     }
30406     if ((v_c[0] != 71) ||
30407         (v_c[1] != 73) ||
30408         (v_c[2] != 70) ||
30409         (v_c[3] != 56) ||
30410         ((v_c[4] != 55) && (v_c[4] != 57)) ||
30411         (v_c[5] != 97)) {
30412       status = wuffs_base__make_status(wuffs_gif__error__bad_header);
30413       goto exit;
30414     }
30415 
30416     goto ok;
30417     ok:
30418     self->private_impl.p_decode_header[0] = 0;
30419     goto exit;
30420   }
30421 
30422   goto suspend;
30423   suspend:
30424   self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30425   memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
30426   self->private_data.s_decode_header[0].v_i = v_i;
30427 
30428   goto exit;
30429   exit:
30430   if (a_src) {
30431     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30432   }
30433 
30434   return status;
30435 }
30436 
30437 // -------- func gif.decoder.decode_lsd
30438 
30439 static wuffs_base__status
wuffs_gif__decoder__decode_lsd(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30440 wuffs_gif__decoder__decode_lsd(
30441     wuffs_gif__decoder* self,
30442     wuffs_base__io_buffer* a_src) {
30443   wuffs_base__status status = wuffs_base__make_status(NULL);
30444 
30445   uint8_t v_flags = 0;
30446   uint8_t v_background_color_index = 0;
30447   uint32_t v_num_palette_entries = 0;
30448   uint32_t v_i = 0;
30449   uint32_t v_j = 0;
30450   uint32_t v_argb = 0;
30451 
30452   const uint8_t* iop_a_src = NULL;
30453   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30454   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30455   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30456   if (a_src) {
30457     io0_a_src = a_src->data.ptr;
30458     io1_a_src = io0_a_src + a_src->meta.ri;
30459     iop_a_src = io1_a_src;
30460     io2_a_src = io0_a_src + a_src->meta.wi;
30461   }
30462 
30463   uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
30464   if (coro_susp_point) {
30465     v_flags = self->private_data.s_decode_lsd[0].v_flags;
30466     v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index;
30467     v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries;
30468     v_i = self->private_data.s_decode_lsd[0].v_i;
30469   }
30470   switch (coro_susp_point) {
30471     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30472 
30473     {
30474       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30475       uint32_t t_0;
30476       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30477         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30478         iop_a_src += 2;
30479       } else {
30480         self->private_data.s_decode_lsd[0].scratch = 0;
30481         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30482         while (true) {
30483           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30484             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30485             goto suspend;
30486           }
30487           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30488           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
30489           *scratch <<= 8;
30490           *scratch >>= 8;
30491           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
30492           if (num_bits_0 == 8) {
30493             t_0 = ((uint32_t)(*scratch));
30494             break;
30495           }
30496           num_bits_0 += 8;
30497           *scratch |= ((uint64_t)(num_bits_0)) << 56;
30498         }
30499       }
30500       self->private_impl.f_width = t_0;
30501     }
30502     {
30503       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30504       uint32_t t_1;
30505       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30506         t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30507         iop_a_src += 2;
30508       } else {
30509         self->private_data.s_decode_lsd[0].scratch = 0;
30510         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30511         while (true) {
30512           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30513             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30514             goto suspend;
30515           }
30516           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30517           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
30518           *scratch <<= 8;
30519           *scratch >>= 8;
30520           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
30521           if (num_bits_1 == 8) {
30522             t_1 = ((uint32_t)(*scratch));
30523             break;
30524           }
30525           num_bits_1 += 8;
30526           *scratch |= ((uint64_t)(num_bits_1)) << 56;
30527         }
30528       }
30529       self->private_impl.f_height = t_1;
30530     }
30531     {
30532       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30533       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30534         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30535         goto suspend;
30536       }
30537       uint8_t t_2 = *iop_a_src++;
30538       v_flags = t_2;
30539     }
30540     {
30541       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30542       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30543         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30544         goto suspend;
30545       }
30546       uint8_t t_3 = *iop_a_src++;
30547       v_background_color_index = t_3;
30548     }
30549     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
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     iop_a_src++;
30555     v_i = 0;
30556     self->private_impl.f_has_global_palette = ((v_flags & 128) != 0);
30557     if (self->private_impl.f_has_global_palette) {
30558       v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
30559       while (v_i < v_num_palette_entries) {
30560         {
30561           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30562           uint32_t t_4;
30563           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
30564             t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
30565             iop_a_src += 3;
30566           } else {
30567             self->private_data.s_decode_lsd[0].scratch = 0;
30568             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
30569             while (true) {
30570               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30571                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30572                 goto suspend;
30573               }
30574               uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30575               uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
30576               *scratch >>= 8;
30577               *scratch <<= 8;
30578               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
30579               if (num_bits_4 == 16) {
30580                 t_4 = ((uint32_t)(*scratch >> 40));
30581                 break;
30582               }
30583               num_bits_4 += 8;
30584               *scratch |= ((uint64_t)(num_bits_4));
30585             }
30586           }
30587           v_argb = t_4;
30588         }
30589         v_argb |= 4278190080;
30590         self->private_data.f_palettes[0][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
30591         self->private_data.f_palettes[0][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
30592         self->private_data.f_palettes[0][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
30593         self->private_data.f_palettes[0][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
30594         v_i += 1;
30595       }
30596       if (self->private_impl.f_quirks[2]) {
30597         if ((v_background_color_index != 0) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
30598           v_j = (4 * ((uint32_t)(v_background_color_index)));
30599           self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0][(v_j + 0)])) << 0) |
30600               (((uint32_t)(self->private_data.f_palettes[0][(v_j + 1)])) << 8) |
30601               (((uint32_t)(self->private_data.f_palettes[0][(v_j + 2)])) << 16) |
30602               (((uint32_t)(self->private_data.f_palettes[0][(v_j + 3)])) << 24));
30603         } else {
30604           self->private_impl.f_background_color_u32_argb_premul = 77;
30605         }
30606       }
30607     }
30608     while (v_i < 256) {
30609       self->private_data.f_palettes[0][((4 * v_i) + 0)] = 0;
30610       self->private_data.f_palettes[0][((4 * v_i) + 1)] = 0;
30611       self->private_data.f_palettes[0][((4 * v_i) + 2)] = 0;
30612       self->private_data.f_palettes[0][((4 * v_i) + 3)] = 255;
30613       v_i += 1;
30614     }
30615 
30616     goto ok;
30617     ok:
30618     self->private_impl.p_decode_lsd[0] = 0;
30619     goto exit;
30620   }
30621 
30622   goto suspend;
30623   suspend:
30624   self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30625   self->private_data.s_decode_lsd[0].v_flags = v_flags;
30626   self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index;
30627   self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries;
30628   self->private_data.s_decode_lsd[0].v_i = v_i;
30629 
30630   goto exit;
30631   exit:
30632   if (a_src) {
30633     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30634   }
30635 
30636   return status;
30637 }
30638 
30639 // -------- func gif.decoder.decode_extension
30640 
30641 static wuffs_base__status
wuffs_gif__decoder__decode_extension(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30642 wuffs_gif__decoder__decode_extension(
30643     wuffs_gif__decoder* self,
30644     wuffs_base__io_buffer* a_src) {
30645   wuffs_base__status status = wuffs_base__make_status(NULL);
30646 
30647   uint8_t v_label = 0;
30648 
30649   const uint8_t* iop_a_src = NULL;
30650   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30651   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30652   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30653   if (a_src) {
30654     io0_a_src = a_src->data.ptr;
30655     io1_a_src = io0_a_src + a_src->meta.ri;
30656     iop_a_src = io1_a_src;
30657     io2_a_src = io0_a_src + a_src->meta.wi;
30658   }
30659 
30660   uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
30661   switch (coro_susp_point) {
30662     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30663 
30664     {
30665       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30666       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30667         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30668         goto suspend;
30669       }
30670       uint8_t t_0 = *iop_a_src++;
30671       v_label = t_0;
30672     }
30673     if (v_label == 249) {
30674       if (a_src) {
30675         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30676       }
30677       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30678       status = wuffs_gif__decoder__decode_gc(self, a_src);
30679       if (a_src) {
30680         iop_a_src = a_src->data.ptr + a_src->meta.ri;
30681       }
30682       if (status.repr) {
30683         goto suspend;
30684       }
30685       status = wuffs_base__make_status(NULL);
30686       goto ok;
30687     } else if (v_label == 255) {
30688       if (a_src) {
30689         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30690       }
30691       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30692       status = wuffs_gif__decoder__decode_ae(self, a_src);
30693       if (a_src) {
30694         iop_a_src = a_src->data.ptr + a_src->meta.ri;
30695       }
30696       if (status.repr) {
30697         goto suspend;
30698       }
30699       status = wuffs_base__make_status(NULL);
30700       goto ok;
30701     }
30702     if (a_src) {
30703       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30704     }
30705     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30706     status = wuffs_gif__decoder__skip_blocks(self, a_src);
30707     if (a_src) {
30708       iop_a_src = a_src->data.ptr + a_src->meta.ri;
30709     }
30710     if (status.repr) {
30711       goto suspend;
30712     }
30713 
30714     ok:
30715     self->private_impl.p_decode_extension[0] = 0;
30716     goto exit;
30717   }
30718 
30719   goto suspend;
30720   suspend:
30721   self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30722 
30723   goto exit;
30724   exit:
30725   if (a_src) {
30726     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30727   }
30728 
30729   return status;
30730 }
30731 
30732 // -------- func gif.decoder.skip_blocks
30733 
30734 static wuffs_base__status
wuffs_gif__decoder__skip_blocks(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30735 wuffs_gif__decoder__skip_blocks(
30736     wuffs_gif__decoder* self,
30737     wuffs_base__io_buffer* a_src) {
30738   wuffs_base__status status = wuffs_base__make_status(NULL);
30739 
30740   uint8_t v_block_size = 0;
30741 
30742   const uint8_t* iop_a_src = NULL;
30743   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30744   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30745   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30746   if (a_src) {
30747     io0_a_src = a_src->data.ptr;
30748     io1_a_src = io0_a_src + a_src->meta.ri;
30749     iop_a_src = io1_a_src;
30750     io2_a_src = io0_a_src + a_src->meta.wi;
30751   }
30752 
30753   uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
30754   switch (coro_susp_point) {
30755     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30756 
30757     while (true) {
30758       {
30759         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30760         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30761           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30762           goto suspend;
30763         }
30764         uint8_t t_0 = *iop_a_src++;
30765         v_block_size = t_0;
30766       }
30767       if (v_block_size == 0) {
30768         status = wuffs_base__make_status(NULL);
30769         goto ok;
30770       }
30771       self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
30772       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30773       if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30774         self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30775         iop_a_src = io2_a_src;
30776         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30777         goto suspend;
30778       }
30779       iop_a_src += self->private_data.s_skip_blocks[0].scratch;
30780     }
30781 
30782     ok:
30783     self->private_impl.p_skip_blocks[0] = 0;
30784     goto exit;
30785   }
30786 
30787   goto suspend;
30788   suspend:
30789   self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30790 
30791   goto exit;
30792   exit:
30793   if (a_src) {
30794     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30795   }
30796 
30797   return status;
30798 }
30799 
30800 // -------- func gif.decoder.decode_ae
30801 
30802 static wuffs_base__status
wuffs_gif__decoder__decode_ae(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30803 wuffs_gif__decoder__decode_ae(
30804     wuffs_gif__decoder* self,
30805     wuffs_base__io_buffer* a_src) {
30806   wuffs_base__status status = wuffs_base__make_status(NULL);
30807 
30808   uint8_t v_c = 0;
30809   uint8_t v_block_size = 0;
30810   bool v_is_animexts = false;
30811   bool v_is_netscape = false;
30812   bool v_is_iccp = false;
30813   bool v_is_xmp = false;
30814 
30815   const uint8_t* iop_a_src = NULL;
30816   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30817   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30818   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30819   if (a_src) {
30820     io0_a_src = a_src->data.ptr;
30821     io1_a_src = io0_a_src + a_src->meta.ri;
30822     iop_a_src = io1_a_src;
30823     io2_a_src = io0_a_src + a_src->meta.wi;
30824   }
30825 
30826   uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
30827   if (coro_susp_point) {
30828     v_block_size = self->private_data.s_decode_ae[0].v_block_size;
30829     v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
30830     v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
30831     v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
30832     v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
30833   }
30834   switch (coro_susp_point) {
30835     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30836 
30837     while (true) {
30838       if (self->private_impl.f_metadata_fourcc != 0) {
30839         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30840         goto ok;
30841       }
30842       {
30843         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30844         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30845           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30846           goto suspend;
30847         }
30848         uint8_t t_0 = *iop_a_src++;
30849         v_block_size = t_0;
30850       }
30851       if (v_block_size == 0) {
30852         status = wuffs_base__make_status(NULL);
30853         goto ok;
30854       }
30855       if (v_block_size != 11) {
30856         self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
30857         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30858         if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30859           self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30860           iop_a_src = io2_a_src;
30861           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30862           goto suspend;
30863         }
30864         iop_a_src += self->private_data.s_decode_ae[0].scratch;
30865         goto label__goto_done__break;
30866       }
30867       v_is_animexts = true;
30868       v_is_netscape = true;
30869       v_is_iccp = true;
30870       v_is_xmp = true;
30871       v_block_size = 0;
30872       while (v_block_size < 11) {
30873         {
30874           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30875           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30876             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30877             goto suspend;
30878           }
30879           uint8_t t_1 = *iop_a_src++;
30880           v_c = t_1;
30881         }
30882         v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
30883         v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
30884         v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size]));
30885         v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size]));
30886 #if defined(__GNUC__)
30887 #pragma GCC diagnostic push
30888 #pragma GCC diagnostic ignored "-Wconversion"
30889 #endif
30890         v_block_size += 1;
30891 #if defined(__GNUC__)
30892 #pragma GCC diagnostic pop
30893 #endif
30894       }
30895       if (v_is_animexts || v_is_netscape) {
30896         {
30897           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30898           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30899             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30900             goto suspend;
30901           }
30902           uint8_t t_2 = *iop_a_src++;
30903           v_block_size = t_2;
30904         }
30905         if (v_block_size != 3) {
30906           self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
30907           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30908           if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30909             self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30910             iop_a_src = io2_a_src;
30911             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30912             goto suspend;
30913           }
30914           iop_a_src += self->private_data.s_decode_ae[0].scratch;
30915           goto label__goto_done__break;
30916         }
30917         {
30918           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30919           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30920             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30921             goto suspend;
30922           }
30923           uint8_t t_3 = *iop_a_src++;
30924           v_c = t_3;
30925         }
30926         if (v_c != 1) {
30927           self->private_data.s_decode_ae[0].scratch = 2;
30928           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
30929           if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30930             self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30931             iop_a_src = io2_a_src;
30932             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30933             goto suspend;
30934           }
30935           iop_a_src += self->private_data.s_decode_ae[0].scratch;
30936           goto label__goto_done__break;
30937         }
30938         {
30939           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30940           uint32_t t_4;
30941           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30942             t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30943             iop_a_src += 2;
30944           } else {
30945             self->private_data.s_decode_ae[0].scratch = 0;
30946             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
30947             while (true) {
30948               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30949                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30950                 goto suspend;
30951               }
30952               uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
30953               uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
30954               *scratch <<= 8;
30955               *scratch >>= 8;
30956               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
30957               if (num_bits_4 == 8) {
30958                 t_4 = ((uint32_t)(*scratch));
30959                 break;
30960               }
30961               num_bits_4 += 8;
30962               *scratch |= ((uint64_t)(num_bits_4)) << 56;
30963             }
30964           }
30965           self->private_impl.f_num_animation_loops_value = t_4;
30966         }
30967         self->private_impl.f_seen_num_animation_loops_value = true;
30968         if ((0 < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535)) {
30969           self->private_impl.f_num_animation_loops_value += 1;
30970         }
30971       } else if (self->private_impl.f_ignore_metadata) {
30972       } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
30973         self->private_impl.f_metadata_fourcc = 1229144912;
30974         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)));
30975         self->private_impl.f_call_sequence = 1;
30976         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30977         goto ok;
30978       } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
30979         self->private_impl.f_metadata_fourcc = 1481461792;
30980         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)));
30981         self->private_impl.f_call_sequence = 1;
30982         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30983         goto ok;
30984       }
30985       goto label__goto_done__break;
30986     }
30987     label__goto_done__break:;
30988     if (a_src) {
30989       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30990     }
30991     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
30992     status = wuffs_gif__decoder__skip_blocks(self, a_src);
30993     if (a_src) {
30994       iop_a_src = a_src->data.ptr + a_src->meta.ri;
30995     }
30996     if (status.repr) {
30997       goto suspend;
30998     }
30999 
31000     ok:
31001     self->private_impl.p_decode_ae[0] = 0;
31002     goto exit;
31003   }
31004 
31005   goto suspend;
31006   suspend:
31007   self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31008   self->private_data.s_decode_ae[0].v_block_size = v_block_size;
31009   self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
31010   self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
31011   self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
31012   self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
31013 
31014   goto exit;
31015   exit:
31016   if (a_src) {
31017     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31018   }
31019 
31020   return status;
31021 }
31022 
31023 // -------- func gif.decoder.decode_gc
31024 
31025 static wuffs_base__status
wuffs_gif__decoder__decode_gc(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)31026 wuffs_gif__decoder__decode_gc(
31027     wuffs_gif__decoder* self,
31028     wuffs_base__io_buffer* a_src) {
31029   wuffs_base__status status = wuffs_base__make_status(NULL);
31030 
31031   uint8_t v_c = 0;
31032   uint8_t v_flags = 0;
31033   uint16_t v_gc_duration_centiseconds = 0;
31034 
31035   const uint8_t* iop_a_src = NULL;
31036   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31037   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31038   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31039   if (a_src) {
31040     io0_a_src = a_src->data.ptr;
31041     io1_a_src = io0_a_src + a_src->meta.ri;
31042     iop_a_src = io1_a_src;
31043     io2_a_src = io0_a_src + a_src->meta.wi;
31044   }
31045 
31046   uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
31047   switch (coro_susp_point) {
31048     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31049 
31050     {
31051       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31052       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31053         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31054         goto suspend;
31055       }
31056       uint8_t t_0 = *iop_a_src++;
31057       v_c = t_0;
31058     }
31059     if (v_c != 4) {
31060       status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
31061       goto exit;
31062     }
31063     {
31064       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31065       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31066         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31067         goto suspend;
31068       }
31069       uint8_t t_1 = *iop_a_src++;
31070       v_flags = t_1;
31071     }
31072     self->private_impl.f_gc_has_transparent_index = ((v_flags & 1) != 0);
31073     v_flags = ((v_flags >> 2) & 7);
31074     if (v_flags == 2) {
31075       self->private_impl.f_gc_disposal = 1;
31076     } else if ((v_flags == 3) || (v_flags == 4)) {
31077       self->private_impl.f_gc_disposal = 2;
31078     } else {
31079       self->private_impl.f_gc_disposal = 0;
31080     }
31081     {
31082       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31083       uint16_t t_2;
31084       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31085         t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
31086         iop_a_src += 2;
31087       } else {
31088         self->private_data.s_decode_gc[0].scratch = 0;
31089         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31090         while (true) {
31091           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31092             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31093             goto suspend;
31094           }
31095           uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
31096           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
31097           *scratch <<= 8;
31098           *scratch >>= 8;
31099           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
31100           if (num_bits_2 == 8) {
31101             t_2 = ((uint16_t)(*scratch));
31102             break;
31103           }
31104           num_bits_2 += 8;
31105           *scratch |= ((uint64_t)(num_bits_2)) << 56;
31106         }
31107       }
31108       v_gc_duration_centiseconds = t_2;
31109     }
31110     self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000);
31111     {
31112       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31113       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31114         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31115         goto suspend;
31116       }
31117       uint8_t t_3 = *iop_a_src++;
31118       self->private_impl.f_gc_transparent_index = t_3;
31119     }
31120     {
31121       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31122       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31123         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31124         goto suspend;
31125       }
31126       uint8_t t_4 = *iop_a_src++;
31127       v_c = t_4;
31128     }
31129     if (v_c != 0) {
31130       status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
31131       goto exit;
31132     }
31133 
31134     goto ok;
31135     ok:
31136     self->private_impl.p_decode_gc[0] = 0;
31137     goto exit;
31138   }
31139 
31140   goto suspend;
31141   suspend:
31142   self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31143 
31144   goto exit;
31145   exit:
31146   if (a_src) {
31147     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31148   }
31149 
31150   return status;
31151 }
31152 
31153 // -------- func gif.decoder.decode_id_part0
31154 
31155 static wuffs_base__status
wuffs_gif__decoder__decode_id_part0(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)31156 wuffs_gif__decoder__decode_id_part0(
31157     wuffs_gif__decoder* self,
31158     wuffs_base__io_buffer* a_src) {
31159   wuffs_base__status status = wuffs_base__make_status(NULL);
31160 
31161   const uint8_t* iop_a_src = NULL;
31162   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31163   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31164   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31165   if (a_src) {
31166     io0_a_src = a_src->data.ptr;
31167     io1_a_src = io0_a_src + a_src->meta.ri;
31168     iop_a_src = io1_a_src;
31169     io2_a_src = io0_a_src + a_src->meta.wi;
31170   }
31171 
31172   uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
31173   switch (coro_susp_point) {
31174     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31175 
31176     {
31177       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31178       uint32_t t_0;
31179       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31180         t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31181         iop_a_src += 2;
31182       } else {
31183         self->private_data.s_decode_id_part0[0].scratch = 0;
31184         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31185         while (true) {
31186           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31187             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31188             goto suspend;
31189           }
31190           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31191           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
31192           *scratch <<= 8;
31193           *scratch >>= 8;
31194           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
31195           if (num_bits_0 == 8) {
31196             t_0 = ((uint32_t)(*scratch));
31197             break;
31198           }
31199           num_bits_0 += 8;
31200           *scratch |= ((uint64_t)(num_bits_0)) << 56;
31201         }
31202       }
31203       self->private_impl.f_frame_rect_x0 = t_0;
31204     }
31205     {
31206       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31207       uint32_t t_1;
31208       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31209         t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31210         iop_a_src += 2;
31211       } else {
31212         self->private_data.s_decode_id_part0[0].scratch = 0;
31213         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31214         while (true) {
31215           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31216             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31217             goto suspend;
31218           }
31219           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31220           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
31221           *scratch <<= 8;
31222           *scratch >>= 8;
31223           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
31224           if (num_bits_1 == 8) {
31225             t_1 = ((uint32_t)(*scratch));
31226             break;
31227           }
31228           num_bits_1 += 8;
31229           *scratch |= ((uint64_t)(num_bits_1)) << 56;
31230         }
31231       }
31232       self->private_impl.f_frame_rect_y0 = t_1;
31233     }
31234     {
31235       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31236       uint32_t t_2;
31237       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31238         t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31239         iop_a_src += 2;
31240       } else {
31241         self->private_data.s_decode_id_part0[0].scratch = 0;
31242         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31243         while (true) {
31244           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31245             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31246             goto suspend;
31247           }
31248           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31249           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
31250           *scratch <<= 8;
31251           *scratch >>= 8;
31252           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
31253           if (num_bits_2 == 8) {
31254             t_2 = ((uint32_t)(*scratch));
31255             break;
31256           }
31257           num_bits_2 += 8;
31258           *scratch |= ((uint64_t)(num_bits_2)) << 56;
31259         }
31260       }
31261       self->private_impl.f_frame_rect_x1 = t_2;
31262     }
31263     self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
31264     {
31265       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
31266       uint32_t t_3;
31267       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31268         t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31269         iop_a_src += 2;
31270       } else {
31271         self->private_data.s_decode_id_part0[0].scratch = 0;
31272         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
31273         while (true) {
31274           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31275             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31276             goto suspend;
31277           }
31278           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31279           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
31280           *scratch <<= 8;
31281           *scratch >>= 8;
31282           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
31283           if (num_bits_3 == 8) {
31284             t_3 = ((uint32_t)(*scratch));
31285             break;
31286           }
31287           num_bits_3 += 8;
31288           *scratch |= ((uint64_t)(num_bits_3)) << 56;
31289         }
31290       }
31291       self->private_impl.f_frame_rect_y1 = t_3;
31292     }
31293     self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
31294     self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31295     self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
31296     if ((self->private_impl.f_call_sequence == 0) &&  ! self->private_impl.f_quirks[4]) {
31297       self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
31298       self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
31299     }
31300 
31301     goto ok;
31302     ok:
31303     self->private_impl.p_decode_id_part0[0] = 0;
31304     goto exit;
31305   }
31306 
31307   goto suspend;
31308   suspend:
31309   self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31310 
31311   goto exit;
31312   exit:
31313   if (a_src) {
31314     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31315   }
31316 
31317   return status;
31318 }
31319 
31320 // -------- func gif.decoder.decode_id_part1
31321 
31322 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)31323 wuffs_gif__decoder__decode_id_part1(
31324     wuffs_gif__decoder* self,
31325     wuffs_base__pixel_buffer* a_dst,
31326     wuffs_base__io_buffer* a_src,
31327     wuffs_base__pixel_blend a_blend) {
31328   wuffs_base__status status = wuffs_base__make_status(NULL);
31329 
31330   uint8_t v_flags = 0;
31331   uint8_t v_which_palette = 0;
31332   uint32_t v_num_palette_entries = 0;
31333   uint32_t v_i = 0;
31334   uint32_t v_argb = 0;
31335   wuffs_base__status v_status = wuffs_base__make_status(NULL);
31336   uint8_t v_lw = 0;
31337 
31338   const uint8_t* iop_a_src = NULL;
31339   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31340   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31341   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31342   if (a_src) {
31343     io0_a_src = a_src->data.ptr;
31344     io1_a_src = io0_a_src + a_src->meta.ri;
31345     iop_a_src = io1_a_src;
31346     io2_a_src = io0_a_src + a_src->meta.wi;
31347   }
31348 
31349   uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0];
31350   if (coro_susp_point) {
31351     v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette;
31352     v_num_palette_entries = self->private_data.s_decode_id_part1[0].v_num_palette_entries;
31353     v_i = self->private_data.s_decode_id_part1[0].v_i;
31354   }
31355   switch (coro_susp_point) {
31356     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31357 
31358     {
31359       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31360       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31361         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31362         goto suspend;
31363       }
31364       uint8_t t_0 = *iop_a_src++;
31365       v_flags = t_0;
31366     }
31367     if ((v_flags & 64) != 0) {
31368       self->private_impl.f_interlace = 4;
31369     } else {
31370       self->private_impl.f_interlace = 0;
31371     }
31372     v_which_palette = 1;
31373     if ((v_flags & 128) != 0) {
31374       v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
31375       v_i = 0;
31376       while (v_i < v_num_palette_entries) {
31377         {
31378           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31379           uint32_t t_1;
31380           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
31381             t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
31382             iop_a_src += 3;
31383           } else {
31384             self->private_data.s_decode_id_part1[0].scratch = 0;
31385             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31386             while (true) {
31387               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31388                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31389                 goto suspend;
31390               }
31391               uint64_t* scratch = &self->private_data.s_decode_id_part1[0].scratch;
31392               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
31393               *scratch >>= 8;
31394               *scratch <<= 8;
31395               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
31396               if (num_bits_1 == 16) {
31397                 t_1 = ((uint32_t)(*scratch >> 40));
31398                 break;
31399               }
31400               num_bits_1 += 8;
31401               *scratch |= ((uint64_t)(num_bits_1));
31402             }
31403           }
31404           v_argb = t_1;
31405         }
31406         v_argb |= 4278190080;
31407         self->private_data.f_palettes[1][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
31408         self->private_data.f_palettes[1][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
31409         self->private_data.f_palettes[1][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
31410         self->private_data.f_palettes[1][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
31411         v_i += 1;
31412       }
31413       while (v_i < 256) {
31414         self->private_data.f_palettes[1][((4 * v_i) + 0)] = 0;
31415         self->private_data.f_palettes[1][((4 * v_i) + 1)] = 0;
31416         self->private_data.f_palettes[1][((4 * v_i) + 2)] = 0;
31417         self->private_data.f_palettes[1][((4 * v_i) + 3)] = 255;
31418         v_i += 1;
31419       }
31420     } else if (self->private_impl.f_quirks[6] &&  ! self->private_impl.f_has_global_palette) {
31421       status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
31422       goto exit;
31423     } else if (self->private_impl.f_gc_has_transparent_index) {
31424       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));
31425     } else {
31426       v_which_palette = 0;
31427     }
31428     if (self->private_impl.f_gc_has_transparent_index) {
31429       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0)] = 0;
31430       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1)] = 0;
31431       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2)] = 0;
31432       self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3)] = 0;
31433     }
31434     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
31435         wuffs_base__pixel_buffer__pixel_format(a_dst),
31436         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
31437         wuffs_base__utility__make_pixel_format(2198077448),
31438         wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024),
31439         a_blend);
31440     if ( ! wuffs_base__status__is_ok(&v_status)) {
31441       status = v_status;
31442       if (wuffs_base__status__is_error(&status)) {
31443         goto exit;
31444       } else if (wuffs_base__status__is_suspension(&status)) {
31445         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
31446         goto exit;
31447       }
31448       goto ok;
31449     }
31450     if (self->private_impl.f_previous_lzw_decode_ended_abruptly) {
31451       wuffs_base__ignore_status(wuffs_lzw__decoder__initialize(&self->private_data.f_lzw,
31452           sizeof (wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
31453     }
31454     {
31455       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31456       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31457         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31458         goto suspend;
31459       }
31460       uint8_t t_2 = *iop_a_src++;
31461       v_lw = t_2;
31462     }
31463     if (v_lw > 8) {
31464       status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
31465       goto exit;
31466     }
31467     wuffs_lzw__decoder__set_literal_width(&self->private_data.f_lzw, ((uint32_t)(v_lw)));
31468     self->private_impl.f_previous_lzw_decode_ended_abruptly = true;
31469 
31470     ok:
31471     self->private_impl.p_decode_id_part1[0] = 0;
31472     goto exit;
31473   }
31474 
31475   goto suspend;
31476   suspend:
31477   self->private_impl.p_decode_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31478   self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette;
31479   self->private_data.s_decode_id_part1[0].v_num_palette_entries = v_num_palette_entries;
31480   self->private_data.s_decode_id_part1[0].v_i = v_i;
31481 
31482   goto exit;
31483   exit:
31484   if (a_src) {
31485     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31486   }
31487 
31488   return status;
31489 }
31490 
31491 // -------- func gif.decoder.decode_id_part2
31492 
31493 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)31494 wuffs_gif__decoder__decode_id_part2(
31495     wuffs_gif__decoder* self,
31496     wuffs_base__pixel_buffer* a_dst,
31497     wuffs_base__io_buffer* a_src,
31498     wuffs_base__slice_u8 a_workbuf) {
31499   wuffs_base__io_buffer empty_io_buffer = wuffs_base__empty_io_buffer();
31500 
31501   wuffs_base__status status = wuffs_base__make_status(NULL);
31502 
31503   uint64_t v_block_size = 0;
31504   bool v_need_block_size = false;
31505   uint32_t v_n_copied = 0;
31506   uint64_t v_n_compressed = 0;
31507   wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
31508   wuffs_base__io_buffer* v_r = &u_r;
31509   const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31510   const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31511   const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31512   const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31513   uint64_t v_mark = 0;
31514   wuffs_base__status v_lzw_status = wuffs_base__make_status(NULL);
31515   wuffs_base__status v_copy_status = wuffs_base__make_status(NULL);
31516   wuffs_base__slice_u8 v_uncompressed = {0};
31517 
31518   const uint8_t* iop_a_src = NULL;
31519   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31520   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31521   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31522   if (a_src) {
31523     io0_a_src = a_src->data.ptr;
31524     io1_a_src = io0_a_src + a_src->meta.ri;
31525     iop_a_src = io1_a_src;
31526     io2_a_src = io0_a_src + a_src->meta.wi;
31527   }
31528 
31529   uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0];
31530   if (coro_susp_point) {
31531     v_block_size = self->private_data.s_decode_id_part2[0].v_block_size;
31532     v_need_block_size = self->private_data.s_decode_id_part2[0].v_need_block_size;
31533     v_lzw_status = self->private_data.s_decode_id_part2[0].v_lzw_status;
31534   }
31535   switch (coro_susp_point) {
31536     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31537 
31538     v_need_block_size = true;
31539     label__outer__continue:;
31540     while (true) {
31541       if (v_need_block_size) {
31542         v_need_block_size = false;
31543         {
31544           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31545           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31546             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31547             goto suspend;
31548           }
31549           uint64_t t_0 = *iop_a_src++;
31550           v_block_size = t_0;
31551         }
31552       }
31553       if (v_block_size == 0) {
31554         goto label__outer__break;
31555       }
31556       while (((uint64_t)(io2_a_src - iop_a_src)) == 0) {
31557         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31558         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
31559       }
31560       if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) {
31561         self->private_impl.f_compressed_ri = 0;
31562         self->private_impl.f_compressed_wi = 0;
31563       }
31564       while (self->private_impl.f_compressed_wi <= 3841) {
31565         v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
31566         if (v_n_compressed <= 0) {
31567           goto label__0__break;
31568         }
31569         v_n_copied = wuffs_base__io_reader__limited_copy_u32_to_slice(
31570             &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));
31571         wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied)));
31572         wuffs_base__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied)));
31573         if (v_block_size > 0) {
31574           goto label__0__break;
31575         }
31576         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
31577           v_need_block_size = true;
31578           goto label__0__break;
31579         }
31580         v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
31581         iop_a_src += 1;
31582       }
31583       label__0__break:;
31584       label__inner__continue:;
31585       while (true) {
31586         if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096)) {
31587           status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31588           goto exit;
31589         }
31590         {
31591           wuffs_base__io_buffer* o_0_v_r = v_r;
31592           const uint8_t *o_0_iop_v_r = iop_v_r;
31593           const uint8_t *o_0_io0_v_r = io0_v_r;
31594           const uint8_t *o_0_io1_v_r = io1_v_r;
31595           const uint8_t *o_0_io2_v_r = io2_v_r;
31596           v_r = wuffs_base__io_reader__set(
31597               &u_r,
31598               &iop_v_r,
31599               &io0_v_r,
31600               &io1_v_r,
31601               &io2_v_r,
31602               wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_compressed,
31603               4096),
31604               self->private_impl.f_compressed_ri,
31605               self->private_impl.f_compressed_wi),
31606               0);
31607           v_mark = ((uint64_t)(iop_v_r - io0_v_r));
31608           {
31609             u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
31610             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());
31611             v_lzw_status = t_1;
31612             iop_v_r = u_r.data.ptr + u_r.meta.ri;
31613           }
31614           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))));
31615           v_r = o_0_v_r;
31616           iop_v_r = o_0_iop_v_r;
31617           io0_v_r = o_0_io0_v_r;
31618           io1_v_r = o_0_io1_v_r;
31619           io2_v_r = o_0_io2_v_r;
31620         }
31621         v_uncompressed = wuffs_lzw__decoder__flush(&self->private_data.f_lzw);
31622         if (((uint64_t)(v_uncompressed.len)) > 0) {
31623           v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(self, a_dst, v_uncompressed);
31624           if (wuffs_base__status__is_error(&v_copy_status)) {
31625             status = v_copy_status;
31626             goto exit;
31627           }
31628         }
31629         if (wuffs_base__status__is_ok(&v_lzw_status)) {
31630           self->private_impl.f_previous_lzw_decode_ended_abruptly = false;
31631           if (v_need_block_size || (v_block_size > 0)) {
31632             self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
31633             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31634             if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31635               self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31636               iop_a_src = io2_a_src;
31637               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31638               goto suspend;
31639             }
31640             iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
31641             if (a_src) {
31642               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31643             }
31644             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31645             status = wuffs_gif__decoder__skip_blocks(self, a_src);
31646             if (a_src) {
31647               iop_a_src = a_src->data.ptr + a_src->meta.ri;
31648             }
31649             if (status.repr) {
31650               goto suspend;
31651             }
31652           }
31653           goto label__outer__break;
31654         } else if (v_lzw_status.repr == wuffs_base__suspension__short_read) {
31655           goto label__outer__continue;
31656         } else if (v_lzw_status.repr == wuffs_base__suspension__short_write) {
31657           goto label__inner__continue;
31658         } else if (self->private_impl.f_quirks[3] && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) && (self->private_impl.f_interlace == 0)) {
31659           if (v_need_block_size || (v_block_size > 0)) {
31660             self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
31661             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31662             if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31663               self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31664               iop_a_src = io2_a_src;
31665               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31666               goto suspend;
31667             }
31668             iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
31669             if (a_src) {
31670               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31671             }
31672             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31673             status = wuffs_gif__decoder__skip_blocks(self, a_src);
31674             if (a_src) {
31675               iop_a_src = a_src->data.ptr + a_src->meta.ri;
31676             }
31677             if (status.repr) {
31678               goto suspend;
31679             }
31680           }
31681           goto label__outer__break;
31682         }
31683         status = v_lzw_status;
31684         if (wuffs_base__status__is_error(&status)) {
31685           goto exit;
31686         } else if (wuffs_base__status__is_suspension(&status)) {
31687           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
31688           goto exit;
31689         }
31690         goto ok;
31691       }
31692     }
31693     label__outer__break:;
31694     self->private_impl.f_compressed_ri = 0;
31695     self->private_impl.f_compressed_wi = 0;
31696     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)) {
31697       status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
31698       goto exit;
31699     }
31700 
31701     ok:
31702     self->private_impl.p_decode_id_part2[0] = 0;
31703     goto exit;
31704   }
31705 
31706   goto suspend;
31707   suspend:
31708   self->private_impl.p_decode_id_part2[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31709   self->private_data.s_decode_id_part2[0].v_block_size = v_block_size;
31710   self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size;
31711   self->private_data.s_decode_id_part2[0].v_lzw_status = v_lzw_status;
31712 
31713   goto exit;
31714   exit:
31715   if (a_src) {
31716     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31717   }
31718 
31719   return status;
31720 }
31721 
31722 // -------- func gif.decoder.copy_to_image_buffer
31723 
31724 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)31725 wuffs_gif__decoder__copy_to_image_buffer(
31726     wuffs_gif__decoder* self,
31727     wuffs_base__pixel_buffer* a_pb,
31728     wuffs_base__slice_u8 a_src) {
31729   wuffs_base__slice_u8 v_dst = {0};
31730   wuffs_base__slice_u8 v_src = {0};
31731   uint64_t v_width_in_bytes = 0;
31732   uint64_t v_n = 0;
31733   uint64_t v_src_ri = 0;
31734   wuffs_base__pixel_format v_pixfmt = {0};
31735   uint32_t v_bytes_per_pixel = 0;
31736   uint32_t v_bits_per_pixel = 0;
31737   wuffs_base__table_u8 v_tab = {0};
31738   uint64_t v_i = 0;
31739   uint64_t v_j = 0;
31740   uint32_t v_replicate_y0 = 0;
31741   uint32_t v_replicate_y1 = 0;
31742   wuffs_base__slice_u8 v_replicate_dst = {0};
31743   wuffs_base__slice_u8 v_replicate_src = {0};
31744 
31745   v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
31746   v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt);
31747   if ((v_bits_per_pixel & 7) != 0) {
31748     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
31749   }
31750   v_bytes_per_pixel = (v_bits_per_pixel >> 3);
31751   v_width_in_bytes = (((uint64_t)(self->private_impl.f_width)) * ((uint64_t)(v_bytes_per_pixel)));
31752   v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0);
31753   label__0__continue:;
31754   while (v_src_ri < ((uint64_t)(a_src.len))) {
31755     v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
31756     if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
31757       if (self->private_impl.f_quirks[3]) {
31758         return wuffs_base__make_status(NULL);
31759       }
31760       return wuffs_base__make_status(wuffs_base__error__too_much_data);
31761     }
31762     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
31763     if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
31764       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0);
31765     } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) {
31766       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes);
31767     }
31768     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel)));
31769     if (v_i < ((uint64_t)(v_dst.len))) {
31770       v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel)));
31771       if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
31772         v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
31773       } else {
31774         v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
31775       }
31776       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);
31777       wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
31778       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
31779       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));
31780     }
31781     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
31782       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31783       if (self->private_impl.f_interlace == 0) {
31784         wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1);
31785         goto label__0__continue;
31786       }
31787       if ((self->private_impl.f_num_decoded_frames_value == 0) &&  ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1)) {
31788         v_replicate_src = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
31789         v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1);
31790         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])));
31791         v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1);
31792         while (v_replicate_y0 < v_replicate_y1) {
31793           v_replicate_dst = wuffs_base__table_u8__row_u32(v_tab, v_replicate_y0);
31794           wuffs_base__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src);
31795           v_replicate_y0 += 1;
31796         }
31797         self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1);
31798       }
31799       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
31800       while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
31801 #if defined(__GNUC__)
31802 #pragma GCC diagnostic push
31803 #pragma GCC diagnostic ignored "-Wconversion"
31804 #endif
31805         self->private_impl.f_interlace -= 1;
31806 #if defined(__GNUC__)
31807 #pragma GCC diagnostic pop
31808 #endif
31809         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]);
31810       }
31811       goto label__0__continue;
31812     }
31813     if (((uint64_t)(a_src.len)) == v_src_ri) {
31814       goto label__0__break;
31815     } else if (((uint64_t)(a_src.len)) < v_src_ri) {
31816       return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31817     }
31818     v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
31819     v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
31820     wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
31821     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
31822     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
31823       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31824       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
31825       while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
31826 #if defined(__GNUC__)
31827 #pragma GCC diagnostic push
31828 #pragma GCC diagnostic ignored "-Wconversion"
31829 #endif
31830         self->private_impl.f_interlace -= 1;
31831 #if defined(__GNUC__)
31832 #pragma GCC diagnostic pop
31833 #endif
31834         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]);
31835       }
31836       goto label__0__continue;
31837     }
31838     if (v_src_ri != ((uint64_t)(a_src.len))) {
31839       return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31840     }
31841     goto label__0__break;
31842   }
31843   label__0__break:;
31844   return wuffs_base__make_status(NULL);
31845 }
31846 
31847 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
31848 
31849 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
31850 
31851 // ---------------- Status Codes Implementations
31852 
31853 const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum";
31854 const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method";
31855 const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags";
31856 const char wuffs_gzip__error__bad_header[] = "#gzip: bad header";
31857 
31858 // ---------------- Private Consts
31859 
31860 // ---------------- Private Initializer Prototypes
31861 
31862 // ---------------- Private Function Prototypes
31863 
31864 // ---------------- VTables
31865 
31866 const wuffs_base__io_transformer__func_ptrs
31867 wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
31868   (wuffs_base__empty_struct(*)(void*,
31869       uint32_t,
31870       bool))(&wuffs_gzip__decoder__set_quirk_enabled),
31871   (wuffs_base__status(*)(void*,
31872       wuffs_base__io_buffer*,
31873       wuffs_base__io_buffer*,
31874       wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io),
31875   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len),
31876 };
31877 
31878 // ---------------- Initializer Implementations
31879 
31880 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)31881 wuffs_gzip__decoder__initialize(
31882     wuffs_gzip__decoder* self,
31883     size_t sizeof_star_self,
31884     uint64_t wuffs_version,
31885     uint32_t options){
31886   if (!self) {
31887     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
31888   }
31889   if (sizeof(*self) != sizeof_star_self) {
31890     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
31891   }
31892   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
31893       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
31894     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
31895   }
31896 
31897   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
31898     // The whole point of this if-check is to detect an uninitialized *self.
31899     // We disable the warning on GCC. Clang-5.0 does not have this warning.
31900 #if !defined(__clang__) && defined(__GNUC__)
31901 #pragma GCC diagnostic push
31902 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
31903 #endif
31904     if (self->private_impl.magic != 0) {
31905       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
31906     }
31907 #if !defined(__clang__) && defined(__GNUC__)
31908 #pragma GCC diagnostic pop
31909 #endif
31910   } else {
31911     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
31912       memset(self, 0, sizeof(*self));
31913       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
31914     } else {
31915       memset(&(self->private_impl), 0, sizeof(self->private_impl));
31916     }
31917   }
31918 
31919   {
31920     wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
31921         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
31922     if (z.repr) {
31923       return z;
31924     }
31925   }
31926   {
31927     wuffs_base__status z = wuffs_deflate__decoder__initialize(
31928         &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
31929     if (z.repr) {
31930       return z;
31931     }
31932   }
31933   self->private_impl.magic = WUFFS_BASE__MAGIC;
31934   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
31935       wuffs_base__io_transformer__vtable_name;
31936   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
31937       (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
31938   return wuffs_base__make_status(NULL);
31939 }
31940 
31941 wuffs_gzip__decoder*
wuffs_gzip__decoder__alloc()31942 wuffs_gzip__decoder__alloc() {
31943   wuffs_gzip__decoder* x =
31944       (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
31945   if (!x) {
31946     return NULL;
31947   }
31948   if (wuffs_gzip__decoder__initialize(
31949       x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
31950     free(x);
31951     return NULL;
31952   }
31953   return x;
31954 }
31955 
31956 size_t
sizeof__wuffs_gzip__decoder()31957 sizeof__wuffs_gzip__decoder() {
31958   return sizeof(wuffs_gzip__decoder);
31959 }
31960 
31961 // ---------------- Function Implementations
31962 
31963 // -------- func gzip.decoder.set_quirk_enabled
31964 
31965 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)31966 wuffs_gzip__decoder__set_quirk_enabled(
31967     wuffs_gzip__decoder* self,
31968     uint32_t a_quirk,
31969     bool a_enabled) {
31970   if (!self) {
31971     return wuffs_base__make_empty_struct();
31972   }
31973   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
31974     return wuffs_base__make_empty_struct();
31975   }
31976 
31977   if (a_quirk == 1) {
31978     self->private_impl.f_ignore_checksum = a_enabled;
31979   }
31980   return wuffs_base__make_empty_struct();
31981 }
31982 
31983 // -------- func gzip.decoder.workbuf_len
31984 
31985 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gzip__decoder__workbuf_len(const wuffs_gzip__decoder * self)31986 wuffs_gzip__decoder__workbuf_len(
31987     const wuffs_gzip__decoder* self) {
31988   if (!self) {
31989     return wuffs_base__utility__empty_range_ii_u64();
31990   }
31991   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
31992       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
31993     return wuffs_base__utility__empty_range_ii_u64();
31994   }
31995 
31996   return wuffs_base__utility__make_range_ii_u64(1, 1);
31997 }
31998 
31999 // -------- func gzip.decoder.transform_io
32000 
32001 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)32002 wuffs_gzip__decoder__transform_io(
32003     wuffs_gzip__decoder* self,
32004     wuffs_base__io_buffer* a_dst,
32005     wuffs_base__io_buffer* a_src,
32006     wuffs_base__slice_u8 a_workbuf) {
32007   if (!self) {
32008     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32009   }
32010   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32011     return wuffs_base__make_status(
32012         (self->private_impl.magic == WUFFS_BASE__DISABLED)
32013         ? wuffs_base__error__disabled_by_previous_error
32014         : wuffs_base__error__initialize_not_called);
32015   }
32016   if (!a_dst || !a_src) {
32017     self->private_impl.magic = WUFFS_BASE__DISABLED;
32018     return wuffs_base__make_status(wuffs_base__error__bad_argument);
32019   }
32020   if ((self->private_impl.active_coroutine != 0) &&
32021       (self->private_impl.active_coroutine != 1)) {
32022     self->private_impl.magic = WUFFS_BASE__DISABLED;
32023     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32024   }
32025   self->private_impl.active_coroutine = 0;
32026   wuffs_base__status status = wuffs_base__make_status(NULL);
32027 
32028   uint8_t v_c = 0;
32029   uint8_t v_flags = 0;
32030   uint16_t v_xlen = 0;
32031   uint64_t v_mark = 0;
32032   uint32_t v_checksum_got = 0;
32033   uint32_t v_decoded_length_got = 0;
32034   wuffs_base__status v_status = wuffs_base__make_status(NULL);
32035   uint32_t v_checksum_want = 0;
32036   uint32_t v_decoded_length_want = 0;
32037 
32038   uint8_t* iop_a_dst = NULL;
32039   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32040   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32041   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32042   if (a_dst) {
32043     io0_a_dst = a_dst->data.ptr;
32044     io1_a_dst = io0_a_dst + a_dst->meta.wi;
32045     iop_a_dst = io1_a_dst;
32046     io2_a_dst = io0_a_dst + a_dst->data.len;
32047     if (a_dst->meta.closed) {
32048       io2_a_dst = iop_a_dst;
32049     }
32050   }
32051   const uint8_t* iop_a_src = NULL;
32052   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32053   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32054   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32055   if (a_src) {
32056     io0_a_src = a_src->data.ptr;
32057     io1_a_src = io0_a_src + a_src->meta.ri;
32058     iop_a_src = io1_a_src;
32059     io2_a_src = io0_a_src + a_src->meta.wi;
32060   }
32061 
32062   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
32063   if (coro_susp_point) {
32064     v_flags = self->private_data.s_transform_io[0].v_flags;
32065     v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
32066     v_decoded_length_got = self->private_data.s_transform_io[0].v_decoded_length_got;
32067     v_checksum_want = self->private_data.s_transform_io[0].v_checksum_want;
32068   }
32069   switch (coro_susp_point) {
32070     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32071 
32072     {
32073       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
32074       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32075         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32076         goto suspend;
32077       }
32078       uint8_t t_0 = *iop_a_src++;
32079       v_c = t_0;
32080     }
32081     if (v_c != 31) {
32082       status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
32083       goto exit;
32084     }
32085     {
32086       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
32087       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32088         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32089         goto suspend;
32090       }
32091       uint8_t t_1 = *iop_a_src++;
32092       v_c = t_1;
32093     }
32094     if (v_c != 139) {
32095       status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
32096       goto exit;
32097     }
32098     {
32099       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
32100       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32101         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32102         goto suspend;
32103       }
32104       uint8_t t_2 = *iop_a_src++;
32105       v_c = t_2;
32106     }
32107     if (v_c != 8) {
32108       status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method);
32109       goto exit;
32110     }
32111     {
32112       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
32113       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32114         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32115         goto suspend;
32116       }
32117       uint8_t t_3 = *iop_a_src++;
32118       v_flags = t_3;
32119     }
32120     self->private_data.s_transform_io[0].scratch = 6;
32121     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
32122     if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32123       self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32124       iop_a_src = io2_a_src;
32125       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32126       goto suspend;
32127     }
32128     iop_a_src += self->private_data.s_transform_io[0].scratch;
32129     if ((v_flags & 4) != 0) {
32130       {
32131         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
32132         uint16_t t_4;
32133         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
32134           t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
32135           iop_a_src += 2;
32136         } else {
32137           self->private_data.s_transform_io[0].scratch = 0;
32138           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
32139           while (true) {
32140             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32141               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32142               goto suspend;
32143             }
32144             uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
32145             uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
32146             *scratch <<= 8;
32147             *scratch >>= 8;
32148             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
32149             if (num_bits_4 == 8) {
32150               t_4 = ((uint16_t)(*scratch));
32151               break;
32152             }
32153             num_bits_4 += 8;
32154             *scratch |= ((uint64_t)(num_bits_4)) << 56;
32155           }
32156         }
32157         v_xlen = t_4;
32158       }
32159       self->private_data.s_transform_io[0].scratch = ((uint32_t)(v_xlen));
32160       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
32161       if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32162         self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32163         iop_a_src = io2_a_src;
32164         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32165         goto suspend;
32166       }
32167       iop_a_src += self->private_data.s_transform_io[0].scratch;
32168     }
32169     if ((v_flags & 8) != 0) {
32170       while (true) {
32171         {
32172           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
32173           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32174             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32175             goto suspend;
32176           }
32177           uint8_t t_5 = *iop_a_src++;
32178           v_c = t_5;
32179         }
32180         if (v_c == 0) {
32181           goto label__0__break;
32182         }
32183       }
32184       label__0__break:;
32185     }
32186     if ((v_flags & 16) != 0) {
32187       while (true) {
32188         {
32189           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
32190           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32191             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32192             goto suspend;
32193           }
32194           uint8_t t_6 = *iop_a_src++;
32195           v_c = t_6;
32196         }
32197         if (v_c == 0) {
32198           goto label__1__break;
32199         }
32200       }
32201       label__1__break:;
32202     }
32203     if ((v_flags & 2) != 0) {
32204       self->private_data.s_transform_io[0].scratch = 2;
32205       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
32206       if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32207         self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32208         iop_a_src = io2_a_src;
32209         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32210         goto suspend;
32211       }
32212       iop_a_src += self->private_data.s_transform_io[0].scratch;
32213     }
32214     if ((v_flags & 224) != 0) {
32215       status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags);
32216       goto exit;
32217     }
32218     while (true) {
32219       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
32220       {
32221         if (a_dst) {
32222           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32223         }
32224         if (a_src) {
32225           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32226         }
32227         wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
32228         v_status = t_7;
32229         if (a_dst) {
32230           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
32231         }
32232         if (a_src) {
32233           iop_a_src = a_src->data.ptr + a_src->meta.ri;
32234         }
32235       }
32236       if ( ! self->private_impl.f_ignore_checksum) {
32237         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));
32238         v_decoded_length_got += ((uint32_t)((wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))) & 4294967295)));
32239       }
32240       if (wuffs_base__status__is_ok(&v_status)) {
32241         goto label__2__break;
32242       }
32243       status = v_status;
32244       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
32245     }
32246     label__2__break:;
32247     {
32248       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
32249       uint32_t t_8;
32250       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32251         t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32252         iop_a_src += 4;
32253       } else {
32254         self->private_data.s_transform_io[0].scratch = 0;
32255         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
32256         while (true) {
32257           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32258             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32259             goto suspend;
32260           }
32261           uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
32262           uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
32263           *scratch <<= 8;
32264           *scratch >>= 8;
32265           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
32266           if (num_bits_8 == 24) {
32267             t_8 = ((uint32_t)(*scratch));
32268             break;
32269           }
32270           num_bits_8 += 8;
32271           *scratch |= ((uint64_t)(num_bits_8)) << 56;
32272         }
32273       }
32274       v_checksum_want = t_8;
32275     }
32276     {
32277       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
32278       uint32_t t_9;
32279       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32280         t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32281         iop_a_src += 4;
32282       } else {
32283         self->private_data.s_transform_io[0].scratch = 0;
32284         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
32285         while (true) {
32286           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32287             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32288             goto suspend;
32289           }
32290           uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
32291           uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
32292           *scratch <<= 8;
32293           *scratch >>= 8;
32294           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
32295           if (num_bits_9 == 24) {
32296             t_9 = ((uint32_t)(*scratch));
32297             break;
32298           }
32299           num_bits_9 += 8;
32300           *scratch |= ((uint64_t)(num_bits_9)) << 56;
32301         }
32302       }
32303       v_decoded_length_want = t_9;
32304     }
32305     if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_got != v_checksum_want) || (v_decoded_length_got != v_decoded_length_want))) {
32306       status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum);
32307       goto exit;
32308     }
32309 
32310     ok:
32311     self->private_impl.p_transform_io[0] = 0;
32312     goto exit;
32313   }
32314 
32315   goto suspend;
32316   suspend:
32317   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32318   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
32319   self->private_data.s_transform_io[0].v_flags = v_flags;
32320   self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
32321   self->private_data.s_transform_io[0].v_decoded_length_got = v_decoded_length_got;
32322   self->private_data.s_transform_io[0].v_checksum_want = v_checksum_want;
32323 
32324   goto exit;
32325   exit:
32326   if (a_dst) {
32327     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32328   }
32329   if (a_src) {
32330     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32331   }
32332 
32333   if (wuffs_base__status__is_error(&status)) {
32334     self->private_impl.magic = WUFFS_BASE__DISABLED;
32335   }
32336   return status;
32337 }
32338 
32339 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
32340 
32341 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
32342 
32343 // ---------------- Status Codes Implementations
32344 
32345 const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code";
32346 const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8";
32347 const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape";
32348 const char wuffs_json__error__bad_input[] = "#json: bad input";
32349 const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string";
32350 const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination";
32351 const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length";
32352 const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth";
32353 const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O";
32354 
32355 // ---------------- Private Consts
32356 
32357 #define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99
32358 
32359 static const uint8_t
32360 WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32361   0, 0, 0, 0, 0, 0, 0, 0,
32362   0, 0, 3, 0, 0, 0, 0, 0,
32363   0, 0, 0, 0, 0, 0, 0, 0,
32364   0, 0, 0, 0, 0, 0, 0, 0,
32365   0, 0, 162, 0, 0, 0, 0, 5,
32366   0, 0, 0, 0, 0, 0, 0, 175,
32367   7, 0, 0, 0, 0, 0, 0, 0,
32368   0, 0, 0, 0, 0, 0, 0, 4,
32369   0, 0, 0, 0, 0, 0, 0, 0,
32370   0, 0, 0, 0, 0, 0, 0, 0,
32371   0, 0, 0, 0, 0, 0, 0, 0,
32372   0, 0, 0, 0, 220, 0, 0, 0,
32373   0, 1, 136, 0, 0, 2, 140, 0,
32374   0, 0, 0, 0, 0, 0, 138, 0,
32375   0, 0, 141, 0, 137, 0, 6, 0,
32376   0, 0, 0, 0, 0, 0, 0, 0,
32377   0, 0, 0, 0, 0, 0, 0, 0,
32378   0, 0, 0, 0, 0, 0, 0, 0,
32379   0, 0, 0, 0, 0, 0, 0, 0,
32380   0, 0, 0, 0, 0, 0, 0, 0,
32381   0, 0, 0, 0, 0, 0, 0, 0,
32382   0, 0, 0, 0, 0, 0, 0, 0,
32383   0, 0, 0, 0, 0, 0, 0, 0,
32384   0, 0, 0, 0, 0, 0, 0, 0,
32385   0, 0, 0, 0, 0, 0, 0, 0,
32386   0, 0, 0, 0, 0, 0, 0, 0,
32387   0, 0, 0, 0, 0, 0, 0, 0,
32388   0, 0, 0, 0, 0, 0, 0, 0,
32389   0, 0, 0, 0, 0, 0, 0, 0,
32390   0, 0, 0, 0, 0, 0, 0, 0,
32391   0, 0, 0, 0, 0, 0, 0, 0,
32392   0, 0, 0, 0, 0, 0, 0, 0,
32393 };
32394 
32395 static const uint8_t
32396 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
32397   0, 1, 3, 4, 5, 6, 7, 10,
32398 };
32399 
32400 static const uint8_t
32401 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
32402   0, 7, 27, 10, 63, 39, 11, 0,
32403 };
32404 
32405 static const uint8_t
32406 WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32407   128, 129, 130, 131, 132, 133, 134, 135,
32408   136, 137, 138, 139, 140, 141, 142, 143,
32409   144, 145, 146, 147, 148, 149, 150, 151,
32410   152, 153, 154, 155, 156, 157, 158, 159,
32411   0, 0, 1, 0, 0, 0, 0, 0,
32412   0, 0, 0, 0, 0, 0, 0, 0,
32413   0, 0, 0, 0, 0, 0, 0, 0,
32414   0, 0, 0, 0, 0, 0, 0, 0,
32415   0, 0, 0, 0, 0, 0, 0, 0,
32416   0, 0, 0, 0, 0, 0, 0, 0,
32417   0, 0, 0, 0, 0, 0, 0, 0,
32418   0, 0, 0, 0, 2, 0, 0, 0,
32419   0, 0, 0, 0, 0, 0, 0, 0,
32420   0, 0, 0, 0, 0, 0, 0, 0,
32421   0, 0, 0, 0, 0, 0, 0, 0,
32422   0, 0, 0, 0, 0, 0, 0, 0,
32423   16, 16, 16, 16, 16, 16, 16, 16,
32424   16, 16, 16, 16, 16, 16, 16, 16,
32425   16, 16, 16, 16, 16, 16, 16, 16,
32426   16, 16, 16, 16, 16, 16, 16, 16,
32427   16, 16, 16, 16, 16, 16, 16, 16,
32428   16, 16, 16, 16, 16, 16, 16, 16,
32429   16, 16, 16, 16, 16, 16, 16, 16,
32430   16, 16, 16, 16, 16, 16, 16, 16,
32431   32, 32, 3, 3, 3, 3, 3, 3,
32432   3, 3, 3, 3, 3, 3, 3, 3,
32433   3, 3, 3, 3, 3, 3, 3, 3,
32434   3, 3, 3, 3, 3, 3, 3, 3,
32435   4, 4, 4, 4, 4, 4, 4, 4,
32436   4, 4, 4, 4, 4, 4, 4, 4,
32437   5, 5, 5, 5, 5, 32, 32, 32,
32438   32, 32, 32, 32, 32, 32, 32, 32,
32439 };
32440 
32441 #define WUFFS_JSON__CLASS_WHITESPACE 0
32442 
32443 #define WUFFS_JSON__CLASS_STRING 1
32444 
32445 #define WUFFS_JSON__CLASS_COMMA 2
32446 
32447 #define WUFFS_JSON__CLASS_COLON 3
32448 
32449 #define WUFFS_JSON__CLASS_NUMBER 4
32450 
32451 #define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5
32452 
32453 #define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6
32454 
32455 #define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7
32456 
32457 #define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8
32458 
32459 #define WUFFS_JSON__CLASS_FALSE 9
32460 
32461 #define WUFFS_JSON__CLASS_TRUE 10
32462 
32463 #define WUFFS_JSON__CLASS_NULL_NAN_INF 11
32464 
32465 #define WUFFS_JSON__CLASS_COMMENT 12
32466 
32467 #define WUFFS_JSON__EXPECT_VALUE 7858
32468 
32469 #define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856
32470 
32471 #define WUFFS_JSON__EXPECT_STRING 4098
32472 
32473 #define WUFFS_JSON__EXPECT_COMMA 4100
32474 
32475 #define WUFFS_JSON__EXPECT_COLON 4104
32476 
32477 #define WUFFS_JSON__EXPECT_NUMBER 4112
32478 
32479 #define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160
32480 
32481 #define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352
32482 
32483 static const uint8_t
32484 WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32485   15, 15, 15, 15, 15, 15, 15, 15,
32486   15, 0, 0, 15, 15, 0, 15, 15,
32487   15, 15, 15, 15, 15, 15, 15, 15,
32488   15, 15, 15, 15, 15, 15, 15, 15,
32489   0, 15, 1, 15, 15, 15, 15, 15,
32490   15, 15, 15, 11, 2, 4, 15, 12,
32491   4, 4, 4, 4, 4, 4, 4, 4,
32492   4, 4, 3, 15, 15, 15, 15, 15,
32493   15, 15, 15, 15, 15, 15, 15, 15,
32494   15, 11, 15, 15, 15, 15, 11, 15,
32495   15, 15, 15, 15, 15, 15, 15, 15,
32496   15, 15, 15, 7, 15, 8, 15, 15,
32497   15, 15, 15, 15, 15, 15, 9, 15,
32498   15, 11, 15, 15, 15, 15, 11, 15,
32499   15, 15, 15, 15, 10, 15, 15, 15,
32500   15, 15, 15, 5, 15, 6, 15, 15,
32501   15, 15, 15, 15, 15, 15, 15, 15,
32502   15, 15, 15, 15, 15, 15, 15, 15,
32503   15, 15, 15, 15, 15, 15, 15, 15,
32504   15, 15, 15, 15, 15, 15, 15, 15,
32505   15, 15, 15, 15, 15, 15, 15, 15,
32506   15, 15, 15, 15, 15, 15, 15, 15,
32507   15, 15, 15, 15, 15, 15, 15, 15,
32508   15, 15, 15, 15, 15, 15, 15, 15,
32509   15, 15, 15, 15, 15, 15, 15, 15,
32510   15, 15, 15, 15, 15, 15, 15, 15,
32511   15, 15, 15, 15, 15, 15, 15, 15,
32512   15, 15, 15, 15, 15, 15, 15, 15,
32513   15, 15, 15, 15, 15, 15, 15, 15,
32514   15, 15, 15, 15, 15, 15, 15, 15,
32515   15, 15, 15, 15, 15, 15, 15, 15,
32516   15, 15, 15, 15, 15, 15, 15, 15,
32517 };
32518 
32519 static const uint8_t
32520 WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32521   0, 0, 0, 0, 0, 0, 0, 0,
32522   0, 0, 0, 0, 0, 0, 0, 0,
32523   0, 0, 0, 0, 0, 0, 0, 0,
32524   0, 0, 0, 0, 0, 0, 0, 0,
32525   0, 0, 0, 0, 0, 0, 0, 0,
32526   0, 0, 0, 0, 0, 0, 0, 0,
32527   128, 129, 130, 131, 132, 133, 134, 135,
32528   136, 137, 0, 0, 0, 0, 0, 0,
32529   0, 0, 0, 0, 0, 0, 0, 0,
32530   0, 0, 0, 0, 0, 0, 0, 0,
32531   0, 0, 0, 0, 0, 0, 0, 0,
32532   0, 0, 0, 0, 0, 0, 0, 0,
32533   0, 0, 0, 0, 0, 0, 0, 0,
32534   0, 0, 0, 0, 0, 0, 0, 0,
32535   0, 0, 0, 0, 0, 0, 0, 0,
32536   0, 0, 0, 0, 0, 0, 0, 0,
32537   0, 0, 0, 0, 0, 0, 0, 0,
32538   0, 0, 0, 0, 0, 0, 0, 0,
32539   0, 0, 0, 0, 0, 0, 0, 0,
32540   0, 0, 0, 0, 0, 0, 0, 0,
32541   0, 0, 0, 0, 0, 0, 0, 0,
32542   0, 0, 0, 0, 0, 0, 0, 0,
32543   0, 0, 0, 0, 0, 0, 0, 0,
32544   0, 0, 0, 0, 0, 0, 0, 0,
32545   0, 0, 0, 0, 0, 0, 0, 0,
32546   0, 0, 0, 0, 0, 0, 0, 0,
32547   0, 0, 0, 0, 0, 0, 0, 0,
32548   0, 0, 0, 0, 0, 0, 0, 0,
32549   0, 0, 0, 0, 0, 0, 0, 0,
32550   0, 0, 0, 0, 0, 0, 0, 0,
32551   0, 0, 0, 0, 0, 0, 0, 0,
32552   0, 0, 0, 0, 0, 0, 0, 0,
32553 };
32554 
32555 static const uint8_t
32556 WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32557   0, 0, 0, 0, 0, 0, 0, 0,
32558   0, 0, 0, 0, 0, 0, 0, 0,
32559   0, 0, 0, 0, 0, 0, 0, 0,
32560   0, 0, 0, 0, 0, 0, 0, 0,
32561   0, 0, 0, 0, 0, 0, 0, 0,
32562   0, 0, 0, 0, 0, 0, 0, 0,
32563   128, 129, 130, 131, 132, 133, 134, 135,
32564   136, 137, 0, 0, 0, 0, 0, 0,
32565   0, 138, 139, 140, 141, 142, 143, 0,
32566   0, 0, 0, 0, 0, 0, 0, 0,
32567   0, 0, 0, 0, 0, 0, 0, 0,
32568   0, 0, 0, 0, 0, 0, 0, 0,
32569   0, 138, 139, 140, 141, 142, 143, 0,
32570   0, 0, 0, 0, 0, 0, 0, 0,
32571   0, 0, 0, 0, 0, 0, 0, 0,
32572   0, 0, 0, 0, 0, 0, 0, 0,
32573   0, 0, 0, 0, 0, 0, 0, 0,
32574   0, 0, 0, 0, 0, 0, 0, 0,
32575   0, 0, 0, 0, 0, 0, 0, 0,
32576   0, 0, 0, 0, 0, 0, 0, 0,
32577   0, 0, 0, 0, 0, 0, 0, 0,
32578   0, 0, 0, 0, 0, 0, 0, 0,
32579   0, 0, 0, 0, 0, 0, 0, 0,
32580   0, 0, 0, 0, 0, 0, 0, 0,
32581   0, 0, 0, 0, 0, 0, 0, 0,
32582   0, 0, 0, 0, 0, 0, 0, 0,
32583   0, 0, 0, 0, 0, 0, 0, 0,
32584   0, 0, 0, 0, 0, 0, 0, 0,
32585   0, 0, 0, 0, 0, 0, 0, 0,
32586   0, 0, 0, 0, 0, 0, 0, 0,
32587   0, 0, 0, 0, 0, 0, 0, 0,
32588   0, 0, 0, 0, 0, 0, 0, 0,
32589 };
32590 
32591 #define WUFFS_JSON__QUIRKS_BASE 1225364480
32592 
32593 #define WUFFS_JSON__QUIRKS_COUNT 21
32594 
32595 // ---------------- Private Initializer Prototypes
32596 
32597 // ---------------- Private Function Prototypes
32598 
32599 static uint32_t
32600 wuffs_json__decoder__decode_number(
32601     wuffs_json__decoder* self,
32602     wuffs_base__io_buffer* a_src);
32603 
32604 static uint32_t
32605 wuffs_json__decoder__decode_digits(
32606     wuffs_json__decoder* self,
32607     wuffs_base__io_buffer* a_src,
32608     uint32_t a_n);
32609 
32610 static wuffs_base__status
32611 wuffs_json__decoder__decode_leading(
32612     wuffs_json__decoder* self,
32613     wuffs_base__token_buffer* a_dst,
32614     wuffs_base__io_buffer* a_src);
32615 
32616 static wuffs_base__status
32617 wuffs_json__decoder__decode_comment(
32618     wuffs_json__decoder* self,
32619     wuffs_base__token_buffer* a_dst,
32620     wuffs_base__io_buffer* a_src);
32621 
32622 static wuffs_base__status
32623 wuffs_json__decoder__decode_inf_nan(
32624     wuffs_json__decoder* self,
32625     wuffs_base__token_buffer* a_dst,
32626     wuffs_base__io_buffer* a_src);
32627 
32628 static wuffs_base__status
32629 wuffs_json__decoder__decode_trailer(
32630     wuffs_json__decoder* self,
32631     wuffs_base__token_buffer* a_dst,
32632     wuffs_base__io_buffer* a_src);
32633 
32634 // ---------------- VTables
32635 
32636 const wuffs_base__token_decoder__func_ptrs
32637 wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
32638   (wuffs_base__status(*)(void*,
32639       wuffs_base__token_buffer*,
32640       wuffs_base__io_buffer*,
32641       wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens),
32642   (wuffs_base__empty_struct(*)(void*,
32643       uint32_t,
32644       bool))(&wuffs_json__decoder__set_quirk_enabled),
32645   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len),
32646 };
32647 
32648 // ---------------- Initializer Implementations
32649 
32650 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)32651 wuffs_json__decoder__initialize(
32652     wuffs_json__decoder* self,
32653     size_t sizeof_star_self,
32654     uint64_t wuffs_version,
32655     uint32_t options){
32656   if (!self) {
32657     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32658   }
32659   if (sizeof(*self) != sizeof_star_self) {
32660     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
32661   }
32662   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
32663       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
32664     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
32665   }
32666 
32667   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
32668     // The whole point of this if-check is to detect an uninitialized *self.
32669     // We disable the warning on GCC. Clang-5.0 does not have this warning.
32670 #if !defined(__clang__) && defined(__GNUC__)
32671 #pragma GCC diagnostic push
32672 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
32673 #endif
32674     if (self->private_impl.magic != 0) {
32675       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
32676     }
32677 #if !defined(__clang__) && defined(__GNUC__)
32678 #pragma GCC diagnostic pop
32679 #endif
32680   } else {
32681     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
32682       memset(self, 0, sizeof(*self));
32683       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
32684     } else {
32685       memset(&(self->private_impl), 0, sizeof(self->private_impl));
32686     }
32687   }
32688 
32689   self->private_impl.magic = WUFFS_BASE__MAGIC;
32690   self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
32691       wuffs_base__token_decoder__vtable_name;
32692   self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
32693       (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
32694   return wuffs_base__make_status(NULL);
32695 }
32696 
32697 wuffs_json__decoder*
wuffs_json__decoder__alloc()32698 wuffs_json__decoder__alloc() {
32699   wuffs_json__decoder* x =
32700       (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
32701   if (!x) {
32702     return NULL;
32703   }
32704   if (wuffs_json__decoder__initialize(
32705       x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
32706     free(x);
32707     return NULL;
32708   }
32709   return x;
32710 }
32711 
32712 size_t
sizeof__wuffs_json__decoder()32713 sizeof__wuffs_json__decoder() {
32714   return sizeof(wuffs_json__decoder);
32715 }
32716 
32717 // ---------------- Function Implementations
32718 
32719 // -------- func json.decoder.set_quirk_enabled
32720 
32721 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)32722 wuffs_json__decoder__set_quirk_enabled(
32723     wuffs_json__decoder* self,
32724     uint32_t a_quirk,
32725     bool a_enabled) {
32726   if (!self) {
32727     return wuffs_base__make_empty_struct();
32728   }
32729   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32730     return wuffs_base__make_empty_struct();
32731   }
32732 
32733   if (a_quirk >= 1225364480) {
32734     a_quirk -= 1225364480;
32735     if (a_quirk < 21) {
32736       self->private_impl.f_quirks[a_quirk] = a_enabled;
32737     }
32738   }
32739   return wuffs_base__make_empty_struct();
32740 }
32741 
32742 // -------- func json.decoder.workbuf_len
32743 
32744 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_json__decoder__workbuf_len(const wuffs_json__decoder * self)32745 wuffs_json__decoder__workbuf_len(
32746     const wuffs_json__decoder* self) {
32747   if (!self) {
32748     return wuffs_base__utility__empty_range_ii_u64();
32749   }
32750   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
32751       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
32752     return wuffs_base__utility__empty_range_ii_u64();
32753   }
32754 
32755   return wuffs_base__utility__empty_range_ii_u64();
32756 }
32757 
32758 // -------- func json.decoder.decode_tokens
32759 
32760 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)32761 wuffs_json__decoder__decode_tokens(
32762     wuffs_json__decoder* self,
32763     wuffs_base__token_buffer* a_dst,
32764     wuffs_base__io_buffer* a_src,
32765     wuffs_base__slice_u8 a_workbuf) {
32766   if (!self) {
32767     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32768   }
32769   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32770     return wuffs_base__make_status(
32771         (self->private_impl.magic == WUFFS_BASE__DISABLED)
32772         ? wuffs_base__error__disabled_by_previous_error
32773         : wuffs_base__error__initialize_not_called);
32774   }
32775   if (!a_dst || !a_src) {
32776     self->private_impl.magic = WUFFS_BASE__DISABLED;
32777     return wuffs_base__make_status(wuffs_base__error__bad_argument);
32778   }
32779   if ((self->private_impl.active_coroutine != 0) &&
32780       (self->private_impl.active_coroutine != 1)) {
32781     self->private_impl.magic = WUFFS_BASE__DISABLED;
32782     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32783   }
32784   self->private_impl.active_coroutine = 0;
32785   wuffs_base__status status = wuffs_base__make_status(NULL);
32786 
32787   uint32_t v_vminor = 0;
32788   uint32_t v_number_length = 0;
32789   uint32_t v_number_status = 0;
32790   uint32_t v_string_length = 0;
32791   uint32_t v_whitespace_length = 0;
32792   uint32_t v_depth = 0;
32793   uint32_t v_stack_byte = 0;
32794   uint32_t v_stack_bit = 0;
32795   uint32_t v_match = 0;
32796   uint32_t v_c4 = 0;
32797   uint8_t v_c = 0;
32798   uint8_t v_backslash = 0;
32799   uint8_t v_char = 0;
32800   uint8_t v_class = 0;
32801   uint32_t v_multi_byte_utf8 = 0;
32802   uint8_t v_backslash_x_ok = 0;
32803   uint8_t v_backslash_x_value = 0;
32804   uint32_t v_backslash_x_string = 0;
32805   uint8_t v_uni4_ok = 0;
32806   uint64_t v_uni4_string = 0;
32807   uint32_t v_uni4_value = 0;
32808   uint32_t v_uni4_high_surrogate = 0;
32809   uint8_t v_uni8_ok = 0;
32810   uint64_t v_uni8_string = 0;
32811   uint32_t v_uni8_value = 0;
32812   uint32_t v_expect = 0;
32813   uint32_t v_expect_after_value = 0;
32814 
32815   wuffs_base__token* iop_a_dst = NULL;
32816   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32817   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32818   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32819   if (a_dst) {
32820     io0_a_dst = a_dst->data.ptr;
32821     io1_a_dst = io0_a_dst + a_dst->meta.wi;
32822     iop_a_dst = io1_a_dst;
32823     io2_a_dst = io0_a_dst + a_dst->data.len;
32824     if (a_dst->meta.closed) {
32825       io2_a_dst = iop_a_dst;
32826     }
32827   }
32828   const uint8_t* iop_a_src = NULL;
32829   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32830   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32831   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32832   if (a_src) {
32833     io0_a_src = a_src->data.ptr;
32834     io1_a_src = io0_a_src + a_src->meta.ri;
32835     iop_a_src = io1_a_src;
32836     io2_a_src = io0_a_src + a_src->meta.wi;
32837   }
32838 
32839   uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
32840   if (coro_susp_point) {
32841     v_depth = self->private_data.s_decode_tokens[0].v_depth;
32842     v_expect = self->private_data.s_decode_tokens[0].v_expect;
32843     v_expect_after_value = self->private_data.s_decode_tokens[0].v_expect_after_value;
32844   }
32845   switch (coro_susp_point) {
32846     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32847 
32848     if (self->private_impl.f_end_of_data) {
32849       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
32850       goto ok;
32851     }
32852     if (self->private_impl.f_quirks[18]) {
32853       if (self->private_impl.f_quirks[11] || self->private_impl.f_quirks[12] || self->private_impl.f_quirks[17]) {
32854         status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination);
32855         goto exit;
32856       }
32857     }
32858     if (self->private_impl.f_quirks[15] || self->private_impl.f_quirks[16]) {
32859       if (a_dst) {
32860         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32861       }
32862       if (a_src) {
32863         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32864       }
32865       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
32866       status = wuffs_json__decoder__decode_leading(self, a_dst, a_src);
32867       if (a_dst) {
32868         iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
32869       }
32870       if (a_src) {
32871         iop_a_src = a_src->data.ptr + a_src->meta.ri;
32872       }
32873       if (status.repr) {
32874         goto suspend;
32875       }
32876     }
32877     v_expect = 7858;
32878     label__outer__continue:;
32879     while (true) {
32880       while (true) {
32881         if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32882           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32883           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
32884           goto label__outer__continue;
32885         }
32886         v_whitespace_length = 0;
32887         v_c = 0;
32888         v_class = 0;
32889         while (true) {
32890           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
32891             if (v_whitespace_length > 0) {
32892               *iop_a_dst++ = wuffs_base__make_token(
32893                   (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32894                   (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32895               v_whitespace_length = 0;
32896             }
32897             if (a_src && a_src->meta.closed) {
32898               status = wuffs_base__make_status(wuffs_json__error__bad_input);
32899               goto exit;
32900             }
32901             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32902             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
32903             v_whitespace_length = 0;
32904             goto label__outer__continue;
32905           }
32906           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
32907           v_class = WUFFS_JSON__LUT_CLASSES[v_c];
32908           if (v_class != 0) {
32909             goto label__ws__break;
32910           }
32911           iop_a_src += 1;
32912           if (v_whitespace_length >= 65534) {
32913             *iop_a_dst++ = wuffs_base__make_token(
32914                 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32915                 (((uint64_t)(65535)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32916             v_whitespace_length = 0;
32917             goto label__outer__continue;
32918           }
32919           v_whitespace_length += 1;
32920         }
32921         label__ws__break:;
32922         if (v_whitespace_length > 0) {
32923           *iop_a_dst++ = wuffs_base__make_token(
32924               (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32925               (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32926           v_whitespace_length = 0;
32927           if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32928             goto label__outer__continue;
32929           }
32930         }
32931         if (0 == (v_expect & (((uint32_t)(1)) << v_class))) {
32932           status = wuffs_base__make_status(wuffs_json__error__bad_input);
32933           goto exit;
32934         }
32935         if (v_class == 1) {
32936           *iop_a_dst++ = wuffs_base__make_token(
32937               (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32938               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32939               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32940           iop_a_src += 1;
32941           label__string_loop_outer__continue:;
32942           while (true) {
32943             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32944               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32945               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
32946               goto label__string_loop_outer__continue;
32947             }
32948             v_string_length = 0;
32949             label__string_loop_inner__continue:;
32950             while (true) {
32951               if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
32952                 if (v_string_length > 0) {
32953                   *iop_a_dst++ = wuffs_base__make_token(
32954                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32955                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32956                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32957                   v_string_length = 0;
32958                 }
32959                 if (a_src && a_src->meta.closed) {
32960                   status = wuffs_base__make_status(wuffs_json__error__bad_input);
32961                   goto exit;
32962                 }
32963                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32964                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
32965                 v_string_length = 0;
32966                 goto label__string_loop_outer__continue;
32967               }
32968               while (((uint64_t)(io2_a_src - iop_a_src)) > 4) {
32969                 v_c4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32970                 if (0 != (WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 0))] |
32971                     WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 8))] |
32972                     WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 16))] |
32973                     WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 24))])) {
32974                   goto label__0__break;
32975                 }
32976                 iop_a_src += 4;
32977                 if (v_string_length > 65527) {
32978                   *iop_a_dst++ = wuffs_base__make_token(
32979                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32980                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32981                       (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32982                   v_string_length = 0;
32983                   goto label__string_loop_outer__continue;
32984                 }
32985                 v_string_length += 4;
32986               }
32987               label__0__break:;
32988               v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
32989               v_char = WUFFS_JSON__LUT_CHARS[v_c];
32990               if (v_char == 0) {
32991                 iop_a_src += 1;
32992                 if (v_string_length >= 65531) {
32993                   *iop_a_dst++ = wuffs_base__make_token(
32994                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32995                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32996                       (((uint64_t)(65532)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32997                   v_string_length = 0;
32998                   goto label__string_loop_outer__continue;
32999                 }
33000                 v_string_length += 1;
33001                 goto label__string_loop_inner__continue;
33002               } else if (v_char == 1) {
33003                 if (v_string_length != 0) {
33004                   *iop_a_dst++ = wuffs_base__make_token(
33005                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33006                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33007                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33008                   v_string_length = 0;
33009                 }
33010                 goto label__string_loop_outer__break;
33011               } else if (v_char == 2) {
33012                 if (v_string_length > 0) {
33013                   *iop_a_dst++ = wuffs_base__make_token(
33014                       (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33015                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33016                       (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33017                   v_string_length = 0;
33018                   if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33019                     goto label__string_loop_outer__continue;
33020                   }
33021                 }
33022                 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
33023                   if (a_src && a_src->meta.closed) {
33024                     status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33025                     goto exit;
33026                   }
33027                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33028                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
33029                   v_string_length = 0;
33030                   v_char = 0;
33031                   goto label__string_loop_outer__continue;
33032                 }
33033                 v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8)));
33034                 v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c];
33035                 if ((v_backslash & 128) != 0) {
33036                   iop_a_src += 2;
33037                   *iop_a_dst++ = wuffs_base__make_token(
33038                       (((uint64_t)((6291456 | ((uint32_t)((v_backslash & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33039                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33040                       (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33041                   goto label__string_loop_outer__continue;
33042                 } else if (v_backslash != 0) {
33043                   if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(v_backslash & 7)]]) {
33044                     iop_a_src += 2;
33045                     *iop_a_dst++ = wuffs_base__make_token(
33046                         (((uint64_t)((6291456 | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(v_backslash & 7)]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33047                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33048                         (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33049                     goto label__string_loop_outer__continue;
33050                   }
33051                 } else if (v_c == 117) {
33052                   if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
33053                     if (a_src && a_src->meta.closed) {
33054                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33055                       goto exit;
33056                     }
33057                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33058                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
33059                     v_string_length = 0;
33060                     v_char = 0;
33061                     goto label__string_loop_outer__continue;
33062                   }
33063                   v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16);
33064                   v_uni4_value = 0;
33065                   v_uni4_ok = 128;
33066                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
33067                   v_uni4_ok &= v_c;
33068                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
33069                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
33070                   v_uni4_ok &= v_c;
33071                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
33072                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
33073                   v_uni4_ok &= v_c;
33074                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
33075                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
33076                   v_uni4_ok &= v_c;
33077                   v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
33078                   if (v_uni4_ok == 0) {
33079                   } else if ((v_uni4_value < 55296) || (57343 < v_uni4_value)) {
33080                     iop_a_src += 6;
33081                     *iop_a_dst++ = wuffs_base__make_token(
33082                         (((uint64_t)((6291456 | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33083                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33084                         (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33085                     goto label__string_loop_outer__continue;
33086                   } else if (v_uni4_value >= 56320) {
33087                   } else {
33088                     if (((uint64_t)(io2_a_src - iop_a_src)) < 12) {
33089                       if (a_src && a_src->meta.closed) {
33090                         if (self->private_impl.f_quirks[20]) {
33091                           iop_a_src += 6;
33092                           *iop_a_dst++ = wuffs_base__make_token(
33093                               (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33094                               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33095                               (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33096                           goto label__string_loop_outer__continue;
33097                         }
33098                         status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33099                         goto exit;
33100                       }
33101                       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33102                       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
33103                       v_string_length = 0;
33104                       v_uni4_value = 0;
33105                       v_char = 0;
33106                       goto label__string_loop_outer__continue;
33107                     }
33108                     v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4) >> 16);
33109                     if (((255 & (v_uni4_string >> 0)) != 92) || ((255 & (v_uni4_string >> 8)) != 117)) {
33110                       v_uni4_high_surrogate = 0;
33111                       v_uni4_value = 0;
33112                       v_uni4_ok = 0;
33113                     } else {
33114                       v_uni4_high_surrogate = (65536 + ((v_uni4_value - 55296) << 10));
33115                       v_uni4_value = 0;
33116                       v_uni4_ok = 128;
33117                       v_uni4_string >>= 16;
33118                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
33119                       v_uni4_ok &= v_c;
33120                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
33121                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
33122                       v_uni4_ok &= v_c;
33123                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
33124                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
33125                       v_uni4_ok &= v_c;
33126                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
33127                       v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
33128                       v_uni4_ok &= v_c;
33129                       v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
33130                     }
33131                     if ((v_uni4_ok != 0) && (56320 <= v_uni4_value) && (v_uni4_value <= 57343)) {
33132                       v_uni4_value -= 56320;
33133                       iop_a_src += 12;
33134                       *iop_a_dst++ = wuffs_base__make_token(
33135                           (((uint64_t)((6291456 | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33136                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33137                           (((uint64_t)(12)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33138                       goto label__string_loop_outer__continue;
33139                     }
33140                   }
33141                   if (self->private_impl.f_quirks[20]) {
33142                     if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
33143                       status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33144                       goto exit;
33145                     }
33146                     iop_a_src += 6;
33147                     *iop_a_dst++ = wuffs_base__make_token(
33148                         (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33149                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33150                         (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33151                     goto label__string_loop_outer__continue;
33152                   }
33153                 } else if ((v_c == 85) && self->private_impl.f_quirks[2]) {
33154                   if (((uint64_t)(io2_a_src - iop_a_src)) < 10) {
33155                     if (a_src && a_src->meta.closed) {
33156                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33157                       goto exit;
33158                     }
33159                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33160                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
33161                     v_string_length = 0;
33162                     v_char = 0;
33163                     goto label__string_loop_outer__continue;
33164                   }
33165                   v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2);
33166                   v_uni8_value = 0;
33167                   v_uni8_ok = 128;
33168                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 0))];
33169                   v_uni8_ok &= v_c;
33170                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 28);
33171                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 8))];
33172                   v_uni8_ok &= v_c;
33173                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 24);
33174                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 16))];
33175                   v_uni8_ok &= v_c;
33176                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 20);
33177                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 24))];
33178                   v_uni8_ok &= v_c;
33179                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 16);
33180                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 32))];
33181                   v_uni8_ok &= v_c;
33182                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 12);
33183                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 40))];
33184                   v_uni8_ok &= v_c;
33185                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 8);
33186                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 48))];
33187                   v_uni8_ok &= v_c;
33188                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 4);
33189                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 56))];
33190                   v_uni8_ok &= v_c;
33191                   v_uni8_value |= (((uint32_t)((v_c & 15))) << 0);
33192                   if (v_uni8_ok == 0) {
33193                   } else if ((v_uni8_value < 55296) || ((57343 < v_uni8_value) && (v_uni8_value <= 1114111))) {
33194                     iop_a_src += 10;
33195                     *iop_a_dst++ = wuffs_base__make_token(
33196                         (((uint64_t)((6291456 | (v_uni8_value & 2097151)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33197                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33198                         (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33199                     goto label__string_loop_outer__continue;
33200                   } else if (self->private_impl.f_quirks[20]) {
33201                     iop_a_src += 10;
33202                     *iop_a_dst++ = wuffs_base__make_token(
33203                         (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33204                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33205                         (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33206                     goto label__string_loop_outer__continue;
33207                   }
33208                 } else if ((v_c == 120) && self->private_impl.f_quirks[9]) {
33209                   if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33210                     if (a_src && a_src->meta.closed) {
33211                       status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33212                       goto exit;
33213                     }
33214                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33215                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
33216                     v_string_length = 0;
33217                     v_char = 0;
33218                     goto label__string_loop_outer__continue;
33219                   }
33220                   v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
33221                   v_backslash_x_ok = 128;
33222                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 16))];
33223                   v_backslash_x_ok &= v_c;
33224                   v_backslash_x_value = ((uint8_t)(((v_c & 15) << 4)));
33225                   v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 24))];
33226                   v_backslash_x_ok &= v_c;
33227                   v_backslash_x_value = ((uint8_t)((v_backslash_x_value | (v_c & 15))));
33228                   if ((v_backslash_x_ok == 0) || ((v_backslash_x_string & 65535) != 30812)) {
33229                     status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33230                     goto exit;
33231                   }
33232                   iop_a_src += 4;
33233                   *iop_a_dst++ = wuffs_base__make_token(
33234                       (((uint64_t)((6291456 | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33235                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33236                       (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33237                   goto label__string_loop_outer__continue;
33238                 }
33239                 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33240                 goto exit;
33241               } else if (v_char == 3) {
33242                 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
33243                   if (v_string_length > 0) {
33244                     *iop_a_dst++ = wuffs_base__make_token(
33245                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33246                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33247                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33248                     v_string_length = 0;
33249                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33250                       goto label__string_loop_outer__continue;
33251                     }
33252                   }
33253                   if (a_src && a_src->meta.closed) {
33254                     if (self->private_impl.f_quirks[20]) {
33255                       *iop_a_dst++ = wuffs_base__make_token(
33256                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33257                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33258                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33259                       iop_a_src += 1;
33260                       goto label__string_loop_outer__continue;
33261                     }
33262                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33263                     goto exit;
33264                   }
33265                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33266                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
33267                   v_string_length = 0;
33268                   v_char = 0;
33269                   goto label__string_loop_outer__continue;
33270                 }
33271                 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
33272                 if ((v_multi_byte_utf8 & 49152) == 32768) {
33273                   v_multi_byte_utf8 = ((1984 & ((uint32_t)(v_multi_byte_utf8 << 6))) | (63 & (v_multi_byte_utf8 >> 8)));
33274                   iop_a_src += 2;
33275                   if (v_string_length >= 65528) {
33276                     *iop_a_dst++ = wuffs_base__make_token(
33277                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33278                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33279                         (((uint64_t)((v_string_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33280                     v_string_length = 0;
33281                     goto label__string_loop_outer__continue;
33282                   }
33283                   v_string_length += 2;
33284                   goto label__string_loop_inner__continue;
33285                 }
33286               } else if (v_char == 4) {
33287                 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
33288                   if (v_string_length > 0) {
33289                     *iop_a_dst++ = wuffs_base__make_token(
33290                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33291                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33292                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33293                     v_string_length = 0;
33294                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33295                       goto label__string_loop_outer__continue;
33296                     }
33297                   }
33298                   if (a_src && a_src->meta.closed) {
33299                     if (self->private_impl.f_quirks[20]) {
33300                       *iop_a_dst++ = wuffs_base__make_token(
33301                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33302                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33303                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33304                       iop_a_src += 1;
33305                       goto label__string_loop_outer__continue;
33306                     }
33307                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33308                     goto exit;
33309                   }
33310                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33311                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
33312                   v_string_length = 0;
33313                   v_char = 0;
33314                   goto label__string_loop_outer__continue;
33315                 }
33316                 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
33317                 if ((v_multi_byte_utf8 & 12632064) == 8421376) {
33318                   v_multi_byte_utf8 = ((61440 & ((uint32_t)(v_multi_byte_utf8 << 12))) | (4032 & (v_multi_byte_utf8 >> 2)) | (63 & (v_multi_byte_utf8 >> 16)));
33319                   if ((2047 < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296) || (57343 < v_multi_byte_utf8))) {
33320                     iop_a_src += 3;
33321                     if (v_string_length >= 65528) {
33322                       *iop_a_dst++ = wuffs_base__make_token(
33323                           (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33324                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33325                           (((uint64_t)((v_string_length + 3))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33326                       v_string_length = 0;
33327                       goto label__string_loop_outer__continue;
33328                     }
33329                     v_string_length += 3;
33330                     goto label__string_loop_inner__continue;
33331                   }
33332                 }
33333               } else if (v_char == 5) {
33334                 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33335                   if (v_string_length > 0) {
33336                     *iop_a_dst++ = wuffs_base__make_token(
33337                         (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33338                         (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33339                         (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33340                     v_string_length = 0;
33341                     if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33342                       goto label__string_loop_outer__continue;
33343                     }
33344                   }
33345                   if (a_src && a_src->meta.closed) {
33346                     if (self->private_impl.f_quirks[20]) {
33347                       *iop_a_dst++ = wuffs_base__make_token(
33348                           (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33349                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33350                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33351                       iop_a_src += 1;
33352                       goto label__string_loop_outer__continue;
33353                     }
33354                     status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33355                     goto exit;
33356                   }
33357                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33358                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13);
33359                   v_string_length = 0;
33360                   v_char = 0;
33361                   goto label__string_loop_outer__continue;
33362                 }
33363                 v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
33364                 if ((v_multi_byte_utf8 & 3233857536) == 2155905024) {
33365                   v_multi_byte_utf8 = ((1835008 & ((uint32_t)(v_multi_byte_utf8 << 18))) |
33366                       (258048 & ((uint32_t)(v_multi_byte_utf8 << 4))) |
33367                       (4032 & (v_multi_byte_utf8 >> 10)) |
33368                       (63 & (v_multi_byte_utf8 >> 24)));
33369                   if ((65535 < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111)) {
33370                     iop_a_src += 4;
33371                     if (v_string_length >= 65528) {
33372                       *iop_a_dst++ = wuffs_base__make_token(
33373                           (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33374                           (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33375                           (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33376                       v_string_length = 0;
33377                       goto label__string_loop_outer__continue;
33378                     }
33379                     v_string_length += 4;
33380                     goto label__string_loop_inner__continue;
33381                   }
33382                 }
33383               }
33384               if (v_string_length > 0) {
33385                 *iop_a_dst++ = wuffs_base__make_token(
33386                     (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33387                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33388                     (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33389                 v_string_length = 0;
33390                 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33391                   goto label__string_loop_outer__continue;
33392                 }
33393               }
33394               if ((v_char & 128) != 0) {
33395                 if (self->private_impl.f_quirks[0]) {
33396                   *iop_a_dst++ = wuffs_base__make_token(
33397                       (((uint64_t)((6291456 | ((uint32_t)((v_char & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33398                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33399                       (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33400                   iop_a_src += 1;
33401                   goto label__string_loop_outer__continue;
33402                 }
33403                 if (v_char == 138) {
33404                   status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string);
33405                   goto exit;
33406                 }
33407                 status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
33408                 goto exit;
33409               }
33410               if (self->private_impl.f_quirks[20]) {
33411                 *iop_a_dst++ = wuffs_base__make_token(
33412                     (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33413                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33414                     (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33415                 iop_a_src += 1;
33416                 goto label__string_loop_outer__continue;
33417               }
33418               status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33419               goto exit;
33420             }
33421           }
33422           label__string_loop_outer__break:;
33423           label__1__continue:;
33424           while (true) {
33425             if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33426               if (a_src && a_src->meta.closed) {
33427                 status = wuffs_base__make_status(wuffs_json__error__bad_input);
33428                 goto exit;
33429               }
33430               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33431               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14);
33432               goto label__1__continue;
33433             }
33434             if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33435               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33436               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15);
33437               goto label__1__continue;
33438             }
33439             iop_a_src += 1;
33440             *iop_a_dst++ = wuffs_base__make_token(
33441                 (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33442                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33443             goto label__1__break;
33444           }
33445           label__1__break:;
33446           if (0 == (v_expect & (((uint32_t)(1)) << 4))) {
33447             v_expect = 4104;
33448             goto label__outer__continue;
33449           }
33450           goto label__goto_parsed_a_leaf_value__break;
33451         } else if (v_class == 2) {
33452           iop_a_src += 1;
33453           *iop_a_dst++ = wuffs_base__make_token(
33454               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33455               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33456           if (0 == (v_expect & (((uint32_t)(1)) << 8))) {
33457             if (self->private_impl.f_quirks[13]) {
33458               v_expect = 4162;
33459             } else {
33460               v_expect = 4098;
33461             }
33462           } else {
33463             if (self->private_impl.f_quirks[13]) {
33464               v_expect = 8114;
33465             } else {
33466               v_expect = 7858;
33467             }
33468           }
33469           goto label__outer__continue;
33470         } else if (v_class == 3) {
33471           iop_a_src += 1;
33472           *iop_a_dst++ = wuffs_base__make_token(
33473               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33474               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33475           v_expect = 7858;
33476           goto label__outer__continue;
33477         } else if (v_class == 4) {
33478           while (true) {
33479             if (a_src) {
33480               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33481             }
33482             v_number_length = wuffs_json__decoder__decode_number(self, a_src);
33483             if (a_src) {
33484               iop_a_src = a_src->data.ptr + a_src->meta.ri;
33485             }
33486             v_number_status = (v_number_length >> 8);
33487             v_vminor = 10486787;
33488             if ((v_number_length & 128) != 0) {
33489               v_vminor = 10486785;
33490             }
33491             v_number_length = (v_number_length & 127);
33492             if (v_number_status == 0) {
33493               *iop_a_dst++ = wuffs_base__make_token(
33494                   (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33495                   (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33496               goto label__2__break;
33497             }
33498             while (v_number_length > 0) {
33499               v_number_length -= 1;
33500               if (iop_a_src > io1_a_src) {
33501                 iop_a_src--;
33502               } else {
33503                 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33504                 goto exit;
33505               }
33506             }
33507             if (v_number_status == 1) {
33508               if (self->private_impl.f_quirks[14]) {
33509                 if (a_dst) {
33510                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33511                 }
33512                 if (a_src) {
33513                   a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33514                 }
33515                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
33516                 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
33517                 if (a_dst) {
33518                   iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33519                 }
33520                 if (a_src) {
33521                   iop_a_src = a_src->data.ptr + a_src->meta.ri;
33522                 }
33523                 if (status.repr) {
33524                   goto suspend;
33525                 }
33526                 goto label__2__break;
33527               }
33528               status = wuffs_base__make_status(wuffs_json__error__bad_input);
33529               goto exit;
33530             } else if (v_number_status == 2) {
33531               status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length);
33532               goto exit;
33533             } else {
33534               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33535               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17);
33536               while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33537                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33538                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18);
33539               }
33540             }
33541           }
33542           label__2__break:;
33543           goto label__goto_parsed_a_leaf_value__break;
33544         } else if (v_class == 5) {
33545           v_vminor = 2113553;
33546           if (v_depth == 0) {
33547           } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
33548             v_vminor = 2113601;
33549           } else {
33550             v_vminor = 2113569;
33551           }
33552           if (v_depth >= 1024) {
33553             status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
33554             goto exit;
33555           }
33556           v_stack_byte = (v_depth / 32);
33557           v_stack_bit = (v_depth & 31);
33558           self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1)) << v_stack_bit);
33559           v_depth += 1;
33560           iop_a_src += 1;
33561           *iop_a_dst++ = wuffs_base__make_token(
33562               (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33563               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33564           v_expect = 4162;
33565           v_expect_after_value = 4164;
33566           goto label__outer__continue;
33567         } else if (v_class == 6) {
33568           iop_a_src += 1;
33569           if (v_depth <= 1) {
33570             *iop_a_dst++ = wuffs_base__make_token(
33571                 (((uint64_t)(2101314)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33572                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33573             goto label__outer__break;
33574           }
33575           v_depth -= 1;
33576           v_stack_byte = ((v_depth - 1) / 32);
33577           v_stack_bit = ((v_depth - 1) & 31);
33578           if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
33579             *iop_a_dst++ = wuffs_base__make_token(
33580                 (((uint64_t)(2105410)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33581                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33582             v_expect = 4356;
33583             v_expect_after_value = 4356;
33584           } else {
33585             *iop_a_dst++ = wuffs_base__make_token(
33586                 (((uint64_t)(2113602)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33587                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33588             v_expect = 4164;
33589             v_expect_after_value = 4164;
33590           }
33591           goto label__outer__continue;
33592         } else if (v_class == 7) {
33593           v_vminor = 2105361;
33594           if (v_depth == 0) {
33595           } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
33596             v_vminor = 2105409;
33597           } else {
33598             v_vminor = 2105377;
33599           }
33600           if (v_depth >= 1024) {
33601             status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
33602             goto exit;
33603           }
33604           v_stack_byte = (v_depth / 32);
33605           v_stack_bit = (v_depth & 31);
33606           self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(1)) << v_stack_bit));
33607           v_depth += 1;
33608           iop_a_src += 1;
33609           *iop_a_dst++ = wuffs_base__make_token(
33610               (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33611               (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33612           v_expect = 8114;
33613           v_expect_after_value = 4356;
33614           goto label__outer__continue;
33615         } else if (v_class == 8) {
33616           iop_a_src += 1;
33617           if (v_depth <= 1) {
33618             *iop_a_dst++ = wuffs_base__make_token(
33619                 (((uint64_t)(2101282)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33620                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33621             goto label__outer__break;
33622           }
33623           v_depth -= 1;
33624           v_stack_byte = ((v_depth - 1) / 32);
33625           v_stack_bit = ((v_depth - 1) & 31);
33626           if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
33627             *iop_a_dst++ = wuffs_base__make_token(
33628                 (((uint64_t)(2105378)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33629                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33630             v_expect = 4356;
33631             v_expect_after_value = 4356;
33632           } else {
33633             *iop_a_dst++ = wuffs_base__make_token(
33634                 (((uint64_t)(2113570)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33635                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33636             v_expect = 4164;
33637             v_expect_after_value = 4164;
33638           }
33639           goto label__outer__continue;
33640         } else if (v_class == 9) {
33641           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,111546413966853);
33642           if (v_match == 0) {
33643             *iop_a_dst++ = wuffs_base__make_token(
33644                 (((uint64_t)(8388612)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33645                 (((uint64_t)(5)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33646             if (((uint64_t)(io2_a_src - iop_a_src)) < 5) {
33647               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33648               goto exit;
33649             }
33650             iop_a_src += 5;
33651             goto label__goto_parsed_a_leaf_value__break;
33652           } else if (v_match == 1) {
33653             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33654             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19);
33655             goto label__outer__continue;
33656           }
33657         } else if (v_class == 10) {
33658           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,435762131972);
33659           if (v_match == 0) {
33660             *iop_a_dst++ = wuffs_base__make_token(
33661                 (((uint64_t)(8388616)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33662                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33663             if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33664               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33665               goto exit;
33666             }
33667             iop_a_src += 4;
33668             goto label__goto_parsed_a_leaf_value__break;
33669           } else if (v_match == 1) {
33670             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33671             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20);
33672             goto label__outer__continue;
33673           }
33674         } else if (v_class == 11) {
33675           v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,465676103172);
33676           if (v_match == 0) {
33677             *iop_a_dst++ = wuffs_base__make_token(
33678                 (((uint64_t)(8388610)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33679                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33680             if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33681               status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33682               goto exit;
33683             }
33684             iop_a_src += 4;
33685             goto label__goto_parsed_a_leaf_value__break;
33686           } else if (v_match == 1) {
33687             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33688             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
33689             goto label__outer__continue;
33690           }
33691           if (self->private_impl.f_quirks[14]) {
33692             if (a_dst) {
33693               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33694             }
33695             if (a_src) {
33696               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33697             }
33698             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
33699             status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
33700             if (a_dst) {
33701               iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33702             }
33703             if (a_src) {
33704               iop_a_src = a_src->data.ptr + a_src->meta.ri;
33705             }
33706             if (status.repr) {
33707               goto suspend;
33708             }
33709             goto label__goto_parsed_a_leaf_value__break;
33710           }
33711         } else if (v_class == 12) {
33712           if (self->private_impl.f_quirks[11] || self->private_impl.f_quirks[12]) {
33713             if (a_dst) {
33714               a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33715             }
33716             if (a_src) {
33717               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33718             }
33719             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
33720             status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
33721             if (a_dst) {
33722               iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33723             }
33724             if (a_src) {
33725               iop_a_src = a_src->data.ptr + a_src->meta.ri;
33726             }
33727             if (status.repr) {
33728               goto suspend;
33729             }
33730             if (self->private_impl.f_comment_type > 0) {
33731               goto label__outer__continue;
33732             }
33733           }
33734         }
33735         status = wuffs_base__make_status(wuffs_json__error__bad_input);
33736         goto exit;
33737       }
33738       label__goto_parsed_a_leaf_value__break:;
33739       if (v_depth == 0) {
33740         goto label__outer__break;
33741       }
33742       v_expect = v_expect_after_value;
33743     }
33744     label__outer__break:;
33745     if (self->private_impl.f_quirks[17] || self->private_impl.f_quirks[18]) {
33746       if (a_dst) {
33747         a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33748       }
33749       if (a_src) {
33750         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33751       }
33752       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
33753       status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src);
33754       if (a_dst) {
33755         iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33756       }
33757       if (a_src) {
33758         iop_a_src = a_src->data.ptr + a_src->meta.ri;
33759       }
33760       if (status.repr) {
33761         goto suspend;
33762       }
33763     }
33764     self->private_impl.f_end_of_data = true;
33765 
33766     ok:
33767     self->private_impl.p_decode_tokens[0] = 0;
33768     goto exit;
33769   }
33770 
33771   goto suspend;
33772   suspend:
33773   self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33774   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
33775   self->private_data.s_decode_tokens[0].v_depth = v_depth;
33776   self->private_data.s_decode_tokens[0].v_expect = v_expect;
33777   self->private_data.s_decode_tokens[0].v_expect_after_value = v_expect_after_value;
33778 
33779   goto exit;
33780   exit:
33781   if (a_dst) {
33782     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33783   }
33784   if (a_src) {
33785     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33786   }
33787 
33788   if (wuffs_base__status__is_error(&status)) {
33789     self->private_impl.magic = WUFFS_BASE__DISABLED;
33790   }
33791   return status;
33792 }
33793 
33794 // -------- func json.decoder.decode_number
33795 
33796 static uint32_t
wuffs_json__decoder__decode_number(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src)33797 wuffs_json__decoder__decode_number(
33798     wuffs_json__decoder* self,
33799     wuffs_base__io_buffer* a_src) {
33800   uint8_t v_c = 0;
33801   uint32_t v_n = 0;
33802   uint32_t v_floating_point = 0;
33803 
33804   const uint8_t* iop_a_src = NULL;
33805   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33806   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33807   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33808   if (a_src) {
33809     io0_a_src = a_src->data.ptr;
33810     io1_a_src = io0_a_src + a_src->meta.ri;
33811     iop_a_src = io1_a_src;
33812     io2_a_src = io0_a_src + a_src->meta.wi;
33813   }
33814 
33815   while (true) {
33816     v_n = 0;
33817     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33818       if ( ! (a_src && a_src->meta.closed)) {
33819         v_n |= 768;
33820       }
33821       goto label__goto_done__break;
33822     }
33823     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33824     if (v_c != 45) {
33825     } else {
33826       v_n += 1;
33827       iop_a_src += 1;
33828       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33829         if ( ! (a_src && a_src->meta.closed)) {
33830           v_n |= 768;
33831         }
33832         v_n |= 256;
33833         goto label__goto_done__break;
33834       }
33835       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33836     }
33837     if (v_c == 48) {
33838       v_n += 1;
33839       iop_a_src += 1;
33840     } else {
33841       if (a_src) {
33842         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33843       }
33844       v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33845       if (a_src) {
33846         iop_a_src = a_src->data.ptr + a_src->meta.ri;
33847       }
33848       if (v_n > 99) {
33849         goto label__goto_done__break;
33850       }
33851     }
33852     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33853       if ( ! (a_src && a_src->meta.closed)) {
33854         v_n |= 768;
33855       }
33856       goto label__goto_done__break;
33857     }
33858     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33859     if (v_c != 46) {
33860     } else {
33861       if (v_n >= 99) {
33862         v_n |= 512;
33863         goto label__goto_done__break;
33864       }
33865       v_n += 1;
33866       iop_a_src += 1;
33867       v_floating_point = 128;
33868       if (a_src) {
33869         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33870       }
33871       v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33872       if (a_src) {
33873         iop_a_src = a_src->data.ptr + a_src->meta.ri;
33874       }
33875       if (v_n > 99) {
33876         goto label__goto_done__break;
33877       }
33878       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33879         if ( ! (a_src && a_src->meta.closed)) {
33880           v_n |= 768;
33881         }
33882         goto label__goto_done__break;
33883       }
33884       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33885     }
33886     if ((v_c != 69) && (v_c != 101)) {
33887       goto label__goto_done__break;
33888     }
33889     if (v_n >= 99) {
33890       v_n |= 512;
33891       goto label__goto_done__break;
33892     }
33893     v_n += 1;
33894     iop_a_src += 1;
33895     v_floating_point = 128;
33896     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33897       if ( ! (a_src && a_src->meta.closed)) {
33898         v_n |= 768;
33899       }
33900       v_n |= 256;
33901       goto label__goto_done__break;
33902     }
33903     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33904     if ((v_c != 43) && (v_c != 45)) {
33905     } else {
33906       if (v_n >= 99) {
33907         v_n |= 512;
33908         goto label__goto_done__break;
33909       }
33910       v_n += 1;
33911       iop_a_src += 1;
33912     }
33913     if (a_src) {
33914       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33915     }
33916     v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33917     if (a_src) {
33918       iop_a_src = a_src->data.ptr + a_src->meta.ri;
33919     }
33920     goto label__goto_done__break;
33921   }
33922   label__goto_done__break:;
33923   if (a_src) {
33924     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33925   }
33926   return (v_n | v_floating_point);
33927 }
33928 
33929 // -------- func json.decoder.decode_digits
33930 
33931 static uint32_t
wuffs_json__decoder__decode_digits(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src,uint32_t a_n)33932 wuffs_json__decoder__decode_digits(
33933     wuffs_json__decoder* self,
33934     wuffs_base__io_buffer* a_src,
33935     uint32_t a_n) {
33936   uint8_t v_c = 0;
33937   uint32_t v_n = 0;
33938 
33939   const uint8_t* iop_a_src = NULL;
33940   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33941   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33942   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33943   if (a_src) {
33944     io0_a_src = a_src->data.ptr;
33945     io1_a_src = io0_a_src + a_src->meta.ri;
33946     iop_a_src = io1_a_src;
33947     io2_a_src = io0_a_src + a_src->meta.wi;
33948   }
33949 
33950   v_n = a_n;
33951   while (true) {
33952     if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33953       if ( ! (a_src && a_src->meta.closed)) {
33954         v_n |= 768;
33955       }
33956       goto label__0__break;
33957     }
33958     v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33959     if (0 == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c]) {
33960       goto label__0__break;
33961     }
33962     if (v_n >= 99) {
33963       v_n |= 512;
33964       goto label__0__break;
33965     }
33966     v_n += 1;
33967     iop_a_src += 1;
33968   }
33969   label__0__break:;
33970   if (v_n == a_n) {
33971     v_n |= 256;
33972   }
33973   if (a_src) {
33974     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33975   }
33976   return v_n;
33977 }
33978 
33979 // -------- func json.decoder.decode_leading
33980 
33981 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)33982 wuffs_json__decoder__decode_leading(
33983     wuffs_json__decoder* self,
33984     wuffs_base__token_buffer* a_dst,
33985     wuffs_base__io_buffer* a_src) {
33986   wuffs_base__status status = wuffs_base__make_status(NULL);
33987 
33988   uint8_t v_c = 0;
33989   uint32_t v_u = 0;
33990 
33991   wuffs_base__token* iop_a_dst = NULL;
33992   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33993   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33994   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33995   if (a_dst) {
33996     io0_a_dst = a_dst->data.ptr;
33997     io1_a_dst = io0_a_dst + a_dst->meta.wi;
33998     iop_a_dst = io1_a_dst;
33999     io2_a_dst = io0_a_dst + a_dst->data.len;
34000     if (a_dst->meta.closed) {
34001       io2_a_dst = iop_a_dst;
34002     }
34003   }
34004   const uint8_t* iop_a_src = NULL;
34005   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34006   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34007   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34008   if (a_src) {
34009     io0_a_src = a_src->data.ptr;
34010     io1_a_src = io0_a_src + a_src->meta.ri;
34011     iop_a_src = io1_a_src;
34012     io2_a_src = io0_a_src + a_src->meta.wi;
34013   }
34014 
34015   uint32_t coro_susp_point = self->private_impl.p_decode_leading[0];
34016   switch (coro_susp_point) {
34017     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34018 
34019     self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15];
34020     self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16];
34021     label__0__continue:;
34022     while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) {
34023       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34024         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34025         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34026         goto label__0__continue;
34027       }
34028       if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
34029         if (a_src && a_src->meta.closed) {
34030           goto label__0__break;
34031         }
34032         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34033         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34034         goto label__0__continue;
34035       }
34036       v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
34037       if ((v_c == 30) && self->private_impl.f_allow_leading_ars) {
34038         self->private_impl.f_allow_leading_ars = false;
34039         iop_a_src += 1;
34040         *iop_a_dst++ = wuffs_base__make_token(
34041             (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34042             (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34043         goto label__0__continue;
34044       } else if ((v_c == 239) && self->private_impl.f_allow_leading_ubom) {
34045         if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
34046           if (a_src && a_src->meta.closed) {
34047             goto label__0__break;
34048           }
34049           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34050           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
34051           goto label__0__continue;
34052         }
34053         v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
34054         if (v_u == 12565487) {
34055           self->private_impl.f_allow_leading_ubom = false;
34056           iop_a_src += 3;
34057           *iop_a_dst++ = wuffs_base__make_token(
34058               (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34059               (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34060           goto label__0__continue;
34061         }
34062       }
34063       goto label__0__break;
34064     }
34065     label__0__break:;
34066 
34067     ok:
34068     self->private_impl.p_decode_leading[0] = 0;
34069     goto exit;
34070   }
34071 
34072   goto suspend;
34073   suspend:
34074   self->private_impl.p_decode_leading[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34075 
34076   goto exit;
34077   exit:
34078   if (a_dst) {
34079     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34080   }
34081   if (a_src) {
34082     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34083   }
34084 
34085   return status;
34086 }
34087 
34088 // -------- func json.decoder.decode_comment
34089 
34090 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)34091 wuffs_json__decoder__decode_comment(
34092     wuffs_json__decoder* self,
34093     wuffs_base__token_buffer* a_dst,
34094     wuffs_base__io_buffer* a_src) {
34095   wuffs_base__status status = wuffs_base__make_status(NULL);
34096 
34097   uint8_t v_c = 0;
34098   uint16_t v_c2 = 0;
34099   uint32_t v_length = 0;
34100 
34101   wuffs_base__token* iop_a_dst = NULL;
34102   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34103   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34104   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34105   if (a_dst) {
34106     io0_a_dst = a_dst->data.ptr;
34107     io1_a_dst = io0_a_dst + a_dst->meta.wi;
34108     iop_a_dst = io1_a_dst;
34109     io2_a_dst = io0_a_dst + a_dst->data.len;
34110     if (a_dst->meta.closed) {
34111       io2_a_dst = iop_a_dst;
34112     }
34113   }
34114   const uint8_t* iop_a_src = NULL;
34115   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34116   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34117   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34118   if (a_src) {
34119     io0_a_src = a_src->data.ptr;
34120     io1_a_src = io0_a_src + a_src->meta.ri;
34121     iop_a_src = io1_a_src;
34122     io2_a_src = io0_a_src + a_src->meta.wi;
34123   }
34124 
34125   uint32_t coro_susp_point = self->private_impl.p_decode_comment[0];
34126   switch (coro_susp_point) {
34127     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34128 
34129     self->private_impl.f_comment_type = 0;
34130     label__0__continue:;
34131     while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1)) {
34132       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34133         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34134         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34135         goto label__0__continue;
34136       }
34137       if (a_src && a_src->meta.closed) {
34138         status = wuffs_base__make_status(NULL);
34139         goto ok;
34140       }
34141       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34142       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34143     }
34144     v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
34145     if ((v_c2 == 10799) && self->private_impl.f_quirks[11]) {
34146       iop_a_src += 2;
34147       v_length = 2;
34148       label__comment_block__continue:;
34149       while (true) {
34150         if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34151           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34152           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
34153           v_length = 0;
34154           goto label__comment_block__continue;
34155         }
34156         while (true) {
34157           if (((uint64_t)(io2_a_src - iop_a_src)) <= 1) {
34158             if (v_length > 0) {
34159               *iop_a_dst++ = wuffs_base__make_token(
34160                   (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34161                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34162                   (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34163             }
34164             if (a_src && a_src->meta.closed) {
34165               status = wuffs_base__make_status(wuffs_json__error__bad_input);
34166               goto exit;
34167             }
34168             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34169             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
34170             v_length = 0;
34171             goto label__comment_block__continue;
34172           }
34173           v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
34174           if (v_c2 == 12074) {
34175             iop_a_src += 2;
34176             *iop_a_dst++ = wuffs_base__make_token(
34177                 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34178                 (((uint64_t)((v_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34179             self->private_impl.f_comment_type = 1;
34180             status = wuffs_base__make_status(NULL);
34181             goto ok;
34182           }
34183           iop_a_src += 1;
34184           if (v_length >= 65533) {
34185             *iop_a_dst++ = wuffs_base__make_token(
34186                 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34187                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34188                 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34189             v_length = 0;
34190             goto label__comment_block__continue;
34191           }
34192           v_length += 1;
34193         }
34194       }
34195     } else if ((v_c2 == 12079) && self->private_impl.f_quirks[12]) {
34196       iop_a_src += 2;
34197       v_length = 2;
34198       label__comment_line__continue:;
34199       while (true) {
34200         if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34201           status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34202           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
34203           v_length = 0;
34204           goto label__comment_line__continue;
34205         }
34206         while (true) {
34207           if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
34208             if (a_src && a_src->meta.closed) {
34209               *iop_a_dst++ = wuffs_base__make_token(
34210                   (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34211                   (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34212               self->private_impl.f_comment_type = 2;
34213               status = wuffs_base__make_status(NULL);
34214               goto ok;
34215             } else if (v_length > 0) {
34216               *iop_a_dst++ = wuffs_base__make_token(
34217                   (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34218                   (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34219                   (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34220             }
34221             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34222             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
34223             v_length = 0;
34224             goto label__comment_line__continue;
34225           }
34226           v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
34227           if (v_c == 10) {
34228             *iop_a_dst++ = wuffs_base__make_token(
34229                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34230                 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34231             self->private_impl.f_comment_type = 2;
34232             status = wuffs_base__make_status(NULL);
34233             goto ok;
34234           }
34235           iop_a_src += 1;
34236           if (v_length >= 65533) {
34237             *iop_a_dst++ = wuffs_base__make_token(
34238                 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34239                 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34240                 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34241             v_length = 0;
34242             goto label__comment_line__continue;
34243           }
34244           v_length += 1;
34245         }
34246       }
34247     }
34248 
34249     ok:
34250     self->private_impl.p_decode_comment[0] = 0;
34251     goto exit;
34252   }
34253 
34254   goto suspend;
34255   suspend:
34256   self->private_impl.p_decode_comment[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34257 
34258   goto exit;
34259   exit:
34260   if (a_dst) {
34261     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34262   }
34263   if (a_src) {
34264     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34265   }
34266 
34267   return status;
34268 }
34269 
34270 // -------- func json.decoder.decode_inf_nan
34271 
34272 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)34273 wuffs_json__decoder__decode_inf_nan(
34274     wuffs_json__decoder* self,
34275     wuffs_base__token_buffer* a_dst,
34276     wuffs_base__io_buffer* a_src) {
34277   wuffs_base__status status = wuffs_base__make_status(NULL);
34278 
34279   uint32_t v_c4 = 0;
34280   uint32_t v_neg = 0;
34281 
34282   wuffs_base__token* iop_a_dst = NULL;
34283   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34284   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34285   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34286   if (a_dst) {
34287     io0_a_dst = a_dst->data.ptr;
34288     io1_a_dst = io0_a_dst + a_dst->meta.wi;
34289     iop_a_dst = io1_a_dst;
34290     io2_a_dst = io0_a_dst + a_dst->data.len;
34291     if (a_dst->meta.closed) {
34292       io2_a_dst = iop_a_dst;
34293     }
34294   }
34295   const uint8_t* iop_a_src = NULL;
34296   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34297   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34298   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34299   if (a_src) {
34300     io0_a_src = a_src->data.ptr;
34301     io1_a_src = io0_a_src + a_src->meta.ri;
34302     iop_a_src = io1_a_src;
34303     io2_a_src = io0_a_src + a_src->meta.wi;
34304   }
34305 
34306   uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan[0];
34307   if (coro_susp_point) {
34308     v_neg = self->private_data.s_decode_inf_nan[0].v_neg;
34309   }
34310   switch (coro_susp_point) {
34311     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34312 
34313     label__0__continue:;
34314     while (true) {
34315       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34316         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34317         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34318         goto label__0__continue;
34319       }
34320       if (((uint64_t)(io2_a_src - iop_a_src)) <= 2) {
34321         if (a_src && a_src->meta.closed) {
34322           status = wuffs_base__make_status(wuffs_json__error__bad_input);
34323           goto exit;
34324         }
34325         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34326         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34327         goto label__0__continue;
34328       }
34329       v_c4 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
34330       if ((v_c4 | 2105376) == 6712937) {
34331         if (((uint64_t)(io2_a_src - iop_a_src)) > 7) {
34332           if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536) == 8751735898823356009) {
34333             *iop_a_dst++ = wuffs_base__make_token(
34334                 (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34335                 (((uint64_t)(8)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34336             iop_a_src += 8;
34337             status = wuffs_base__make_status(NULL);
34338             goto ok;
34339           }
34340         } else if ( ! (a_src && a_src->meta.closed)) {
34341           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34342           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
34343           goto label__0__continue;
34344         }
34345         *iop_a_dst++ = wuffs_base__make_token(
34346             (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34347             (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34348         iop_a_src += 3;
34349         status = wuffs_base__make_status(NULL);
34350         goto ok;
34351       } else if ((v_c4 | 2105376) == 7233902) {
34352         *iop_a_dst++ = wuffs_base__make_token(
34353             (((uint64_t)(10485888)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34354             (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34355         iop_a_src += 3;
34356         status = wuffs_base__make_status(NULL);
34357         goto ok;
34358       } else if ((v_c4 & 255) == 43) {
34359         v_neg = 0;
34360       } else if ((v_c4 & 255) == 45) {
34361         v_neg = 1;
34362       } else {
34363         status = wuffs_base__make_status(wuffs_json__error__bad_input);
34364         goto exit;
34365       }
34366       if (((uint64_t)(io2_a_src - iop_a_src)) <= 3) {
34367         if (a_src && a_src->meta.closed) {
34368           status = wuffs_base__make_status(wuffs_json__error__bad_input);
34369           goto exit;
34370         }
34371         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34372         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
34373         goto label__0__continue;
34374       }
34375       v_c4 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8);
34376       if ((v_c4 | 2105376) == 6712937) {
34377         if (((uint64_t)(io2_a_src - iop_a_src)) > 8) {
34378           if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1) | 2314885530818453536) == 8751735898823356009) {
34379             *iop_a_dst++ = wuffs_base__make_token(
34380                 (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34381                 (((uint64_t)(9)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34382             iop_a_src += 9;
34383             status = wuffs_base__make_status(NULL);
34384             goto ok;
34385           }
34386         } else if ( ! (a_src && a_src->meta.closed)) {
34387           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34388           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
34389           goto label__0__continue;
34390         }
34391         *iop_a_dst++ = wuffs_base__make_token(
34392             (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34393             (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34394         iop_a_src += 4;
34395         status = wuffs_base__make_status(NULL);
34396         goto ok;
34397       } else if ((v_c4 | 2105376) == 7233902) {
34398         *iop_a_dst++ = wuffs_base__make_token(
34399             (((uint64_t)((10485760 | (((uint32_t)(128)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34400             (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34401         iop_a_src += 4;
34402         status = wuffs_base__make_status(NULL);
34403         goto ok;
34404       }
34405       status = wuffs_base__make_status(wuffs_json__error__bad_input);
34406       goto exit;
34407     }
34408 
34409     ok:
34410     self->private_impl.p_decode_inf_nan[0] = 0;
34411     goto exit;
34412   }
34413 
34414   goto suspend;
34415   suspend:
34416   self->private_impl.p_decode_inf_nan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34417   self->private_data.s_decode_inf_nan[0].v_neg = v_neg;
34418 
34419   goto exit;
34420   exit:
34421   if (a_dst) {
34422     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34423   }
34424   if (a_src) {
34425     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34426   }
34427 
34428   return status;
34429 }
34430 
34431 // -------- func json.decoder.decode_trailer
34432 
34433 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)34434 wuffs_json__decoder__decode_trailer(
34435     wuffs_json__decoder* self,
34436     wuffs_base__token_buffer* a_dst,
34437     wuffs_base__io_buffer* a_src) {
34438   wuffs_base__status status = wuffs_base__make_status(NULL);
34439 
34440   uint8_t v_c = 0;
34441   uint32_t v_whitespace_length = 0;
34442 
34443   wuffs_base__token* iop_a_dst = NULL;
34444   wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34445   wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34446   wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34447   if (a_dst) {
34448     io0_a_dst = a_dst->data.ptr;
34449     io1_a_dst = io0_a_dst + a_dst->meta.wi;
34450     iop_a_dst = io1_a_dst;
34451     io2_a_dst = io0_a_dst + a_dst->data.len;
34452     if (a_dst->meta.closed) {
34453       io2_a_dst = iop_a_dst;
34454     }
34455   }
34456   const uint8_t* iop_a_src = NULL;
34457   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34458   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34459   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34460   if (a_src) {
34461     io0_a_src = a_src->data.ptr;
34462     io1_a_src = io0_a_src + a_src->meta.ri;
34463     iop_a_src = io1_a_src;
34464     io2_a_src = io0_a_src + a_src->meta.wi;
34465   }
34466 
34467   uint32_t coro_susp_point = self->private_impl.p_decode_trailer[0];
34468   switch (coro_susp_point) {
34469     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34470 
34471     if (self->private_impl.f_quirks[18]) {
34472       self->private_impl.f_trailer_stop = 10;
34473     } else {
34474       self->private_impl.f_trailer_stop = 0;
34475     }
34476     label__outer__continue:;
34477     while (true) {
34478       if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34479         status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34480         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34481         v_whitespace_length = 0;
34482         goto label__outer__continue;
34483       }
34484       while (true) {
34485         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
34486           if (v_whitespace_length > 0) {
34487             *iop_a_dst++ = wuffs_base__make_token(
34488                 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34489                 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34490             v_whitespace_length = 0;
34491           }
34492           if (a_src && a_src->meta.closed) {
34493             goto label__outer__break;
34494           }
34495           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34496           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34497           v_whitespace_length = 0;
34498           goto label__outer__continue;
34499         }
34500         v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
34501         if (WUFFS_JSON__LUT_CLASSES[v_c] != 0) {
34502           if (v_whitespace_length > 0) {
34503             *iop_a_dst++ = wuffs_base__make_token(
34504                 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34505                 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34506             v_whitespace_length = 0;
34507           }
34508           if (self->private_impl.f_trailer_stop > 0) {
34509             status = wuffs_base__make_status(wuffs_json__error__bad_input);
34510             goto exit;
34511           }
34512           if (a_dst) {
34513             a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34514           }
34515           if (a_src) {
34516             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34517           }
34518           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34519           status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
34520           if (a_dst) {
34521             iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
34522           }
34523           if (a_src) {
34524             iop_a_src = a_src->data.ptr + a_src->meta.ri;
34525           }
34526           if (status.repr) {
34527             goto suspend;
34528           }
34529           v_c = 0;
34530           v_whitespace_length = 0;
34531           if (self->private_impl.f_comment_type > 0) {
34532             goto label__outer__continue;
34533           }
34534           status = wuffs_base__make_status(NULL);
34535           goto ok;
34536         }
34537         iop_a_src += 1;
34538         if ((v_whitespace_length >= 65534) || (v_c == self->private_impl.f_trailer_stop)) {
34539           *iop_a_dst++ = wuffs_base__make_token(
34540               (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34541               (((uint64_t)((v_whitespace_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34542           v_whitespace_length = 0;
34543           if (v_c == self->private_impl.f_trailer_stop) {
34544             status = wuffs_base__make_status(NULL);
34545             goto ok;
34546           }
34547           goto label__outer__continue;
34548         }
34549         v_whitespace_length += 1;
34550       }
34551     }
34552     label__outer__break:;
34553 
34554     ok:
34555     self->private_impl.p_decode_trailer[0] = 0;
34556     goto exit;
34557   }
34558 
34559   goto suspend;
34560   suspend:
34561   self->private_impl.p_decode_trailer[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34562 
34563   goto exit;
34564   exit:
34565   if (a_dst) {
34566     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34567   }
34568   if (a_src) {
34569     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34570   }
34571 
34572   return status;
34573 }
34574 
34575 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
34576 
34577 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
34578 
34579 // ---------------- Status Codes Implementations
34580 
34581 const char wuffs_nie__error__bad_header[] = "#nie: bad header";
34582 const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file";
34583 const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read";
34584 
34585 // ---------------- Private Consts
34586 
34587 // ---------------- Private Initializer Prototypes
34588 
34589 // ---------------- Private Function Prototypes
34590 
34591 static wuffs_base__status
34592 wuffs_nie__decoder__swizzle(
34593     wuffs_nie__decoder* self,
34594     wuffs_base__pixel_buffer* a_dst,
34595     wuffs_base__io_buffer* a_src);
34596 
34597 // ---------------- VTables
34598 
34599 const wuffs_base__image_decoder__func_ptrs
34600 wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = {
34601   (wuffs_base__status(*)(void*,
34602       wuffs_base__pixel_buffer*,
34603       wuffs_base__io_buffer*,
34604       wuffs_base__pixel_blend,
34605       wuffs_base__slice_u8,
34606       wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame),
34607   (wuffs_base__status(*)(void*,
34608       wuffs_base__frame_config*,
34609       wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config),
34610   (wuffs_base__status(*)(void*,
34611       wuffs_base__image_config*,
34612       wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config),
34613   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect),
34614   (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops),
34615   (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs),
34616   (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames),
34617   (wuffs_base__status(*)(void*,
34618       uint64_t,
34619       uint64_t))(&wuffs_nie__decoder__restart_frame),
34620   (wuffs_base__empty_struct(*)(void*,
34621       uint32_t,
34622       bool))(&wuffs_nie__decoder__set_quirk_enabled),
34623   (wuffs_base__empty_struct(*)(void*,
34624       uint32_t,
34625       bool))(&wuffs_nie__decoder__set_report_metadata),
34626   (wuffs_base__status(*)(void*,
34627       wuffs_base__io_buffer*,
34628       wuffs_base__more_information*,
34629       wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more),
34630   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len),
34631 };
34632 
34633 // ---------------- Initializer Implementations
34634 
34635 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)34636 wuffs_nie__decoder__initialize(
34637     wuffs_nie__decoder* self,
34638     size_t sizeof_star_self,
34639     uint64_t wuffs_version,
34640     uint32_t options){
34641   if (!self) {
34642     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34643   }
34644   if (sizeof(*self) != sizeof_star_self) {
34645     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
34646   }
34647   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
34648       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
34649     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
34650   }
34651 
34652   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
34653     // The whole point of this if-check is to detect an uninitialized *self.
34654     // We disable the warning on GCC. Clang-5.0 does not have this warning.
34655 #if !defined(__clang__) && defined(__GNUC__)
34656 #pragma GCC diagnostic push
34657 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34658 #endif
34659     if (self->private_impl.magic != 0) {
34660       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
34661     }
34662 #if !defined(__clang__) && defined(__GNUC__)
34663 #pragma GCC diagnostic pop
34664 #endif
34665   } else {
34666     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
34667       memset(self, 0, sizeof(*self));
34668       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
34669     } else {
34670       memset(&(self->private_impl), 0, sizeof(self->private_impl));
34671     }
34672   }
34673 
34674   self->private_impl.magic = WUFFS_BASE__MAGIC;
34675   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
34676       wuffs_base__image_decoder__vtable_name;
34677   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
34678       (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder);
34679   return wuffs_base__make_status(NULL);
34680 }
34681 
34682 wuffs_nie__decoder*
wuffs_nie__decoder__alloc()34683 wuffs_nie__decoder__alloc() {
34684   wuffs_nie__decoder* x =
34685       (wuffs_nie__decoder*)(calloc(sizeof(wuffs_nie__decoder), 1));
34686   if (!x) {
34687     return NULL;
34688   }
34689   if (wuffs_nie__decoder__initialize(
34690       x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
34691     free(x);
34692     return NULL;
34693   }
34694   return x;
34695 }
34696 
34697 size_t
sizeof__wuffs_nie__decoder()34698 sizeof__wuffs_nie__decoder() {
34699   return sizeof(wuffs_nie__decoder);
34700 }
34701 
34702 // ---------------- Function Implementations
34703 
34704 // -------- func nie.decoder.set_quirk_enabled
34705 
34706 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)34707 wuffs_nie__decoder__set_quirk_enabled(
34708     wuffs_nie__decoder* self,
34709     uint32_t a_quirk,
34710     bool a_enabled) {
34711   return wuffs_base__make_empty_struct();
34712 }
34713 
34714 // -------- func nie.decoder.decode_image_config
34715 
34716 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)34717 wuffs_nie__decoder__decode_image_config(
34718     wuffs_nie__decoder* self,
34719     wuffs_base__image_config* a_dst,
34720     wuffs_base__io_buffer* a_src) {
34721   if (!self) {
34722     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34723   }
34724   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34725     return wuffs_base__make_status(
34726         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34727         ? wuffs_base__error__disabled_by_previous_error
34728         : wuffs_base__error__initialize_not_called);
34729   }
34730   if (!a_src) {
34731     self->private_impl.magic = WUFFS_BASE__DISABLED;
34732     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34733   }
34734   if ((self->private_impl.active_coroutine != 0) &&
34735       (self->private_impl.active_coroutine != 1)) {
34736     self->private_impl.magic = WUFFS_BASE__DISABLED;
34737     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34738   }
34739   self->private_impl.active_coroutine = 0;
34740   wuffs_base__status status = wuffs_base__make_status(NULL);
34741 
34742   uint32_t v_a = 0;
34743 
34744   const uint8_t* iop_a_src = NULL;
34745   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34746   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34747   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34748   if (a_src) {
34749     io0_a_src = a_src->data.ptr;
34750     io1_a_src = io0_a_src + a_src->meta.ri;
34751     iop_a_src = io1_a_src;
34752     io2_a_src = io0_a_src + a_src->meta.wi;
34753   }
34754 
34755   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
34756   switch (coro_susp_point) {
34757     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34758 
34759     if (self->private_impl.f_call_sequence != 0) {
34760       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
34761       goto exit;
34762     }
34763     {
34764       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34765       uint32_t t_0;
34766       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34767         t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34768         iop_a_src += 4;
34769       } else {
34770         self->private_data.s_decode_image_config[0].scratch = 0;
34771         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34772         while (true) {
34773           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34774             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34775             goto suspend;
34776           }
34777           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34778           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
34779           *scratch <<= 8;
34780           *scratch >>= 8;
34781           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
34782           if (num_bits_0 == 24) {
34783             t_0 = ((uint32_t)(*scratch));
34784             break;
34785           }
34786           num_bits_0 += 8;
34787           *scratch |= ((uint64_t)(num_bits_0)) << 56;
34788         }
34789       }
34790       v_a = t_0;
34791     }
34792     if (v_a != 1169146734) {
34793       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34794       goto exit;
34795     }
34796     {
34797       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34798       uint32_t t_1;
34799       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34800         t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34801         iop_a_src += 4;
34802       } else {
34803         self->private_data.s_decode_image_config[0].scratch = 0;
34804         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
34805         while (true) {
34806           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34807             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34808             goto suspend;
34809           }
34810           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34811           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
34812           *scratch <<= 8;
34813           *scratch >>= 8;
34814           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
34815           if (num_bits_1 == 24) {
34816             t_1 = ((uint32_t)(*scratch));
34817             break;
34818           }
34819           num_bits_1 += 8;
34820           *scratch |= ((uint64_t)(num_bits_1)) << 56;
34821         }
34822       }
34823       v_a = t_1;
34824     }
34825     if (v_a == 879649535) {
34826       self->private_impl.f_pixfmt = 2164295816;
34827     } else if (v_a == 946758399) {
34828       self->private_impl.f_pixfmt = 2164308923;
34829     } else if (v_a == 879780607) {
34830       status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
34831       goto exit;
34832     } else if (v_a == 946889471) {
34833       status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
34834       goto exit;
34835     } else {
34836       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34837       goto exit;
34838     }
34839     {
34840       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
34841       uint32_t t_2;
34842       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34843         t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34844         iop_a_src += 4;
34845       } else {
34846         self->private_data.s_decode_image_config[0].scratch = 0;
34847         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
34848         while (true) {
34849           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34850             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34851             goto suspend;
34852           }
34853           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34854           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
34855           *scratch <<= 8;
34856           *scratch >>= 8;
34857           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
34858           if (num_bits_2 == 24) {
34859             t_2 = ((uint32_t)(*scratch));
34860             break;
34861           }
34862           num_bits_2 += 8;
34863           *scratch |= ((uint64_t)(num_bits_2)) << 56;
34864         }
34865       }
34866       v_a = t_2;
34867     }
34868     if (v_a >= 2147483648) {
34869       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34870       goto exit;
34871     }
34872     self->private_impl.f_width = v_a;
34873     {
34874       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
34875       uint32_t t_3;
34876       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34877         t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34878         iop_a_src += 4;
34879       } else {
34880         self->private_data.s_decode_image_config[0].scratch = 0;
34881         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
34882         while (true) {
34883           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34884             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34885             goto suspend;
34886           }
34887           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34888           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
34889           *scratch <<= 8;
34890           *scratch >>= 8;
34891           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
34892           if (num_bits_3 == 24) {
34893             t_3 = ((uint32_t)(*scratch));
34894             break;
34895           }
34896           num_bits_3 += 8;
34897           *scratch |= ((uint64_t)(num_bits_3)) << 56;
34898         }
34899       }
34900       v_a = t_3;
34901     }
34902     if (v_a >= 2147483648) {
34903       status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34904       goto exit;
34905     }
34906     self->private_impl.f_height = v_a;
34907     if (a_dst != NULL) {
34908       wuffs_base__image_config__set(
34909           a_dst,
34910           self->private_impl.f_pixfmt,
34911           0,
34912           self->private_impl.f_width,
34913           self->private_impl.f_height,
34914           16,
34915           false);
34916     }
34917     self->private_impl.f_call_sequence = 3;
34918 
34919     goto ok;
34920     ok:
34921     self->private_impl.p_decode_image_config[0] = 0;
34922     goto exit;
34923   }
34924 
34925   goto suspend;
34926   suspend:
34927   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34928   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
34929 
34930   goto exit;
34931   exit:
34932   if (a_src) {
34933     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34934   }
34935 
34936   if (wuffs_base__status__is_error(&status)) {
34937     self->private_impl.magic = WUFFS_BASE__DISABLED;
34938   }
34939   return status;
34940 }
34941 
34942 // -------- func nie.decoder.decode_frame_config
34943 
34944 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)34945 wuffs_nie__decoder__decode_frame_config(
34946     wuffs_nie__decoder* self,
34947     wuffs_base__frame_config* a_dst,
34948     wuffs_base__io_buffer* a_src) {
34949   if (!self) {
34950     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34951   }
34952   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34953     return wuffs_base__make_status(
34954         (self->private_impl.magic == WUFFS_BASE__DISABLED)
34955         ? wuffs_base__error__disabled_by_previous_error
34956         : wuffs_base__error__initialize_not_called);
34957   }
34958   if (!a_src) {
34959     self->private_impl.magic = WUFFS_BASE__DISABLED;
34960     return wuffs_base__make_status(wuffs_base__error__bad_argument);
34961   }
34962   if ((self->private_impl.active_coroutine != 0) &&
34963       (self->private_impl.active_coroutine != 2)) {
34964     self->private_impl.magic = WUFFS_BASE__DISABLED;
34965     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34966   }
34967   self->private_impl.active_coroutine = 0;
34968   wuffs_base__status status = wuffs_base__make_status(NULL);
34969 
34970   const uint8_t* iop_a_src = NULL;
34971   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34972   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34973   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34974   if (a_src) {
34975     io0_a_src = a_src->data.ptr;
34976     io1_a_src = io0_a_src + a_src->meta.ri;
34977     iop_a_src = io1_a_src;
34978     io2_a_src = io0_a_src + a_src->meta.wi;
34979   }
34980 
34981   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
34982   switch (coro_susp_point) {
34983     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34984 
34985     if (self->private_impl.f_call_sequence < 3) {
34986       if (a_src) {
34987         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34988       }
34989       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34990       status = wuffs_nie__decoder__decode_image_config(self, NULL, a_src);
34991       if (a_src) {
34992         iop_a_src = a_src->data.ptr + a_src->meta.ri;
34993       }
34994       if (status.repr) {
34995         goto suspend;
34996       }
34997     } else if (self->private_impl.f_call_sequence == 3) {
34998       if (16 != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
34999         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
35000         goto exit;
35001       }
35002     } else if (self->private_impl.f_call_sequence == 4) {
35003       self->private_impl.f_call_sequence = 255;
35004       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
35005       goto ok;
35006     } else {
35007       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
35008       goto ok;
35009     }
35010     if (a_dst != NULL) {
35011       wuffs_base__frame_config__set(
35012           a_dst,
35013           wuffs_base__utility__make_rect_ie_u32(
35014           0,
35015           0,
35016           self->private_impl.f_width,
35017           self->private_impl.f_height),
35018           ((wuffs_base__flicks)(0)),
35019           0,
35020           16,
35021           0,
35022           false,
35023           false,
35024           0);
35025     }
35026     self->private_impl.f_call_sequence = 4;
35027 
35028     ok:
35029     self->private_impl.p_decode_frame_config[0] = 0;
35030     goto exit;
35031   }
35032 
35033   goto suspend;
35034   suspend:
35035   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35036   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
35037 
35038   goto exit;
35039   exit:
35040   if (a_src) {
35041     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35042   }
35043 
35044   if (wuffs_base__status__is_error(&status)) {
35045     self->private_impl.magic = WUFFS_BASE__DISABLED;
35046   }
35047   return status;
35048 }
35049 
35050 // -------- func nie.decoder.decode_frame
35051 
35052 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)35053 wuffs_nie__decoder__decode_frame(
35054     wuffs_nie__decoder* self,
35055     wuffs_base__pixel_buffer* a_dst,
35056     wuffs_base__io_buffer* a_src,
35057     wuffs_base__pixel_blend a_blend,
35058     wuffs_base__slice_u8 a_workbuf,
35059     wuffs_base__decode_frame_options* a_opts) {
35060   if (!self) {
35061     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35062   }
35063   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35064     return wuffs_base__make_status(
35065         (self->private_impl.magic == WUFFS_BASE__DISABLED)
35066         ? wuffs_base__error__disabled_by_previous_error
35067         : wuffs_base__error__initialize_not_called);
35068   }
35069   if (!a_dst || !a_src) {
35070     self->private_impl.magic = WUFFS_BASE__DISABLED;
35071     return wuffs_base__make_status(wuffs_base__error__bad_argument);
35072   }
35073   if ((self->private_impl.active_coroutine != 0) &&
35074       (self->private_impl.active_coroutine != 3)) {
35075     self->private_impl.magic = WUFFS_BASE__DISABLED;
35076     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35077   }
35078   self->private_impl.active_coroutine = 0;
35079   wuffs_base__status status = wuffs_base__make_status(NULL);
35080 
35081   wuffs_base__status v_status = wuffs_base__make_status(NULL);
35082 
35083   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
35084   switch (coro_susp_point) {
35085     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35086 
35087     if (self->private_impl.f_call_sequence < 4) {
35088       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
35089       status = wuffs_nie__decoder__decode_frame_config(self, NULL, a_src);
35090       if (status.repr) {
35091         goto suspend;
35092       }
35093     } else if (self->private_impl.f_call_sequence == 4) {
35094     } else {
35095       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
35096       goto ok;
35097     }
35098     self->private_impl.f_dst_x = 0;
35099     self->private_impl.f_dst_y = 0;
35100     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
35101         wuffs_base__pixel_buffer__pixel_format(a_dst),
35102         wuffs_base__pixel_buffer__palette(a_dst),
35103         wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
35104         wuffs_base__utility__empty_slice_u8(),
35105         a_blend);
35106     if ( ! wuffs_base__status__is_ok(&v_status)) {
35107       status = v_status;
35108       if (wuffs_base__status__is_error(&status)) {
35109         goto exit;
35110       } else if (wuffs_base__status__is_suspension(&status)) {
35111         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
35112         goto exit;
35113       }
35114       goto ok;
35115     }
35116     while (true) {
35117       v_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src);
35118       if (wuffs_base__status__is_ok(&v_status)) {
35119         goto label__0__break;
35120       } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) {
35121         status = v_status;
35122         if (wuffs_base__status__is_error(&status)) {
35123           goto exit;
35124         } else if (wuffs_base__status__is_suspension(&status)) {
35125           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
35126           goto exit;
35127         }
35128         goto ok;
35129       }
35130       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35131       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
35132     }
35133     label__0__break:;
35134     self->private_impl.f_call_sequence = 255;
35135 
35136     ok:
35137     self->private_impl.p_decode_frame[0] = 0;
35138     goto exit;
35139   }
35140 
35141   goto suspend;
35142   suspend:
35143   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35144   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
35145 
35146   goto exit;
35147   exit:
35148   if (wuffs_base__status__is_error(&status)) {
35149     self->private_impl.magic = WUFFS_BASE__DISABLED;
35150   }
35151   return status;
35152 }
35153 
35154 // -------- func nie.decoder.swizzle
35155 
35156 static wuffs_base__status
wuffs_nie__decoder__swizzle(wuffs_nie__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)35157 wuffs_nie__decoder__swizzle(
35158     wuffs_nie__decoder* self,
35159     wuffs_base__pixel_buffer* a_dst,
35160     wuffs_base__io_buffer* a_src) {
35161   wuffs_base__status status = wuffs_base__make_status(NULL);
35162 
35163   wuffs_base__pixel_format v_dst_pixfmt = {0};
35164   uint32_t v_dst_bits_per_pixel = 0;
35165   uint64_t v_dst_bytes_per_pixel = 0;
35166   uint64_t v_dst_bytes_per_row = 0;
35167   wuffs_base__table_u8 v_tab = {0};
35168   wuffs_base__slice_u8 v_dst = {0};
35169   uint64_t v_i = 0;
35170   uint64_t v_n = 0;
35171 
35172   const uint8_t* iop_a_src = NULL;
35173   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35174   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35175   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35176   if (a_src) {
35177     io0_a_src = a_src->data.ptr;
35178     io1_a_src = io0_a_src + a_src->meta.ri;
35179     iop_a_src = io1_a_src;
35180     io2_a_src = io0_a_src + a_src->meta.wi;
35181   }
35182 
35183   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
35184   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
35185   if ((v_dst_bits_per_pixel & 7) != 0) {
35186     status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
35187     goto exit;
35188   }
35189   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
35190   v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
35191   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
35192   label__0__continue:;
35193   while (true) {
35194     if (self->private_impl.f_dst_x == self->private_impl.f_width) {
35195       self->private_impl.f_dst_x = 0;
35196       self->private_impl.f_dst_y += 1;
35197       if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
35198         goto label__0__break;
35199       }
35200     }
35201     v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
35202     if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
35203       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
35204     }
35205     v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
35206     if (v_i >= ((uint64_t)(v_dst.len))) {
35207       goto label__0__continue;
35208     }
35209     v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
35210         &self->private_impl.f_swizzler,
35211         wuffs_base__slice_u8__subslice_i(v_dst, v_i),
35212         wuffs_base__pixel_buffer__palette(a_dst),
35213         &iop_a_src,
35214         io2_a_src);
35215     if (v_n == 0) {
35216       status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read);
35217       goto ok;
35218     }
35219     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
35220   }
35221   label__0__break:;
35222   status = wuffs_base__make_status(NULL);
35223   goto ok;
35224 
35225   ok:
35226   goto exit;
35227   exit:
35228   if (a_src) {
35229     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35230   }
35231 
35232   return status;
35233 }
35234 
35235 // -------- func nie.decoder.frame_dirty_rect
35236 
35237 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_nie__decoder__frame_dirty_rect(const wuffs_nie__decoder * self)35238 wuffs_nie__decoder__frame_dirty_rect(
35239     const wuffs_nie__decoder* self) {
35240   if (!self) {
35241     return wuffs_base__utility__empty_rect_ie_u32();
35242   }
35243   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35244       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35245     return wuffs_base__utility__empty_rect_ie_u32();
35246   }
35247 
35248   return wuffs_base__utility__make_rect_ie_u32(
35249       0,
35250       0,
35251       self->private_impl.f_width,
35252       self->private_impl.f_height);
35253 }
35254 
35255 // -------- func nie.decoder.num_animation_loops
35256 
35257 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_nie__decoder__num_animation_loops(const wuffs_nie__decoder * self)35258 wuffs_nie__decoder__num_animation_loops(
35259     const wuffs_nie__decoder* self) {
35260   if (!self) {
35261     return 0;
35262   }
35263   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35264       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35265     return 0;
35266   }
35267 
35268   return 0;
35269 }
35270 
35271 // -------- func nie.decoder.num_decoded_frame_configs
35272 
35273 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frame_configs(const wuffs_nie__decoder * self)35274 wuffs_nie__decoder__num_decoded_frame_configs(
35275     const wuffs_nie__decoder* self) {
35276   if (!self) {
35277     return 0;
35278   }
35279   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35280       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35281     return 0;
35282   }
35283 
35284   if (self->private_impl.f_call_sequence > 3) {
35285     return 1;
35286   }
35287   return 0;
35288 }
35289 
35290 // -------- func nie.decoder.num_decoded_frames
35291 
35292 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frames(const wuffs_nie__decoder * self)35293 wuffs_nie__decoder__num_decoded_frames(
35294     const wuffs_nie__decoder* self) {
35295   if (!self) {
35296     return 0;
35297   }
35298   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35299       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35300     return 0;
35301   }
35302 
35303   if (self->private_impl.f_call_sequence > 4) {
35304     return 1;
35305   }
35306   return 0;
35307 }
35308 
35309 // -------- func nie.decoder.restart_frame
35310 
35311 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)35312 wuffs_nie__decoder__restart_frame(
35313     wuffs_nie__decoder* self,
35314     uint64_t a_index,
35315     uint64_t a_io_position) {
35316   if (!self) {
35317     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35318   }
35319   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35320     return wuffs_base__make_status(
35321         (self->private_impl.magic == WUFFS_BASE__DISABLED)
35322         ? wuffs_base__error__disabled_by_previous_error
35323         : wuffs_base__error__initialize_not_called);
35324   }
35325 
35326   if (self->private_impl.f_call_sequence < 3) {
35327     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
35328   }
35329   if ((a_index != 0) || (a_io_position != 16)) {
35330     return wuffs_base__make_status(wuffs_base__error__bad_argument);
35331   }
35332   self->private_impl.f_call_sequence = 3;
35333   return wuffs_base__make_status(NULL);
35334 }
35335 
35336 // -------- func nie.decoder.set_report_metadata
35337 
35338 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)35339 wuffs_nie__decoder__set_report_metadata(
35340     wuffs_nie__decoder* self,
35341     uint32_t a_fourcc,
35342     bool a_report) {
35343   return wuffs_base__make_empty_struct();
35344 }
35345 
35346 // -------- func nie.decoder.tell_me_more
35347 
35348 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)35349 wuffs_nie__decoder__tell_me_more(
35350     wuffs_nie__decoder* self,
35351     wuffs_base__io_buffer* a_dst,
35352     wuffs_base__more_information* a_minfo,
35353     wuffs_base__io_buffer* a_src) {
35354   if (!self) {
35355     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35356   }
35357   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35358     return wuffs_base__make_status(
35359         (self->private_impl.magic == WUFFS_BASE__DISABLED)
35360         ? wuffs_base__error__disabled_by_previous_error
35361         : wuffs_base__error__initialize_not_called);
35362   }
35363   if (!a_dst || !a_src) {
35364     self->private_impl.magic = WUFFS_BASE__DISABLED;
35365     return wuffs_base__make_status(wuffs_base__error__bad_argument);
35366   }
35367   if ((self->private_impl.active_coroutine != 0) &&
35368       (self->private_impl.active_coroutine != 4)) {
35369     self->private_impl.magic = WUFFS_BASE__DISABLED;
35370     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35371   }
35372   self->private_impl.active_coroutine = 0;
35373   wuffs_base__status status = wuffs_base__make_status(NULL);
35374 
35375   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
35376   goto exit;
35377 
35378   goto ok;
35379   ok:
35380   goto exit;
35381   exit:
35382   if (wuffs_base__status__is_error(&status)) {
35383     self->private_impl.magic = WUFFS_BASE__DISABLED;
35384   }
35385   return status;
35386 }
35387 
35388 // -------- func nie.decoder.workbuf_len
35389 
35390 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_nie__decoder__workbuf_len(const wuffs_nie__decoder * self)35391 wuffs_nie__decoder__workbuf_len(
35392     const wuffs_nie__decoder* self) {
35393   if (!self) {
35394     return wuffs_base__utility__empty_range_ii_u64();
35395   }
35396   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35397       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35398     return wuffs_base__utility__empty_range_ii_u64();
35399   }
35400 
35401   return wuffs_base__utility__make_range_ii_u64(0, 0);
35402 }
35403 
35404 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
35405 
35406 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
35407 
35408 // ---------------- Status Codes Implementations
35409 
35410 const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required";
35411 const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum";
35412 const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method";
35413 const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size";
35414 const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check";
35415 const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary";
35416 
35417 // ---------------- Private Consts
35418 
35419 #define WUFFS_ZLIB__QUIRKS_BASE 2113790976
35420 
35421 #define WUFFS_ZLIB__QUIRKS_COUNT 1
35422 
35423 // ---------------- Private Initializer Prototypes
35424 
35425 // ---------------- Private Function Prototypes
35426 
35427 // ---------------- VTables
35428 
35429 const wuffs_base__io_transformer__func_ptrs
35430 wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = {
35431   (wuffs_base__empty_struct(*)(void*,
35432       uint32_t,
35433       bool))(&wuffs_zlib__decoder__set_quirk_enabled),
35434   (wuffs_base__status(*)(void*,
35435       wuffs_base__io_buffer*,
35436       wuffs_base__io_buffer*,
35437       wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io),
35438   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len),
35439 };
35440 
35441 // ---------------- Initializer Implementations
35442 
35443 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)35444 wuffs_zlib__decoder__initialize(
35445     wuffs_zlib__decoder* self,
35446     size_t sizeof_star_self,
35447     uint64_t wuffs_version,
35448     uint32_t options){
35449   if (!self) {
35450     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35451   }
35452   if (sizeof(*self) != sizeof_star_self) {
35453     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
35454   }
35455   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
35456       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
35457     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
35458   }
35459 
35460   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
35461     // The whole point of this if-check is to detect an uninitialized *self.
35462     // We disable the warning on GCC. Clang-5.0 does not have this warning.
35463 #if !defined(__clang__) && defined(__GNUC__)
35464 #pragma GCC diagnostic push
35465 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
35466 #endif
35467     if (self->private_impl.magic != 0) {
35468       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
35469     }
35470 #if !defined(__clang__) && defined(__GNUC__)
35471 #pragma GCC diagnostic pop
35472 #endif
35473   } else {
35474     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
35475       memset(self, 0, sizeof(*self));
35476       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
35477     } else {
35478       memset(&(self->private_impl), 0, sizeof(self->private_impl));
35479     }
35480   }
35481 
35482   {
35483     wuffs_base__status z = wuffs_adler32__hasher__initialize(
35484         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
35485     if (z.repr) {
35486       return z;
35487     }
35488   }
35489   {
35490     wuffs_base__status z = wuffs_adler32__hasher__initialize(
35491         &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options);
35492     if (z.repr) {
35493       return z;
35494     }
35495   }
35496   {
35497     wuffs_base__status z = wuffs_deflate__decoder__initialize(
35498         &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
35499     if (z.repr) {
35500       return z;
35501     }
35502   }
35503   self->private_impl.magic = WUFFS_BASE__MAGIC;
35504   self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
35505       wuffs_base__io_transformer__vtable_name;
35506   self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
35507       (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer);
35508   return wuffs_base__make_status(NULL);
35509 }
35510 
35511 wuffs_zlib__decoder*
wuffs_zlib__decoder__alloc()35512 wuffs_zlib__decoder__alloc() {
35513   wuffs_zlib__decoder* x =
35514       (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
35515   if (!x) {
35516     return NULL;
35517   }
35518   if (wuffs_zlib__decoder__initialize(
35519       x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
35520     free(x);
35521     return NULL;
35522   }
35523   return x;
35524 }
35525 
35526 size_t
sizeof__wuffs_zlib__decoder()35527 sizeof__wuffs_zlib__decoder() {
35528   return sizeof(wuffs_zlib__decoder);
35529 }
35530 
35531 // ---------------- Function Implementations
35532 
35533 // -------- func zlib.decoder.dictionary_id
35534 
35535 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_zlib__decoder__dictionary_id(const wuffs_zlib__decoder * self)35536 wuffs_zlib__decoder__dictionary_id(
35537     const wuffs_zlib__decoder* self) {
35538   if (!self) {
35539     return 0;
35540   }
35541   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35542       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35543     return 0;
35544   }
35545 
35546   return self->private_impl.f_dict_id_want;
35547 }
35548 
35549 // -------- func zlib.decoder.add_dictionary
35550 
35551 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_zlib__decoder__add_dictionary(wuffs_zlib__decoder * self,wuffs_base__slice_u8 a_dict)35552 wuffs_zlib__decoder__add_dictionary(
35553     wuffs_zlib__decoder* self,
35554     wuffs_base__slice_u8 a_dict) {
35555   if (!self) {
35556     return wuffs_base__make_empty_struct();
35557   }
35558   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35559     return wuffs_base__make_empty_struct();
35560   }
35561 
35562   if (self->private_impl.f_header_complete) {
35563     self->private_impl.f_bad_call_sequence = true;
35564   } else {
35565     self->private_impl.f_dict_id_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict);
35566     wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict);
35567   }
35568   self->private_impl.f_got_dictionary = true;
35569   return wuffs_base__make_empty_struct();
35570 }
35571 
35572 // -------- func zlib.decoder.set_quirk_enabled
35573 
35574 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)35575 wuffs_zlib__decoder__set_quirk_enabled(
35576     wuffs_zlib__decoder* self,
35577     uint32_t a_quirk,
35578     bool a_enabled) {
35579   if (!self) {
35580     return wuffs_base__make_empty_struct();
35581   }
35582   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35583     return wuffs_base__make_empty_struct();
35584   }
35585 
35586   if (self->private_impl.f_header_complete) {
35587     self->private_impl.f_bad_call_sequence = true;
35588   } else if (a_quirk == 1) {
35589     self->private_impl.f_ignore_checksum = a_enabled;
35590   } else if (a_quirk >= 2113790976) {
35591     a_quirk -= 2113790976;
35592     if (a_quirk < 1) {
35593       self->private_impl.f_quirks[a_quirk] = a_enabled;
35594     }
35595   }
35596   return wuffs_base__make_empty_struct();
35597 }
35598 
35599 // -------- func zlib.decoder.workbuf_len
35600 
35601 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_zlib__decoder__workbuf_len(const wuffs_zlib__decoder * self)35602 wuffs_zlib__decoder__workbuf_len(
35603     const wuffs_zlib__decoder* self) {
35604   if (!self) {
35605     return wuffs_base__utility__empty_range_ii_u64();
35606   }
35607   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35608       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35609     return wuffs_base__utility__empty_range_ii_u64();
35610   }
35611 
35612   return wuffs_base__utility__make_range_ii_u64(1, 1);
35613 }
35614 
35615 // -------- func zlib.decoder.transform_io
35616 
35617 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)35618 wuffs_zlib__decoder__transform_io(
35619     wuffs_zlib__decoder* self,
35620     wuffs_base__io_buffer* a_dst,
35621     wuffs_base__io_buffer* a_src,
35622     wuffs_base__slice_u8 a_workbuf) {
35623   if (!self) {
35624     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35625   }
35626   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35627     return wuffs_base__make_status(
35628         (self->private_impl.magic == WUFFS_BASE__DISABLED)
35629         ? wuffs_base__error__disabled_by_previous_error
35630         : wuffs_base__error__initialize_not_called);
35631   }
35632   if (!a_dst || !a_src) {
35633     self->private_impl.magic = WUFFS_BASE__DISABLED;
35634     return wuffs_base__make_status(wuffs_base__error__bad_argument);
35635   }
35636   if ((self->private_impl.active_coroutine != 0) &&
35637       (self->private_impl.active_coroutine != 1)) {
35638     self->private_impl.magic = WUFFS_BASE__DISABLED;
35639     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35640   }
35641   self->private_impl.active_coroutine = 0;
35642   wuffs_base__status status = wuffs_base__make_status(NULL);
35643 
35644   uint16_t v_x = 0;
35645   uint32_t v_checksum_got = 0;
35646   wuffs_base__status v_status = wuffs_base__make_status(NULL);
35647   uint32_t v_checksum_want = 0;
35648   uint64_t v_mark = 0;
35649 
35650   uint8_t* iop_a_dst = NULL;
35651   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35652   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35653   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35654   if (a_dst) {
35655     io0_a_dst = a_dst->data.ptr;
35656     io1_a_dst = io0_a_dst + a_dst->meta.wi;
35657     iop_a_dst = io1_a_dst;
35658     io2_a_dst = io0_a_dst + a_dst->data.len;
35659     if (a_dst->meta.closed) {
35660       io2_a_dst = iop_a_dst;
35661     }
35662   }
35663   const uint8_t* iop_a_src = NULL;
35664   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35665   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35666   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35667   if (a_src) {
35668     io0_a_src = a_src->data.ptr;
35669     io1_a_src = io0_a_src + a_src->meta.ri;
35670     iop_a_src = io1_a_src;
35671     io2_a_src = io0_a_src + a_src->meta.wi;
35672   }
35673 
35674   uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
35675   if (coro_susp_point) {
35676     v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
35677   }
35678   switch (coro_susp_point) {
35679     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35680 
35681     if (self->private_impl.f_bad_call_sequence) {
35682       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
35683       goto exit;
35684     } else if (self->private_impl.f_quirks[0]) {
35685     } else if ( ! self->private_impl.f_want_dictionary) {
35686       {
35687         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
35688         uint16_t t_0;
35689         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
35690           t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
35691           iop_a_src += 2;
35692         } else {
35693           self->private_data.s_transform_io[0].scratch = 0;
35694           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
35695           while (true) {
35696             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35697               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35698               goto suspend;
35699             }
35700             uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35701             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
35702             *scratch >>= 8;
35703             *scratch <<= 8;
35704             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
35705             if (num_bits_0 == 8) {
35706               t_0 = ((uint16_t)(*scratch >> 48));
35707               break;
35708             }
35709             num_bits_0 += 8;
35710             *scratch |= ((uint64_t)(num_bits_0));
35711           }
35712         }
35713         v_x = t_0;
35714       }
35715       if (((v_x >> 8) & 15) != 8) {
35716         status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method);
35717         goto exit;
35718       }
35719       if ((v_x >> 12) > 7) {
35720         status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size);
35721         goto exit;
35722       }
35723       if ((v_x % 31) != 0) {
35724         status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check);
35725         goto exit;
35726       }
35727       self->private_impl.f_want_dictionary = ((v_x & 32) != 0);
35728       if (self->private_impl.f_want_dictionary) {
35729         self->private_impl.f_dict_id_got = 1;
35730         {
35731           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
35732           uint32_t t_1;
35733           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
35734             t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
35735             iop_a_src += 4;
35736           } else {
35737             self->private_data.s_transform_io[0].scratch = 0;
35738             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
35739             while (true) {
35740               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35741                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35742                 goto suspend;
35743               }
35744               uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35745               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
35746               *scratch >>= 8;
35747               *scratch <<= 8;
35748               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
35749               if (num_bits_1 == 24) {
35750                 t_1 = ((uint32_t)(*scratch >> 32));
35751                 break;
35752               }
35753               num_bits_1 += 8;
35754               *scratch |= ((uint64_t)(num_bits_1));
35755             }
35756           }
35757           self->private_impl.f_dict_id_want = t_1;
35758         }
35759         status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
35760         goto ok;
35761       } else if (self->private_impl.f_got_dictionary) {
35762         status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
35763         goto exit;
35764       }
35765     } else if (self->private_impl.f_dict_id_got != self->private_impl.f_dict_id_want) {
35766       if (self->private_impl.f_got_dictionary) {
35767         status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
35768         goto exit;
35769       }
35770       status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
35771       goto ok;
35772     }
35773     self->private_impl.f_header_complete = true;
35774     while (true) {
35775       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
35776       {
35777         if (a_dst) {
35778           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35779         }
35780         if (a_src) {
35781           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35782         }
35783         wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
35784         v_status = t_2;
35785         if (a_dst) {
35786           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
35787         }
35788         if (a_src) {
35789           iop_a_src = a_src->data.ptr + a_src->meta.ri;
35790         }
35791       }
35792       if ( ! self->private_impl.f_ignore_checksum &&  ! self->private_impl.f_quirks[0]) {
35793         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));
35794       }
35795       if (wuffs_base__status__is_ok(&v_status)) {
35796         goto label__0__break;
35797       }
35798       status = v_status;
35799       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
35800     }
35801     label__0__break:;
35802     if ( ! self->private_impl.f_quirks[0]) {
35803       {
35804         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
35805         uint32_t t_3;
35806         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
35807           t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
35808           iop_a_src += 4;
35809         } else {
35810           self->private_data.s_transform_io[0].scratch = 0;
35811           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
35812           while (true) {
35813             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35814               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35815               goto suspend;
35816             }
35817             uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35818             uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
35819             *scratch >>= 8;
35820             *scratch <<= 8;
35821             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
35822             if (num_bits_3 == 24) {
35823               t_3 = ((uint32_t)(*scratch >> 32));
35824               break;
35825             }
35826             num_bits_3 += 8;
35827             *scratch |= ((uint64_t)(num_bits_3));
35828           }
35829         }
35830         v_checksum_want = t_3;
35831       }
35832       if ( ! self->private_impl.f_ignore_checksum && (v_checksum_got != v_checksum_want)) {
35833         status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum);
35834         goto exit;
35835       }
35836     }
35837 
35838     ok:
35839     self->private_impl.p_transform_io[0] = 0;
35840     goto exit;
35841   }
35842 
35843   goto suspend;
35844   suspend:
35845   self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35846   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
35847   self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
35848 
35849   goto exit;
35850   exit:
35851   if (a_dst) {
35852     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35853   }
35854   if (a_src) {
35855     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35856   }
35857 
35858   if (wuffs_base__status__is_error(&status)) {
35859     self->private_impl.magic = WUFFS_BASE__DISABLED;
35860   }
35861   return status;
35862 }
35863 
35864 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
35865 
35866 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
35867 
35868 // ---------------- Status Codes Implementations
35869 
35870 const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number";
35871 const char wuffs_png__error__bad_checksum[] = "#png: bad checksum";
35872 const char wuffs_png__error__bad_chunk[] = "#png: bad chunk";
35873 const char wuffs_png__error__bad_filter[] = "#png: bad filter";
35874 const char wuffs_png__error__bad_header[] = "#png: bad header";
35875 const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)";
35876 const char wuffs_png__error__missing_palette[] = "#png: missing palette";
35877 const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method";
35878 const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file";
35879 const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O";
35880 const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type";
35881 const char wuffs_png__error__internal_error_inconsistent_frame_bounds[] = "#png: internal error: inconsistent frame bounds";
35882 const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length";
35883 const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input";
35884 
35885 // ---------------- Private Consts
35886 
35887 #define WUFFS_PNG__ANCILLARY_BIT 32
35888 
35889 static const uint8_t
35890 WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = {
35891   {
35892     0, 0, 0, 0, 0, 0,
35893   }, {
35894     3, 7, 0, 3, 7, 0,
35895   }, {
35896     3, 3, 4, 3, 7, 0,
35897   }, {
35898     2, 3, 0, 3, 3, 4,
35899   }, {
35900     2, 1, 2, 2, 3, 0,
35901   }, {
35902     1, 1, 0, 2, 1, 2,
35903   }, {
35904     1, 0, 1, 1, 1, 0,
35905   }, {
35906     0, 0, 0, 1, 0, 1,
35907   },
35908 };
35909 
35910 static const uint8_t
35911 WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35912   0, 255, 85, 0, 17, 0, 0, 0,
35913 };
35914 
35915 static const uint8_t
35916 WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35917   0, 8, 4, 0, 2, 0, 0, 0,
35918 };
35919 
35920 static const uint8_t
35921 WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35922   1, 0, 3, 1, 2, 0, 4, 0,
35923 };
35924 
35925 static const uint16_t
35926 WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
35927   0, 0, 0, 0, 0, 0, 0, 0,
35928   0, 0, 0, 0, 0, 0, 0, 0,
35929   0, 0, 0, 0, 0, 0, 0, 0,
35930   0, 0, 0, 0, 0, 0, 0, 0,
35931   32, 33, 34, 35, 36, 37, 38, 39,
35932   40, 41, 42, 43, 44, 45, 46, 47,
35933   48, 49, 50, 51, 52, 53, 54, 55,
35934   56, 57, 58, 59, 60, 61, 62, 63,
35935   64, 65, 66, 67, 68, 69, 70, 71,
35936   72, 73, 74, 75, 76, 77, 78, 79,
35937   80, 81, 82, 83, 84, 85, 86, 87,
35938   88, 89, 90, 91, 92, 93, 94, 95,
35939   96, 97, 98, 99, 100, 101, 102, 103,
35940   104, 105, 106, 107, 108, 109, 110, 111,
35941   112, 113, 114, 115, 116, 117, 118, 119,
35942   120, 121, 122, 123, 124, 125, 126, 0,
35943   0, 0, 0, 0, 0, 0, 0, 0,
35944   0, 0, 0, 0, 0, 0, 0, 0,
35945   0, 0, 0, 0, 0, 0, 0, 0,
35946   0, 0, 0, 0, 0, 0, 0, 0,
35947   0, 41410, 41666, 41922, 42178, 42434, 42690, 42946,
35948   43202, 43458, 43714, 43970, 44226, 44482, 44738, 44994,
35949   45250, 45506, 45762, 46018, 46274, 46530, 46786, 47042,
35950   47298, 47554, 47810, 48066, 48322, 48578, 48834, 49090,
35951   32963, 33219, 33475, 33731, 33987, 34243, 34499, 34755,
35952   35011, 35267, 35523, 35779, 36035, 36291, 36547, 36803,
35953   37059, 37315, 37571, 37827, 38083, 38339, 38595, 38851,
35954   39107, 39363, 39619, 39875, 40131, 40387, 40643, 40899,
35955   41155, 41411, 41667, 41923, 42179, 42435, 42691, 42947,
35956   43203, 43459, 43715, 43971, 44227, 44483, 44739, 44995,
35957   45251, 45507, 45763, 46019, 46275, 46531, 46787, 47043,
35958   47299, 47555, 47811, 48067, 48323, 48579, 48835, 49091,
35959 };
35960 
35961 // ---------------- Private Initializer Prototypes
35962 
35963 // ---------------- Private Function Prototypes
35964 
35965 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35966 static wuffs_base__empty_struct
35967 wuffs_png__decoder__filter_1_distance_4_arm_neon(
35968     wuffs_png__decoder* self,
35969     wuffs_base__slice_u8 a_curr);
35970 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35971 
35972 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35973 static wuffs_base__empty_struct
35974 wuffs_png__decoder__filter_3_distance_4_arm_neon(
35975     wuffs_png__decoder* self,
35976     wuffs_base__slice_u8 a_curr,
35977     wuffs_base__slice_u8 a_prev);
35978 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35979 
35980 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35981 static wuffs_base__empty_struct
35982 wuffs_png__decoder__filter_4_distance_3_arm_neon(
35983     wuffs_png__decoder* self,
35984     wuffs_base__slice_u8 a_curr,
35985     wuffs_base__slice_u8 a_prev);
35986 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35987 
35988 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35989 static wuffs_base__empty_struct
35990 wuffs_png__decoder__filter_4_distance_4_arm_neon(
35991     wuffs_png__decoder* self,
35992     wuffs_base__slice_u8 a_curr,
35993     wuffs_base__slice_u8 a_prev);
35994 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35995 
35996 static wuffs_base__empty_struct
35997 wuffs_png__decoder__filter_1(
35998     wuffs_png__decoder* self,
35999     wuffs_base__slice_u8 a_curr);
36000 
36001 static wuffs_base__empty_struct
36002 wuffs_png__decoder__filter_1__choosy_default(
36003     wuffs_png__decoder* self,
36004     wuffs_base__slice_u8 a_curr);
36005 
36006 static wuffs_base__empty_struct
36007 wuffs_png__decoder__filter_1_distance_3_fallback(
36008     wuffs_png__decoder* self,
36009     wuffs_base__slice_u8 a_curr);
36010 
36011 static wuffs_base__empty_struct
36012 wuffs_png__decoder__filter_1_distance_4_fallback(
36013     wuffs_png__decoder* self,
36014     wuffs_base__slice_u8 a_curr);
36015 
36016 static wuffs_base__empty_struct
36017 wuffs_png__decoder__filter_2(
36018     wuffs_png__decoder* self,
36019     wuffs_base__slice_u8 a_curr,
36020     wuffs_base__slice_u8 a_prev);
36021 
36022 static wuffs_base__empty_struct
36023 wuffs_png__decoder__filter_3(
36024     wuffs_png__decoder* self,
36025     wuffs_base__slice_u8 a_curr,
36026     wuffs_base__slice_u8 a_prev);
36027 
36028 static wuffs_base__empty_struct
36029 wuffs_png__decoder__filter_3__choosy_default(
36030     wuffs_png__decoder* self,
36031     wuffs_base__slice_u8 a_curr,
36032     wuffs_base__slice_u8 a_prev);
36033 
36034 static wuffs_base__empty_struct
36035 wuffs_png__decoder__filter_3_distance_3_fallback(
36036     wuffs_png__decoder* self,
36037     wuffs_base__slice_u8 a_curr,
36038     wuffs_base__slice_u8 a_prev);
36039 
36040 static wuffs_base__empty_struct
36041 wuffs_png__decoder__filter_3_distance_4_fallback(
36042     wuffs_png__decoder* self,
36043     wuffs_base__slice_u8 a_curr,
36044     wuffs_base__slice_u8 a_prev);
36045 
36046 static wuffs_base__empty_struct
36047 wuffs_png__decoder__filter_4(
36048     wuffs_png__decoder* self,
36049     wuffs_base__slice_u8 a_curr,
36050     wuffs_base__slice_u8 a_prev);
36051 
36052 static wuffs_base__empty_struct
36053 wuffs_png__decoder__filter_4__choosy_default(
36054     wuffs_png__decoder* self,
36055     wuffs_base__slice_u8 a_curr,
36056     wuffs_base__slice_u8 a_prev);
36057 
36058 static wuffs_base__empty_struct
36059 wuffs_png__decoder__filter_4_distance_3_fallback(
36060     wuffs_png__decoder* self,
36061     wuffs_base__slice_u8 a_curr,
36062     wuffs_base__slice_u8 a_prev);
36063 
36064 static wuffs_base__empty_struct
36065 wuffs_png__decoder__filter_4_distance_4_fallback(
36066     wuffs_png__decoder* self,
36067     wuffs_base__slice_u8 a_curr,
36068     wuffs_base__slice_u8 a_prev);
36069 
36070 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36071 static wuffs_base__empty_struct
36072 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
36073     wuffs_png__decoder* self,
36074     wuffs_base__slice_u8 a_curr);
36075 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36076 
36077 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36078 static wuffs_base__empty_struct
36079 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
36080     wuffs_png__decoder* self,
36081     wuffs_base__slice_u8 a_curr,
36082     wuffs_base__slice_u8 a_prev);
36083 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36084 
36085 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36086 static wuffs_base__empty_struct
36087 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
36088     wuffs_png__decoder* self,
36089     wuffs_base__slice_u8 a_curr,
36090     wuffs_base__slice_u8 a_prev);
36091 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36092 
36093 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36094 static wuffs_base__empty_struct
36095 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
36096     wuffs_png__decoder* self,
36097     wuffs_base__slice_u8 a_curr,
36098     wuffs_base__slice_u8 a_prev);
36099 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36100 
36101 static wuffs_base__status
36102 wuffs_png__decoder__decode_ihdr(
36103     wuffs_png__decoder* self,
36104     wuffs_base__io_buffer* a_src);
36105 
36106 static wuffs_base__empty_struct
36107 wuffs_png__decoder__assign_filter_distance(
36108     wuffs_png__decoder* self);
36109 
36110 static uint64_t
36111 wuffs_png__decoder__calculate_bytes_per_row(
36112     const wuffs_png__decoder* self,
36113     uint32_t a_width);
36114 
36115 static wuffs_base__empty_struct
36116 wuffs_png__decoder__choose_filter_implementations(
36117     wuffs_png__decoder* self);
36118 
36119 static wuffs_base__status
36120 wuffs_png__decoder__decode_other_chunk(
36121     wuffs_png__decoder* self,
36122     wuffs_base__io_buffer* a_src);
36123 
36124 static wuffs_base__status
36125 wuffs_png__decoder__decode_actl(
36126     wuffs_png__decoder* self,
36127     wuffs_base__io_buffer* a_src);
36128 
36129 static wuffs_base__status
36130 wuffs_png__decoder__decode_chrm(
36131     wuffs_png__decoder* self,
36132     wuffs_base__io_buffer* a_src);
36133 
36134 static wuffs_base__status
36135 wuffs_png__decoder__decode_exif(
36136     wuffs_png__decoder* self,
36137     wuffs_base__io_buffer* a_src);
36138 
36139 static wuffs_base__status
36140 wuffs_png__decoder__decode_fctl(
36141     wuffs_png__decoder* self,
36142     wuffs_base__io_buffer* a_src);
36143 
36144 static wuffs_base__status
36145 wuffs_png__decoder__decode_gama(
36146     wuffs_png__decoder* self,
36147     wuffs_base__io_buffer* a_src);
36148 
36149 static wuffs_base__status
36150 wuffs_png__decoder__decode_iccp(
36151     wuffs_png__decoder* self,
36152     wuffs_base__io_buffer* a_src);
36153 
36154 static wuffs_base__status
36155 wuffs_png__decoder__decode_plte(
36156     wuffs_png__decoder* self,
36157     wuffs_base__io_buffer* a_src);
36158 
36159 static wuffs_base__status
36160 wuffs_png__decoder__decode_srgb(
36161     wuffs_png__decoder* self,
36162     wuffs_base__io_buffer* a_src);
36163 
36164 static wuffs_base__status
36165 wuffs_png__decoder__decode_trns(
36166     wuffs_png__decoder* self,
36167     wuffs_base__io_buffer* a_src);
36168 
36169 static wuffs_base__status
36170 wuffs_png__decoder__skip_frame(
36171     wuffs_png__decoder* self,
36172     wuffs_base__io_buffer* a_src);
36173 
36174 static wuffs_base__status
36175 wuffs_png__decoder__decode_pass(
36176     wuffs_png__decoder* self,
36177     wuffs_base__io_buffer* a_src,
36178     wuffs_base__slice_u8 a_workbuf);
36179 
36180 static wuffs_base__status
36181 wuffs_png__decoder__filter_and_swizzle(
36182     wuffs_png__decoder* self,
36183     wuffs_base__pixel_buffer* a_dst,
36184     wuffs_base__slice_u8 a_workbuf);
36185 
36186 static wuffs_base__status
36187 wuffs_png__decoder__filter_and_swizzle__choosy_default(
36188     wuffs_png__decoder* self,
36189     wuffs_base__pixel_buffer* a_dst,
36190     wuffs_base__slice_u8 a_workbuf);
36191 
36192 static wuffs_base__status
36193 wuffs_png__decoder__filter_and_swizzle_tricky(
36194     wuffs_png__decoder* self,
36195     wuffs_base__pixel_buffer* a_dst,
36196     wuffs_base__slice_u8 a_workbuf);
36197 
36198 // ---------------- VTables
36199 
36200 const wuffs_base__image_decoder__func_ptrs
36201 wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = {
36202   (wuffs_base__status(*)(void*,
36203       wuffs_base__pixel_buffer*,
36204       wuffs_base__io_buffer*,
36205       wuffs_base__pixel_blend,
36206       wuffs_base__slice_u8,
36207       wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame),
36208   (wuffs_base__status(*)(void*,
36209       wuffs_base__frame_config*,
36210       wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config),
36211   (wuffs_base__status(*)(void*,
36212       wuffs_base__image_config*,
36213       wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config),
36214   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect),
36215   (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops),
36216   (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs),
36217   (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames),
36218   (wuffs_base__status(*)(void*,
36219       uint64_t,
36220       uint64_t))(&wuffs_png__decoder__restart_frame),
36221   (wuffs_base__empty_struct(*)(void*,
36222       uint32_t,
36223       bool))(&wuffs_png__decoder__set_quirk_enabled),
36224   (wuffs_base__empty_struct(*)(void*,
36225       uint32_t,
36226       bool))(&wuffs_png__decoder__set_report_metadata),
36227   (wuffs_base__status(*)(void*,
36228       wuffs_base__io_buffer*,
36229       wuffs_base__more_information*,
36230       wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more),
36231   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len),
36232 };
36233 
36234 // ---------------- Initializer Implementations
36235 
36236 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)36237 wuffs_png__decoder__initialize(
36238     wuffs_png__decoder* self,
36239     size_t sizeof_star_self,
36240     uint64_t wuffs_version,
36241     uint32_t options){
36242   if (!self) {
36243     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
36244   }
36245   if (sizeof(*self) != sizeof_star_self) {
36246     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
36247   }
36248   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
36249       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
36250     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
36251   }
36252 
36253   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
36254     // The whole point of this if-check is to detect an uninitialized *self.
36255     // We disable the warning on GCC. Clang-5.0 does not have this warning.
36256 #if !defined(__clang__) && defined(__GNUC__)
36257 #pragma GCC diagnostic push
36258 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
36259 #endif
36260     if (self->private_impl.magic != 0) {
36261       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
36262     }
36263 #if !defined(__clang__) && defined(__GNUC__)
36264 #pragma GCC diagnostic pop
36265 #endif
36266   } else {
36267     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
36268       memset(self, 0, sizeof(*self));
36269       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
36270     } else {
36271       memset(&(self->private_impl), 0, sizeof(self->private_impl));
36272     }
36273   }
36274 
36275   self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default;
36276   self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default;
36277   self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default;
36278   self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default;
36279 
36280   {
36281     wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
36282         &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
36283     if (z.repr) {
36284       return z;
36285     }
36286   }
36287   {
36288     wuffs_base__status z = wuffs_zlib__decoder__initialize(
36289         &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options);
36290     if (z.repr) {
36291       return z;
36292     }
36293   }
36294   self->private_impl.magic = WUFFS_BASE__MAGIC;
36295   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
36296       wuffs_base__image_decoder__vtable_name;
36297   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
36298       (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder);
36299   return wuffs_base__make_status(NULL);
36300 }
36301 
36302 wuffs_png__decoder*
wuffs_png__decoder__alloc()36303 wuffs_png__decoder__alloc() {
36304   wuffs_png__decoder* x =
36305       (wuffs_png__decoder*)(calloc(sizeof(wuffs_png__decoder), 1));
36306   if (!x) {
36307     return NULL;
36308   }
36309   if (wuffs_png__decoder__initialize(
36310       x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
36311     free(x);
36312     return NULL;
36313   }
36314   return x;
36315 }
36316 
36317 size_t
sizeof__wuffs_png__decoder()36318 sizeof__wuffs_png__decoder() {
36319   return sizeof(wuffs_png__decoder);
36320 }
36321 
36322 // ---------------- Function Implementations
36323 
36324 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36325 // -------- func png.decoder.filter_1_distance_4_arm_neon
36326 
36327 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36328 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36329 wuffs_png__decoder__filter_1_distance_4_arm_neon(
36330     wuffs_png__decoder* self,
36331     wuffs_base__slice_u8 a_curr) {
36332   wuffs_base__slice_u8 v_curr = {0};
36333   uint8x8_t v_fa = {0};
36334   uint8x8_t v_fx = {0};
36335 
36336   {
36337     wuffs_base__slice_u8 i_slice_curr = a_curr;
36338     v_curr.ptr = i_slice_curr.ptr;
36339     v_curr.len = 4;
36340     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36341     while (v_curr.ptr < i_end0_curr) {
36342       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36343       v_fx = vadd_u8(v_fx, v_fa);
36344       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36345       v_fa = v_fx;
36346       v_curr.ptr += 4;
36347       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36348       v_fx = vadd_u8(v_fx, v_fa);
36349       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36350       v_fa = v_fx;
36351       v_curr.ptr += 4;
36352     }
36353     v_curr.len = 4;
36354     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36355     while (v_curr.ptr < i_end1_curr) {
36356       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36357       v_fx = vadd_u8(v_fx, v_fa);
36358       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36359       v_fa = v_fx;
36360       v_curr.ptr += 4;
36361     }
36362     v_curr.len = 0;
36363   }
36364   return wuffs_base__make_empty_struct();
36365 }
36366 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36367 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36368 
36369 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36370 // -------- func png.decoder.filter_3_distance_4_arm_neon
36371 
36372 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36373 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)36374 wuffs_png__decoder__filter_3_distance_4_arm_neon(
36375     wuffs_png__decoder* self,
36376     wuffs_base__slice_u8 a_curr,
36377     wuffs_base__slice_u8 a_prev) {
36378   wuffs_base__slice_u8 v_curr = {0};
36379   wuffs_base__slice_u8 v_prev = {0};
36380   uint8x8_t v_fa = {0};
36381   uint8x8_t v_fb = {0};
36382   uint8x8_t v_fx = {0};
36383 
36384   if (((uint64_t)(a_prev.len)) == 0) {
36385     {
36386       wuffs_base__slice_u8 i_slice_curr = a_curr;
36387       v_curr.ptr = i_slice_curr.ptr;
36388       v_curr.len = 4;
36389       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36390       while (v_curr.ptr < i_end0_curr) {
36391         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36392         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36393         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36394         v_fa = v_fx;
36395         v_curr.ptr += 4;
36396         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36397         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36398         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36399         v_fa = v_fx;
36400         v_curr.ptr += 4;
36401       }
36402       v_curr.len = 4;
36403       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36404       while (v_curr.ptr < i_end1_curr) {
36405         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36406         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36407         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36408         v_fa = v_fx;
36409         v_curr.ptr += 4;
36410       }
36411       v_curr.len = 0;
36412     }
36413   } else {
36414     {
36415       wuffs_base__slice_u8 i_slice_curr = a_curr;
36416       v_curr.ptr = i_slice_curr.ptr;
36417       wuffs_base__slice_u8 i_slice_prev = a_prev;
36418       v_prev.ptr = i_slice_prev.ptr;
36419       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36420       v_curr.len = 4;
36421       v_prev.len = 4;
36422       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36423       while (v_curr.ptr < i_end0_curr) {
36424         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36425         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36426         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36427         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36428         v_fa = v_fx;
36429         v_curr.ptr += 4;
36430         v_prev.ptr += 4;
36431         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36432         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36433         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36434         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36435         v_fa = v_fx;
36436         v_curr.ptr += 4;
36437         v_prev.ptr += 4;
36438       }
36439       v_curr.len = 4;
36440       v_prev.len = 4;
36441       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36442       while (v_curr.ptr < i_end1_curr) {
36443         v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36444         v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36445         v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36446         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36447         v_fa = v_fx;
36448         v_curr.ptr += 4;
36449         v_prev.ptr += 4;
36450       }
36451       v_curr.len = 0;
36452       v_prev.len = 0;
36453     }
36454   }
36455   return wuffs_base__make_empty_struct();
36456 }
36457 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36458 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36459 
36460 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36461 // -------- func png.decoder.filter_4_distance_3_arm_neon
36462 
36463 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36464 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)36465 wuffs_png__decoder__filter_4_distance_3_arm_neon(
36466     wuffs_png__decoder* self,
36467     wuffs_base__slice_u8 a_curr,
36468     wuffs_base__slice_u8 a_prev) {
36469   wuffs_base__slice_u8 v_curr = {0};
36470   wuffs_base__slice_u8 v_prev = {0};
36471   uint8x8_t v_fa = {0};
36472   uint8x8_t v_fb = {0};
36473   uint8x8_t v_fc = {0};
36474   uint8x8_t v_fx = {0};
36475   uint16x8_t v_fafb = {0};
36476   uint16x8_t v_fcfc = {0};
36477   uint16x8_t v_pa = {0};
36478   uint16x8_t v_pb = {0};
36479   uint16x8_t v_pc = {0};
36480   uint16x8_t v_cmpab = {0};
36481   uint16x8_t v_cmpac = {0};
36482   uint8x8_t v_picka = {0};
36483   uint8x8_t v_pickb = {0};
36484 
36485   {
36486     wuffs_base__slice_u8 i_slice_curr = a_curr;
36487     v_curr.ptr = i_slice_curr.ptr;
36488     wuffs_base__slice_u8 i_slice_prev = a_prev;
36489     v_prev.ptr = i_slice_prev.ptr;
36490     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36491     v_curr.len = 4;
36492     v_prev.len = 4;
36493     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);
36494     while (v_curr.ptr < i_end0_curr) {
36495       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36496       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36497       v_fafb = vaddl_u8(v_fa, v_fb);
36498       v_fcfc = vaddl_u8(v_fc, v_fc);
36499       v_pa = vabdl_u8(v_fb, v_fc);
36500       v_pb = vabdl_u8(v_fa, v_fc);
36501       v_pc = vabdq_u16(v_fafb, v_fcfc);
36502       v_cmpab = vcleq_u16(v_pa, v_pb);
36503       v_cmpac = vcleq_u16(v_pa, v_pc);
36504       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36505       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36506       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36507       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36508       v_fc = v_fb;
36509       v_fa = v_fx;
36510       v_curr.ptr += 3;
36511       v_prev.ptr += 3;
36512       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36513       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36514       v_fafb = vaddl_u8(v_fa, v_fb);
36515       v_fcfc = vaddl_u8(v_fc, v_fc);
36516       v_pa = vabdl_u8(v_fb, v_fc);
36517       v_pb = vabdl_u8(v_fa, v_fc);
36518       v_pc = vabdq_u16(v_fafb, v_fcfc);
36519       v_cmpab = vcleq_u16(v_pa, v_pb);
36520       v_cmpac = vcleq_u16(v_pa, v_pc);
36521       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36522       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36523       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36524       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36525       v_fc = v_fb;
36526       v_fa = v_fx;
36527       v_curr.ptr += 3;
36528       v_prev.ptr += 3;
36529     }
36530     v_curr.len = 4;
36531     v_prev.len = 4;
36532     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);
36533     while (v_curr.ptr < i_end1_curr) {
36534       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36535       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36536       v_fafb = vaddl_u8(v_fa, v_fb);
36537       v_fcfc = vaddl_u8(v_fc, v_fc);
36538       v_pa = vabdl_u8(v_fb, v_fc);
36539       v_pb = vabdl_u8(v_fa, v_fc);
36540       v_pc = vabdq_u16(v_fafb, v_fcfc);
36541       v_cmpab = vcleq_u16(v_pa, v_pb);
36542       v_cmpac = vcleq_u16(v_pa, v_pc);
36543       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36544       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36545       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36546       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36547       v_fc = v_fb;
36548       v_fa = v_fx;
36549       v_curr.ptr += 3;
36550       v_prev.ptr += 3;
36551     }
36552     v_curr.len = 3;
36553     v_prev.len = 3;
36554     uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36555     while (v_curr.ptr < i_end2_curr) {
36556       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
36557       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
36558       v_fafb = vaddl_u8(v_fa, v_fb);
36559       v_fcfc = vaddl_u8(v_fc, v_fc);
36560       v_pa = vabdl_u8(v_fb, v_fc);
36561       v_pb = vabdl_u8(v_fa, v_fc);
36562       v_pc = vabdq_u16(v_fafb, v_fcfc);
36563       v_cmpab = vcleq_u16(v_pa, v_pb);
36564       v_cmpac = vcleq_u16(v_pa, v_pc);
36565       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36566       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36567       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36568       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36569       v_curr.ptr += 3;
36570       v_prev.ptr += 3;
36571     }
36572     v_curr.len = 0;
36573     v_prev.len = 0;
36574   }
36575   return wuffs_base__make_empty_struct();
36576 }
36577 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36578 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36579 
36580 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36581 // -------- func png.decoder.filter_4_distance_4_arm_neon
36582 
36583 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36584 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)36585 wuffs_png__decoder__filter_4_distance_4_arm_neon(
36586     wuffs_png__decoder* self,
36587     wuffs_base__slice_u8 a_curr,
36588     wuffs_base__slice_u8 a_prev) {
36589   wuffs_base__slice_u8 v_curr = {0};
36590   wuffs_base__slice_u8 v_prev = {0};
36591   uint8x8_t v_fa = {0};
36592   uint8x8_t v_fb = {0};
36593   uint8x8_t v_fc = {0};
36594   uint8x8_t v_fx = {0};
36595   uint16x8_t v_fafb = {0};
36596   uint16x8_t v_fcfc = {0};
36597   uint16x8_t v_pa = {0};
36598   uint16x8_t v_pb = {0};
36599   uint16x8_t v_pc = {0};
36600   uint16x8_t v_cmpab = {0};
36601   uint16x8_t v_cmpac = {0};
36602   uint8x8_t v_picka = {0};
36603   uint8x8_t v_pickb = {0};
36604 
36605   {
36606     wuffs_base__slice_u8 i_slice_curr = a_curr;
36607     v_curr.ptr = i_slice_curr.ptr;
36608     wuffs_base__slice_u8 i_slice_prev = a_prev;
36609     v_prev.ptr = i_slice_prev.ptr;
36610     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36611     v_curr.len = 4;
36612     v_prev.len = 4;
36613     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36614     while (v_curr.ptr < i_end0_curr) {
36615       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36616       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36617       v_fafb = vaddl_u8(v_fa, v_fb);
36618       v_fcfc = vaddl_u8(v_fc, v_fc);
36619       v_pa = vabdl_u8(v_fb, v_fc);
36620       v_pb = vabdl_u8(v_fa, v_fc);
36621       v_pc = vabdq_u16(v_fafb, v_fcfc);
36622       v_cmpab = vcleq_u16(v_pa, v_pb);
36623       v_cmpac = vcleq_u16(v_pa, v_pc);
36624       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36625       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36626       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36627       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36628       v_fc = v_fb;
36629       v_fa = v_fx;
36630       v_curr.ptr += 4;
36631       v_prev.ptr += 4;
36632       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36633       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36634       v_fafb = vaddl_u8(v_fa, v_fb);
36635       v_fcfc = vaddl_u8(v_fc, v_fc);
36636       v_pa = vabdl_u8(v_fb, v_fc);
36637       v_pb = vabdl_u8(v_fa, v_fc);
36638       v_pc = vabdq_u16(v_fafb, v_fcfc);
36639       v_cmpab = vcleq_u16(v_pa, v_pb);
36640       v_cmpac = vcleq_u16(v_pa, v_pc);
36641       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36642       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36643       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36644       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36645       v_fc = v_fb;
36646       v_fa = v_fx;
36647       v_curr.ptr += 4;
36648       v_prev.ptr += 4;
36649     }
36650     v_curr.len = 4;
36651     v_prev.len = 4;
36652     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36653     while (v_curr.ptr < i_end1_curr) {
36654       v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36655       v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36656       v_fafb = vaddl_u8(v_fa, v_fb);
36657       v_fcfc = vaddl_u8(v_fc, v_fc);
36658       v_pa = vabdl_u8(v_fb, v_fc);
36659       v_pb = vabdl_u8(v_fa, v_fc);
36660       v_pc = vabdq_u16(v_fafb, v_fcfc);
36661       v_cmpab = vcleq_u16(v_pa, v_pb);
36662       v_cmpac = vcleq_u16(v_pa, v_pc);
36663       v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36664       v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36665       v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36666       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36667       v_fc = v_fb;
36668       v_fa = v_fx;
36669       v_curr.ptr += 4;
36670       v_prev.ptr += 4;
36671     }
36672     v_curr.len = 0;
36673     v_prev.len = 0;
36674   }
36675   return wuffs_base__make_empty_struct();
36676 }
36677 #endif  // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36678 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36679 
36680 // -------- func png.decoder.filter_1
36681 
36682 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36683 wuffs_png__decoder__filter_1(
36684     wuffs_png__decoder* self,
36685     wuffs_base__slice_u8 a_curr) {
36686   return (*self->private_impl.choosy_filter_1)(self, a_curr);
36687 }
36688 
36689 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36690 wuffs_png__decoder__filter_1__choosy_default(
36691     wuffs_png__decoder* self,
36692     wuffs_base__slice_u8 a_curr) {
36693   uint64_t v_filter_distance = 0;
36694   uint8_t v_fa = 0;
36695   uint64_t v_i_start = 0;
36696   uint64_t v_i = 0;
36697 
36698   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
36699   v_i_start = 0;
36700   while (v_i_start < v_filter_distance) {
36701     v_fa = 0;
36702     v_i = v_i_start;
36703     while (v_i < ((uint64_t)(a_curr.len))) {
36704       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa));
36705       v_fa = a_curr.ptr[v_i];
36706       v_i += v_filter_distance;
36707     }
36708     v_i_start += 1;
36709   }
36710   return wuffs_base__make_empty_struct();
36711 }
36712 
36713 // -------- func png.decoder.filter_1_distance_3_fallback
36714 
36715 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36716 wuffs_png__decoder__filter_1_distance_3_fallback(
36717     wuffs_png__decoder* self,
36718     wuffs_base__slice_u8 a_curr) {
36719   wuffs_base__slice_u8 v_curr = {0};
36720   uint8_t v_fa0 = 0;
36721   uint8_t v_fa1 = 0;
36722   uint8_t v_fa2 = 0;
36723 
36724   {
36725     wuffs_base__slice_u8 i_slice_curr = a_curr;
36726     v_curr.ptr = i_slice_curr.ptr;
36727     v_curr.len = 3;
36728     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36729     while (v_curr.ptr < i_end0_curr) {
36730       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36731       v_curr.ptr[0] = v_fa0;
36732       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36733       v_curr.ptr[1] = v_fa1;
36734       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36735       v_curr.ptr[2] = v_fa2;
36736       v_curr.ptr += 3;
36737       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36738       v_curr.ptr[0] = v_fa0;
36739       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36740       v_curr.ptr[1] = v_fa1;
36741       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36742       v_curr.ptr[2] = v_fa2;
36743       v_curr.ptr += 3;
36744     }
36745     v_curr.len = 3;
36746     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36747     while (v_curr.ptr < i_end1_curr) {
36748       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36749       v_curr.ptr[0] = v_fa0;
36750       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36751       v_curr.ptr[1] = v_fa1;
36752       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36753       v_curr.ptr[2] = v_fa2;
36754       v_curr.ptr += 3;
36755     }
36756     v_curr.len = 0;
36757   }
36758   return wuffs_base__make_empty_struct();
36759 }
36760 
36761 // -------- func png.decoder.filter_1_distance_4_fallback
36762 
36763 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36764 wuffs_png__decoder__filter_1_distance_4_fallback(
36765     wuffs_png__decoder* self,
36766     wuffs_base__slice_u8 a_curr) {
36767   wuffs_base__slice_u8 v_curr = {0};
36768   uint8_t v_fa0 = 0;
36769   uint8_t v_fa1 = 0;
36770   uint8_t v_fa2 = 0;
36771   uint8_t v_fa3 = 0;
36772 
36773   {
36774     wuffs_base__slice_u8 i_slice_curr = a_curr;
36775     v_curr.ptr = i_slice_curr.ptr;
36776     v_curr.len = 4;
36777     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36778     while (v_curr.ptr < i_end0_curr) {
36779       v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36780       v_curr.ptr[0] = v_fa0;
36781       v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36782       v_curr.ptr[1] = v_fa1;
36783       v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36784       v_curr.ptr[2] = v_fa2;
36785       v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3]));
36786       v_curr.ptr[3] = v_fa3;
36787       v_curr.ptr += 4;
36788     }
36789     v_curr.len = 0;
36790   }
36791   return wuffs_base__make_empty_struct();
36792 }
36793 
36794 // -------- func png.decoder.filter_2
36795 
36796 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)36797 wuffs_png__decoder__filter_2(
36798     wuffs_png__decoder* self,
36799     wuffs_base__slice_u8 a_curr,
36800     wuffs_base__slice_u8 a_prev) {
36801   uint64_t v_n = 0;
36802   uint64_t v_i = 0;
36803 
36804   v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
36805   v_i = 0;
36806   while (v_i < v_n) {
36807     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
36808     v_i += 1;
36809   }
36810   return wuffs_base__make_empty_struct();
36811 }
36812 
36813 // -------- func png.decoder.filter_3
36814 
36815 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)36816 wuffs_png__decoder__filter_3(
36817     wuffs_png__decoder* self,
36818     wuffs_base__slice_u8 a_curr,
36819     wuffs_base__slice_u8 a_prev) {
36820   return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev);
36821 }
36822 
36823 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)36824 wuffs_png__decoder__filter_3__choosy_default(
36825     wuffs_png__decoder* self,
36826     wuffs_base__slice_u8 a_curr,
36827     wuffs_base__slice_u8 a_prev) {
36828   uint64_t v_filter_distance = 0;
36829   uint64_t v_n = 0;
36830   uint64_t v_i = 0;
36831 
36832   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
36833   if (((uint64_t)(a_prev.len)) == 0) {
36834     v_i = v_filter_distance;
36835     while (v_i < ((uint64_t)(a_curr.len))) {
36836       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_curr.ptr[(v_i - v_filter_distance)] / 2)));
36837       v_i += 1;
36838     }
36839   } else {
36840     v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
36841     v_i = 0;
36842     while ((v_i < v_n) && (v_i < v_filter_distance)) {
36843       a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_prev.ptr[v_i] / 2)));
36844       v_i += 1;
36845     }
36846     v_i = v_filter_distance;
36847     while (v_i < v_n) {
36848       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)))));
36849       v_i += 1;
36850     }
36851   }
36852   return wuffs_base__make_empty_struct();
36853 }
36854 
36855 // -------- func png.decoder.filter_3_distance_3_fallback
36856 
36857 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)36858 wuffs_png__decoder__filter_3_distance_3_fallback(
36859     wuffs_png__decoder* self,
36860     wuffs_base__slice_u8 a_curr,
36861     wuffs_base__slice_u8 a_prev) {
36862   wuffs_base__slice_u8 v_curr = {0};
36863   wuffs_base__slice_u8 v_prev = {0};
36864   uint8_t v_fa0 = 0;
36865   uint8_t v_fa1 = 0;
36866   uint8_t v_fa2 = 0;
36867 
36868   if (((uint64_t)(a_prev.len)) == 0) {
36869     {
36870       wuffs_base__slice_u8 i_slice_curr = a_curr;
36871       v_curr.ptr = i_slice_curr.ptr;
36872       v_curr.len = 3;
36873       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36874       while (v_curr.ptr < i_end0_curr) {
36875         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36876         v_curr.ptr[0] = v_fa0;
36877         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36878         v_curr.ptr[1] = v_fa1;
36879         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36880         v_curr.ptr[2] = v_fa2;
36881         v_curr.ptr += 3;
36882         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36883         v_curr.ptr[0] = v_fa0;
36884         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36885         v_curr.ptr[1] = v_fa1;
36886         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36887         v_curr.ptr[2] = v_fa2;
36888         v_curr.ptr += 3;
36889       }
36890       v_curr.len = 3;
36891       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36892       while (v_curr.ptr < i_end1_curr) {
36893         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36894         v_curr.ptr[0] = v_fa0;
36895         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36896         v_curr.ptr[1] = v_fa1;
36897         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36898         v_curr.ptr[2] = v_fa2;
36899         v_curr.ptr += 3;
36900       }
36901       v_curr.len = 0;
36902     }
36903   } else {
36904     {
36905       wuffs_base__slice_u8 i_slice_curr = a_curr;
36906       v_curr.ptr = i_slice_curr.ptr;
36907       wuffs_base__slice_u8 i_slice_prev = a_prev;
36908       v_prev.ptr = i_slice_prev.ptr;
36909       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36910       v_curr.len = 3;
36911       v_prev.len = 3;
36912       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36913       while (v_curr.ptr < i_end0_curr) {
36914         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36915         v_curr.ptr[0] = v_fa0;
36916         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36917         v_curr.ptr[1] = v_fa1;
36918         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36919         v_curr.ptr[2] = v_fa2;
36920         v_curr.ptr += 3;
36921         v_prev.ptr += 3;
36922         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36923         v_curr.ptr[0] = v_fa0;
36924         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36925         v_curr.ptr[1] = v_fa1;
36926         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36927         v_curr.ptr[2] = v_fa2;
36928         v_curr.ptr += 3;
36929         v_prev.ptr += 3;
36930       }
36931       v_curr.len = 3;
36932       v_prev.len = 3;
36933       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36934       while (v_curr.ptr < i_end1_curr) {
36935         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36936         v_curr.ptr[0] = v_fa0;
36937         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36938         v_curr.ptr[1] = v_fa1;
36939         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36940         v_curr.ptr[2] = v_fa2;
36941         v_curr.ptr += 3;
36942         v_prev.ptr += 3;
36943       }
36944       v_curr.len = 0;
36945       v_prev.len = 0;
36946     }
36947   }
36948   return wuffs_base__make_empty_struct();
36949 }
36950 
36951 // -------- func png.decoder.filter_3_distance_4_fallback
36952 
36953 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)36954 wuffs_png__decoder__filter_3_distance_4_fallback(
36955     wuffs_png__decoder* self,
36956     wuffs_base__slice_u8 a_curr,
36957     wuffs_base__slice_u8 a_prev) {
36958   wuffs_base__slice_u8 v_curr = {0};
36959   wuffs_base__slice_u8 v_prev = {0};
36960   uint8_t v_fa0 = 0;
36961   uint8_t v_fa1 = 0;
36962   uint8_t v_fa2 = 0;
36963   uint8_t v_fa3 = 0;
36964 
36965   if (((uint64_t)(a_prev.len)) == 0) {
36966     {
36967       wuffs_base__slice_u8 i_slice_curr = a_curr;
36968       v_curr.ptr = i_slice_curr.ptr;
36969       v_curr.len = 4;
36970       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36971       while (v_curr.ptr < i_end0_curr) {
36972         v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36973         v_curr.ptr[0] = v_fa0;
36974         v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36975         v_curr.ptr[1] = v_fa1;
36976         v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36977         v_curr.ptr[2] = v_fa2;
36978         v_fa3 = ((uint8_t)((v_fa3 / 2) + v_curr.ptr[3]));
36979         v_curr.ptr[3] = v_fa3;
36980         v_curr.ptr += 4;
36981       }
36982       v_curr.len = 0;
36983     }
36984   } else {
36985     {
36986       wuffs_base__slice_u8 i_slice_curr = a_curr;
36987       v_curr.ptr = i_slice_curr.ptr;
36988       wuffs_base__slice_u8 i_slice_prev = a_prev;
36989       v_prev.ptr = i_slice_prev.ptr;
36990       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36991       v_curr.len = 4;
36992       v_prev.len = 4;
36993       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36994       while (v_curr.ptr < i_end0_curr) {
36995         v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36996         v_curr.ptr[0] = v_fa0;
36997         v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36998         v_curr.ptr[1] = v_fa1;
36999         v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
37000         v_curr.ptr[2] = v_fa2;
37001         v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3]))) / 2))) + v_curr.ptr[3]));
37002         v_curr.ptr[3] = v_fa3;
37003         v_curr.ptr += 4;
37004         v_prev.ptr += 4;
37005       }
37006       v_curr.len = 0;
37007       v_prev.len = 0;
37008     }
37009   }
37010   return wuffs_base__make_empty_struct();
37011 }
37012 
37013 // -------- func png.decoder.filter_4
37014 
37015 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)37016 wuffs_png__decoder__filter_4(
37017     wuffs_png__decoder* self,
37018     wuffs_base__slice_u8 a_curr,
37019     wuffs_base__slice_u8 a_prev) {
37020   return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev);
37021 }
37022 
37023 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)37024 wuffs_png__decoder__filter_4__choosy_default(
37025     wuffs_png__decoder* self,
37026     wuffs_base__slice_u8 a_curr,
37027     wuffs_base__slice_u8 a_prev) {
37028   uint64_t v_filter_distance = 0;
37029   uint64_t v_n = 0;
37030   uint64_t v_i = 0;
37031   uint32_t v_fa = 0;
37032   uint32_t v_fb = 0;
37033   uint32_t v_fc = 0;
37034   uint32_t v_pp = 0;
37035   uint32_t v_pa = 0;
37036   uint32_t v_pb = 0;
37037   uint32_t v_pc = 0;
37038 
37039   v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
37040   v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
37041   v_i = 0;
37042   while ((v_i < v_n) && (v_i < v_filter_distance)) {
37043     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
37044     v_i += 1;
37045   }
37046   v_i = v_filter_distance;
37047   while (v_i < v_n) {
37048     v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
37049     v_fb = ((uint32_t)(a_prev.ptr[v_i]));
37050     v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
37051     v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc));
37052     v_pa = ((uint32_t)(v_pp - v_fa));
37053     if (v_pa >= 2147483648) {
37054       v_pa = ((uint32_t)(0 - v_pa));
37055     }
37056     v_pb = ((uint32_t)(v_pp - v_fb));
37057     if (v_pb >= 2147483648) {
37058       v_pb = ((uint32_t)(0 - v_pb));
37059     }
37060     v_pc = ((uint32_t)(v_pp - v_fc));
37061     if (v_pc >= 2147483648) {
37062       v_pc = ((uint32_t)(0 - v_pc));
37063     }
37064     if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
37065     } else if (v_pb <= v_pc) {
37066       v_fa = v_fb;
37067     } else {
37068       v_fa = v_fc;
37069     }
37070     a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)((v_fa & 255)))));
37071     v_i += 1;
37072   }
37073   return wuffs_base__make_empty_struct();
37074 }
37075 
37076 // -------- func png.decoder.filter_4_distance_3_fallback
37077 
37078 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)37079 wuffs_png__decoder__filter_4_distance_3_fallback(
37080     wuffs_png__decoder* self,
37081     wuffs_base__slice_u8 a_curr,
37082     wuffs_base__slice_u8 a_prev) {
37083   wuffs_base__slice_u8 v_curr = {0};
37084   wuffs_base__slice_u8 v_prev = {0};
37085   uint32_t v_fa0 = 0;
37086   uint32_t v_fa1 = 0;
37087   uint32_t v_fa2 = 0;
37088   uint32_t v_fb0 = 0;
37089   uint32_t v_fb1 = 0;
37090   uint32_t v_fb2 = 0;
37091   uint32_t v_fc0 = 0;
37092   uint32_t v_fc1 = 0;
37093   uint32_t v_fc2 = 0;
37094   uint32_t v_pp0 = 0;
37095   uint32_t v_pp1 = 0;
37096   uint32_t v_pp2 = 0;
37097   uint32_t v_pa0 = 0;
37098   uint32_t v_pa1 = 0;
37099   uint32_t v_pa2 = 0;
37100   uint32_t v_pb0 = 0;
37101   uint32_t v_pb1 = 0;
37102   uint32_t v_pb2 = 0;
37103   uint32_t v_pc0 = 0;
37104   uint32_t v_pc1 = 0;
37105   uint32_t v_pc2 = 0;
37106 
37107   {
37108     wuffs_base__slice_u8 i_slice_curr = a_curr;
37109     v_curr.ptr = i_slice_curr.ptr;
37110     wuffs_base__slice_u8 i_slice_prev = a_prev;
37111     v_prev.ptr = i_slice_prev.ptr;
37112     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37113     v_curr.len = 3;
37114     v_prev.len = 3;
37115     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
37116     while (v_curr.ptr < i_end0_curr) {
37117       v_fb0 = ((uint32_t)(v_prev.ptr[0]));
37118       v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
37119       v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
37120       if (v_pa0 >= 2147483648) {
37121         v_pa0 = ((uint32_t)(0 - v_pa0));
37122       }
37123       v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
37124       if (v_pb0 >= 2147483648) {
37125         v_pb0 = ((uint32_t)(0 - v_pb0));
37126       }
37127       v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
37128       if (v_pc0 >= 2147483648) {
37129         v_pc0 = ((uint32_t)(0 - v_pc0));
37130       }
37131       if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
37132       } else if (v_pb0 <= v_pc0) {
37133         v_fa0 = v_fb0;
37134       } else {
37135         v_fa0 = v_fc0;
37136       }
37137       v_curr.ptr[0] = ((uint8_t)(v_curr.ptr[0] + ((uint8_t)((v_fa0 & 255)))));
37138       v_fa0 = ((uint32_t)(v_curr.ptr[0]));
37139       v_fc0 = v_fb0;
37140       v_fb1 = ((uint32_t)(v_prev.ptr[1]));
37141       v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
37142       v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
37143       if (v_pa1 >= 2147483648) {
37144         v_pa1 = ((uint32_t)(0 - v_pa1));
37145       }
37146       v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
37147       if (v_pb1 >= 2147483648) {
37148         v_pb1 = ((uint32_t)(0 - v_pb1));
37149       }
37150       v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
37151       if (v_pc1 >= 2147483648) {
37152         v_pc1 = ((uint32_t)(0 - v_pc1));
37153       }
37154       if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
37155       } else if (v_pb1 <= v_pc1) {
37156         v_fa1 = v_fb1;
37157       } else {
37158         v_fa1 = v_fc1;
37159       }
37160       v_curr.ptr[1] = ((uint8_t)(v_curr.ptr[1] + ((uint8_t)((v_fa1 & 255)))));
37161       v_fa1 = ((uint32_t)(v_curr.ptr[1]));
37162       v_fc1 = v_fb1;
37163       v_fb2 = ((uint32_t)(v_prev.ptr[2]));
37164       v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
37165       v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
37166       if (v_pa2 >= 2147483648) {
37167         v_pa2 = ((uint32_t)(0 - v_pa2));
37168       }
37169       v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
37170       if (v_pb2 >= 2147483648) {
37171         v_pb2 = ((uint32_t)(0 - v_pb2));
37172       }
37173       v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
37174       if (v_pc2 >= 2147483648) {
37175         v_pc2 = ((uint32_t)(0 - v_pc2));
37176       }
37177       if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
37178       } else if (v_pb2 <= v_pc2) {
37179         v_fa2 = v_fb2;
37180       } else {
37181         v_fa2 = v_fc2;
37182       }
37183       v_curr.ptr[2] = ((uint8_t)(v_curr.ptr[2] + ((uint8_t)((v_fa2 & 255)))));
37184       v_fa2 = ((uint32_t)(v_curr.ptr[2]));
37185       v_fc2 = v_fb2;
37186       v_curr.ptr += 3;
37187       v_prev.ptr += 3;
37188     }
37189     v_curr.len = 0;
37190     v_prev.len = 0;
37191   }
37192   return wuffs_base__make_empty_struct();
37193 }
37194 
37195 // -------- func png.decoder.filter_4_distance_4_fallback
37196 
37197 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)37198 wuffs_png__decoder__filter_4_distance_4_fallback(
37199     wuffs_png__decoder* self,
37200     wuffs_base__slice_u8 a_curr,
37201     wuffs_base__slice_u8 a_prev) {
37202   wuffs_base__slice_u8 v_curr = {0};
37203   wuffs_base__slice_u8 v_prev = {0};
37204   uint32_t v_fa0 = 0;
37205   uint32_t v_fa1 = 0;
37206   uint32_t v_fa2 = 0;
37207   uint32_t v_fa3 = 0;
37208   uint32_t v_fb0 = 0;
37209   uint32_t v_fb1 = 0;
37210   uint32_t v_fb2 = 0;
37211   uint32_t v_fb3 = 0;
37212   uint32_t v_fc0 = 0;
37213   uint32_t v_fc1 = 0;
37214   uint32_t v_fc2 = 0;
37215   uint32_t v_fc3 = 0;
37216   uint32_t v_pp0 = 0;
37217   uint32_t v_pp1 = 0;
37218   uint32_t v_pp2 = 0;
37219   uint32_t v_pp3 = 0;
37220   uint32_t v_pa0 = 0;
37221   uint32_t v_pa1 = 0;
37222   uint32_t v_pa2 = 0;
37223   uint32_t v_pa3 = 0;
37224   uint32_t v_pb0 = 0;
37225   uint32_t v_pb1 = 0;
37226   uint32_t v_pb2 = 0;
37227   uint32_t v_pb3 = 0;
37228   uint32_t v_pc0 = 0;
37229   uint32_t v_pc1 = 0;
37230   uint32_t v_pc2 = 0;
37231   uint32_t v_pc3 = 0;
37232 
37233   {
37234     wuffs_base__slice_u8 i_slice_curr = a_curr;
37235     v_curr.ptr = i_slice_curr.ptr;
37236     wuffs_base__slice_u8 i_slice_prev = a_prev;
37237     v_prev.ptr = i_slice_prev.ptr;
37238     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37239     v_curr.len = 4;
37240     v_prev.len = 4;
37241     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37242     while (v_curr.ptr < i_end0_curr) {
37243       v_fb0 = ((uint32_t)(v_prev.ptr[0]));
37244       v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
37245       v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
37246       if (v_pa0 >= 2147483648) {
37247         v_pa0 = ((uint32_t)(0 - v_pa0));
37248       }
37249       v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
37250       if (v_pb0 >= 2147483648) {
37251         v_pb0 = ((uint32_t)(0 - v_pb0));
37252       }
37253       v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
37254       if (v_pc0 >= 2147483648) {
37255         v_pc0 = ((uint32_t)(0 - v_pc0));
37256       }
37257       if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
37258       } else if (v_pb0 <= v_pc0) {
37259         v_fa0 = v_fb0;
37260       } else {
37261         v_fa0 = v_fc0;
37262       }
37263       v_curr.ptr[0] = ((uint8_t)(v_curr.ptr[0] + ((uint8_t)((v_fa0 & 255)))));
37264       v_fa0 = ((uint32_t)(v_curr.ptr[0]));
37265       v_fc0 = v_fb0;
37266       v_fb1 = ((uint32_t)(v_prev.ptr[1]));
37267       v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
37268       v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
37269       if (v_pa1 >= 2147483648) {
37270         v_pa1 = ((uint32_t)(0 - v_pa1));
37271       }
37272       v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
37273       if (v_pb1 >= 2147483648) {
37274         v_pb1 = ((uint32_t)(0 - v_pb1));
37275       }
37276       v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
37277       if (v_pc1 >= 2147483648) {
37278         v_pc1 = ((uint32_t)(0 - v_pc1));
37279       }
37280       if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
37281       } else if (v_pb1 <= v_pc1) {
37282         v_fa1 = v_fb1;
37283       } else {
37284         v_fa1 = v_fc1;
37285       }
37286       v_curr.ptr[1] = ((uint8_t)(v_curr.ptr[1] + ((uint8_t)((v_fa1 & 255)))));
37287       v_fa1 = ((uint32_t)(v_curr.ptr[1]));
37288       v_fc1 = v_fb1;
37289       v_fb2 = ((uint32_t)(v_prev.ptr[2]));
37290       v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
37291       v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
37292       if (v_pa2 >= 2147483648) {
37293         v_pa2 = ((uint32_t)(0 - v_pa2));
37294       }
37295       v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
37296       if (v_pb2 >= 2147483648) {
37297         v_pb2 = ((uint32_t)(0 - v_pb2));
37298       }
37299       v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
37300       if (v_pc2 >= 2147483648) {
37301         v_pc2 = ((uint32_t)(0 - v_pc2));
37302       }
37303       if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
37304       } else if (v_pb2 <= v_pc2) {
37305         v_fa2 = v_fb2;
37306       } else {
37307         v_fa2 = v_fc2;
37308       }
37309       v_curr.ptr[2] = ((uint8_t)(v_curr.ptr[2] + ((uint8_t)((v_fa2 & 255)))));
37310       v_fa2 = ((uint32_t)(v_curr.ptr[2]));
37311       v_fc2 = v_fb2;
37312       v_fb3 = ((uint32_t)(v_prev.ptr[3]));
37313       v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3));
37314       v_pa3 = ((uint32_t)(v_pp3 - v_fa3));
37315       if (v_pa3 >= 2147483648) {
37316         v_pa3 = ((uint32_t)(0 - v_pa3));
37317       }
37318       v_pb3 = ((uint32_t)(v_pp3 - v_fb3));
37319       if (v_pb3 >= 2147483648) {
37320         v_pb3 = ((uint32_t)(0 - v_pb3));
37321       }
37322       v_pc3 = ((uint32_t)(v_pp3 - v_fc3));
37323       if (v_pc3 >= 2147483648) {
37324         v_pc3 = ((uint32_t)(0 - v_pc3));
37325       }
37326       if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) {
37327       } else if (v_pb3 <= v_pc3) {
37328         v_fa3 = v_fb3;
37329       } else {
37330         v_fa3 = v_fc3;
37331       }
37332       v_curr.ptr[3] = ((uint8_t)(v_curr.ptr[3] + ((uint8_t)((v_fa3 & 255)))));
37333       v_fa3 = ((uint32_t)(v_curr.ptr[3]));
37334       v_fc3 = v_fb3;
37335       v_curr.ptr += 4;
37336       v_prev.ptr += 4;
37337     }
37338     v_curr.len = 0;
37339     v_prev.len = 0;
37340   }
37341   return wuffs_base__make_empty_struct();
37342 }
37343 
37344 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37345 // -------- func png.decoder.filter_1_distance_4_x86_sse42
37346 
37347 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37348 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37349 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)37350 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
37351     wuffs_png__decoder* self,
37352     wuffs_base__slice_u8 a_curr) {
37353   wuffs_base__slice_u8 v_curr = {0};
37354   __m128i v_x128 = {0};
37355   __m128i v_a128 = {0};
37356 
37357   {
37358     wuffs_base__slice_u8 i_slice_curr = a_curr;
37359     v_curr.ptr = i_slice_curr.ptr;
37360     v_curr.len = 4;
37361     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37362     while (v_curr.ptr < i_end0_curr) {
37363       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37364       v_x128 = _mm_add_epi8(v_x128, v_a128);
37365       v_a128 = v_x128;
37366       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37367       v_curr.ptr += 4;
37368       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37369       v_x128 = _mm_add_epi8(v_x128, v_a128);
37370       v_a128 = v_x128;
37371       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37372       v_curr.ptr += 4;
37373     }
37374     v_curr.len = 4;
37375     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37376     while (v_curr.ptr < i_end1_curr) {
37377       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37378       v_x128 = _mm_add_epi8(v_x128, v_a128);
37379       v_a128 = v_x128;
37380       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37381       v_curr.ptr += 4;
37382     }
37383     v_curr.len = 0;
37384   }
37385   return wuffs_base__make_empty_struct();
37386 }
37387 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37388 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37389 
37390 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37391 // -------- func png.decoder.filter_3_distance_4_x86_sse42
37392 
37393 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37394 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37395 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)37396 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
37397     wuffs_png__decoder* self,
37398     wuffs_base__slice_u8 a_curr,
37399     wuffs_base__slice_u8 a_prev) {
37400   wuffs_base__slice_u8 v_curr = {0};
37401   wuffs_base__slice_u8 v_prev = {0};
37402   __m128i v_x128 = {0};
37403   __m128i v_a128 = {0};
37404   __m128i v_b128 = {0};
37405   __m128i v_p128 = {0};
37406   __m128i v_k128 = {0};
37407 
37408   if (((uint64_t)(a_prev.len)) == 0) {
37409     v_k128 = _mm_set1_epi8((int8_t)(254));
37410     {
37411       wuffs_base__slice_u8 i_slice_curr = a_curr;
37412       v_curr.ptr = i_slice_curr.ptr;
37413       v_curr.len = 4;
37414       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37415       while (v_curr.ptr < i_end0_curr) {
37416         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
37417         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37418         v_x128 = _mm_add_epi8(v_x128, v_p128);
37419         v_a128 = v_x128;
37420         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37421         v_curr.ptr += 4;
37422         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
37423         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37424         v_x128 = _mm_add_epi8(v_x128, v_p128);
37425         v_a128 = v_x128;
37426         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37427         v_curr.ptr += 4;
37428       }
37429       v_curr.len = 4;
37430       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37431       while (v_curr.ptr < i_end1_curr) {
37432         v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
37433         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37434         v_x128 = _mm_add_epi8(v_x128, v_p128);
37435         v_a128 = v_x128;
37436         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37437         v_curr.ptr += 4;
37438       }
37439       v_curr.len = 0;
37440     }
37441   } else {
37442     v_k128 = _mm_set1_epi8((int8_t)(1));
37443     {
37444       wuffs_base__slice_u8 i_slice_curr = a_curr;
37445       v_curr.ptr = i_slice_curr.ptr;
37446       wuffs_base__slice_u8 i_slice_prev = a_prev;
37447       v_prev.ptr = i_slice_prev.ptr;
37448       i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37449       v_curr.len = 4;
37450       v_prev.len = 4;
37451       uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37452       while (v_curr.ptr < i_end0_curr) {
37453         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37454         v_p128 = _mm_avg_epu8(v_a128, v_b128);
37455         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
37456         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37457         v_x128 = _mm_add_epi8(v_x128, v_p128);
37458         v_a128 = v_x128;
37459         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37460         v_curr.ptr += 4;
37461         v_prev.ptr += 4;
37462         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37463         v_p128 = _mm_avg_epu8(v_a128, v_b128);
37464         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
37465         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37466         v_x128 = _mm_add_epi8(v_x128, v_p128);
37467         v_a128 = v_x128;
37468         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37469         v_curr.ptr += 4;
37470         v_prev.ptr += 4;
37471       }
37472       v_curr.len = 4;
37473       v_prev.len = 4;
37474       uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37475       while (v_curr.ptr < i_end1_curr) {
37476         v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37477         v_p128 = _mm_avg_epu8(v_a128, v_b128);
37478         v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
37479         v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37480         v_x128 = _mm_add_epi8(v_x128, v_p128);
37481         v_a128 = v_x128;
37482         wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37483         v_curr.ptr += 4;
37484         v_prev.ptr += 4;
37485       }
37486       v_curr.len = 0;
37487       v_prev.len = 0;
37488     }
37489   }
37490   return wuffs_base__make_empty_struct();
37491 }
37492 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37493 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37494 
37495 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37496 // -------- func png.decoder.filter_4_distance_3_x86_sse42
37497 
37498 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37499 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37500 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)37501 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
37502     wuffs_png__decoder* self,
37503     wuffs_base__slice_u8 a_curr,
37504     wuffs_base__slice_u8 a_prev) {
37505   wuffs_base__slice_u8 v_curr = {0};
37506   wuffs_base__slice_u8 v_prev = {0};
37507   __m128i v_x128 = {0};
37508   __m128i v_a128 = {0};
37509   __m128i v_b128 = {0};
37510   __m128i v_c128 = {0};
37511   __m128i v_p128 = {0};
37512   __m128i v_pa128 = {0};
37513   __m128i v_pb128 = {0};
37514   __m128i v_pc128 = {0};
37515   __m128i v_smallest128 = {0};
37516   __m128i v_z128 = {0};
37517 
37518   {
37519     wuffs_base__slice_u8 i_slice_curr = a_curr;
37520     v_curr.ptr = i_slice_curr.ptr;
37521     wuffs_base__slice_u8 i_slice_prev = a_prev;
37522     v_prev.ptr = i_slice_prev.ptr;
37523     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37524     v_curr.len = 4;
37525     v_prev.len = 4;
37526     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);
37527     while (v_curr.ptr < i_end0_curr) {
37528       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37529       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37530       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37531       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37532       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37533       v_pa128 = _mm_abs_epi16(v_pa128);
37534       v_pb128 = _mm_abs_epi16(v_pb128);
37535       v_pc128 = _mm_abs_epi16(v_pc128);
37536       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37537       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));
37538       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37539       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37540       v_x128 = _mm_add_epi8(v_x128, v_p128);
37541       v_a128 = v_x128;
37542       v_c128 = v_b128;
37543       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37544       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37545       v_curr.ptr += 3;
37546       v_prev.ptr += 3;
37547       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37548       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37549       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37550       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37551       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37552       v_pa128 = _mm_abs_epi16(v_pa128);
37553       v_pb128 = _mm_abs_epi16(v_pb128);
37554       v_pc128 = _mm_abs_epi16(v_pc128);
37555       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37556       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));
37557       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37558       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37559       v_x128 = _mm_add_epi8(v_x128, v_p128);
37560       v_a128 = v_x128;
37561       v_c128 = v_b128;
37562       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37563       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37564       v_curr.ptr += 3;
37565       v_prev.ptr += 3;
37566     }
37567     v_curr.len = 4;
37568     v_prev.len = 4;
37569     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);
37570     while (v_curr.ptr < i_end1_curr) {
37571       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37572       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37573       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37574       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37575       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37576       v_pa128 = _mm_abs_epi16(v_pa128);
37577       v_pb128 = _mm_abs_epi16(v_pb128);
37578       v_pc128 = _mm_abs_epi16(v_pc128);
37579       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37580       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));
37581       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37582       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37583       v_x128 = _mm_add_epi8(v_x128, v_p128);
37584       v_a128 = v_x128;
37585       v_c128 = v_b128;
37586       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37587       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37588       v_curr.ptr += 3;
37589       v_prev.ptr += 3;
37590     }
37591     v_curr.len = 3;
37592     v_prev.len = 3;
37593     uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
37594     while (v_curr.ptr < i_end2_curr) {
37595       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
37596       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37597       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37598       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37599       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37600       v_pa128 = _mm_abs_epi16(v_pa128);
37601       v_pb128 = _mm_abs_epi16(v_pb128);
37602       v_pc128 = _mm_abs_epi16(v_pc128);
37603       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37604       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));
37605       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
37606       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37607       v_x128 = _mm_add_epi8(v_x128, v_p128);
37608       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37609       wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37610       v_curr.ptr += 3;
37611       v_prev.ptr += 3;
37612     }
37613     v_curr.len = 0;
37614     v_prev.len = 0;
37615   }
37616   return wuffs_base__make_empty_struct();
37617 }
37618 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37619 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37620 
37621 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37622 // -------- func png.decoder.filter_4_distance_4_x86_sse42
37623 
37624 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37625 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37626 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)37627 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
37628     wuffs_png__decoder* self,
37629     wuffs_base__slice_u8 a_curr,
37630     wuffs_base__slice_u8 a_prev) {
37631   wuffs_base__slice_u8 v_curr = {0};
37632   wuffs_base__slice_u8 v_prev = {0};
37633   __m128i v_x128 = {0};
37634   __m128i v_a128 = {0};
37635   __m128i v_b128 = {0};
37636   __m128i v_c128 = {0};
37637   __m128i v_p128 = {0};
37638   __m128i v_pa128 = {0};
37639   __m128i v_pb128 = {0};
37640   __m128i v_pc128 = {0};
37641   __m128i v_smallest128 = {0};
37642   __m128i v_z128 = {0};
37643 
37644   {
37645     wuffs_base__slice_u8 i_slice_curr = a_curr;
37646     v_curr.ptr = i_slice_curr.ptr;
37647     wuffs_base__slice_u8 i_slice_prev = a_prev;
37648     v_prev.ptr = i_slice_prev.ptr;
37649     i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37650     v_curr.len = 4;
37651     v_prev.len = 4;
37652     uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37653     while (v_curr.ptr < i_end0_curr) {
37654       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37655       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37656       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37657       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37658       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37659       v_pa128 = _mm_abs_epi16(v_pa128);
37660       v_pb128 = _mm_abs_epi16(v_pb128);
37661       v_pc128 = _mm_abs_epi16(v_pc128);
37662       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37663       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));
37664       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37665       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37666       v_x128 = _mm_add_epi8(v_x128, v_p128);
37667       v_a128 = v_x128;
37668       v_c128 = v_b128;
37669       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37670       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37671       v_curr.ptr += 4;
37672       v_prev.ptr += 4;
37673       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37674       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37675       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37676       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37677       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37678       v_pa128 = _mm_abs_epi16(v_pa128);
37679       v_pb128 = _mm_abs_epi16(v_pb128);
37680       v_pc128 = _mm_abs_epi16(v_pc128);
37681       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37682       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));
37683       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37684       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37685       v_x128 = _mm_add_epi8(v_x128, v_p128);
37686       v_a128 = v_x128;
37687       v_c128 = v_b128;
37688       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37689       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37690       v_curr.ptr += 4;
37691       v_prev.ptr += 4;
37692     }
37693     v_curr.len = 4;
37694     v_prev.len = 4;
37695     uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37696     while (v_curr.ptr < i_end1_curr) {
37697       v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37698       v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37699       v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37700       v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37701       v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37702       v_pa128 = _mm_abs_epi16(v_pa128);
37703       v_pb128 = _mm_abs_epi16(v_pb128);
37704       v_pc128 = _mm_abs_epi16(v_pc128);
37705       v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37706       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));
37707       v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37708       v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37709       v_x128 = _mm_add_epi8(v_x128, v_p128);
37710       v_a128 = v_x128;
37711       v_c128 = v_b128;
37712       v_x128 = _mm_packus_epi16(v_x128, v_x128);
37713       wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37714       v_curr.ptr += 4;
37715       v_prev.ptr += 4;
37716     }
37717     v_curr.len = 0;
37718     v_prev.len = 0;
37719   }
37720   return wuffs_base__make_empty_struct();
37721 }
37722 #endif  // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37723 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37724 
37725 // -------- func png.decoder.set_quirk_enabled
37726 
37727 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)37728 wuffs_png__decoder__set_quirk_enabled(
37729     wuffs_png__decoder* self,
37730     uint32_t a_quirk,
37731     bool a_enabled) {
37732   if (!self) {
37733     return wuffs_base__make_empty_struct();
37734   }
37735   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37736     return wuffs_base__make_empty_struct();
37737   }
37738 
37739   if (a_quirk == 1) {
37740     self->private_impl.f_ignore_checksum = a_enabled;
37741     wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, a_quirk, a_enabled);
37742   }
37743   return wuffs_base__make_empty_struct();
37744 }
37745 
37746 // -------- func png.decoder.decode_image_config
37747 
37748 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)37749 wuffs_png__decoder__decode_image_config(
37750     wuffs_png__decoder* self,
37751     wuffs_base__image_config* a_dst,
37752     wuffs_base__io_buffer* a_src) {
37753   if (!self) {
37754     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37755   }
37756   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37757     return wuffs_base__make_status(
37758         (self->private_impl.magic == WUFFS_BASE__DISABLED)
37759         ? wuffs_base__error__disabled_by_previous_error
37760         : wuffs_base__error__initialize_not_called);
37761   }
37762   if (!a_src) {
37763     self->private_impl.magic = WUFFS_BASE__DISABLED;
37764     return wuffs_base__make_status(wuffs_base__error__bad_argument);
37765   }
37766   if ((self->private_impl.active_coroutine != 0) &&
37767       (self->private_impl.active_coroutine != 1)) {
37768     self->private_impl.magic = WUFFS_BASE__DISABLED;
37769     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
37770   }
37771   self->private_impl.active_coroutine = 0;
37772   wuffs_base__status status = wuffs_base__make_status(NULL);
37773 
37774   uint64_t v_magic = 0;
37775   uint64_t v_mark = 0;
37776   uint32_t v_checksum_have = 0;
37777   uint32_t v_checksum_want = 0;
37778   wuffs_base__status v_status = wuffs_base__make_status(NULL);
37779 
37780   const uint8_t* iop_a_src = NULL;
37781   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37782   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37783   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37784   if (a_src) {
37785     io0_a_src = a_src->data.ptr;
37786     io1_a_src = io0_a_src + a_src->meta.ri;
37787     iop_a_src = io1_a_src;
37788     io2_a_src = io0_a_src + a_src->meta.wi;
37789   }
37790 
37791   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
37792   if (coro_susp_point) {
37793     v_checksum_have = self->private_data.s_decode_image_config[0].v_checksum_have;
37794   }
37795   switch (coro_susp_point) {
37796     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37797 
37798     if (self->private_impl.f_call_sequence == 2) {
37799       if (self->private_impl.f_metadata_fourcc != 0) {
37800         self->private_impl.f_call_sequence = 1;
37801         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
37802         goto ok;
37803       }
37804     } else if (self->private_impl.f_call_sequence != 0) {
37805       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
37806       goto exit;
37807     } else {
37808       {
37809         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37810         uint64_t t_0;
37811         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
37812           t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
37813           iop_a_src += 8;
37814         } else {
37815           self->private_data.s_decode_image_config[0].scratch = 0;
37816           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37817           while (true) {
37818             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37819               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37820               goto suspend;
37821             }
37822             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37823             uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
37824             *scratch <<= 8;
37825             *scratch >>= 8;
37826             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
37827             if (num_bits_0 == 56) {
37828               t_0 = ((uint64_t)(*scratch));
37829               break;
37830             }
37831             num_bits_0 += 8;
37832             *scratch |= ((uint64_t)(num_bits_0)) << 56;
37833           }
37834         }
37835         v_magic = t_0;
37836       }
37837       if (v_magic != 727905341920923785) {
37838         status = wuffs_base__make_status(wuffs_png__error__bad_header);
37839         goto exit;
37840       }
37841       {
37842         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37843         uint64_t t_1;
37844         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
37845           t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
37846           iop_a_src += 8;
37847         } else {
37848           self->private_data.s_decode_image_config[0].scratch = 0;
37849           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
37850           while (true) {
37851             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37852               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37853               goto suspend;
37854             }
37855             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37856             uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
37857             *scratch <<= 8;
37858             *scratch >>= 8;
37859             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
37860             if (num_bits_1 == 56) {
37861               t_1 = ((uint64_t)(*scratch));
37862               break;
37863             }
37864             num_bits_1 += 8;
37865             *scratch |= ((uint64_t)(num_bits_1)) << 56;
37866           }
37867         }
37868         v_magic = t_1;
37869       }
37870       if (v_magic != 5927942488114331648) {
37871         status = wuffs_base__make_status(wuffs_png__error__bad_header);
37872         goto exit;
37873       }
37874       self->private_impl.f_chunk_type_array[0] = 73;
37875       self->private_impl.f_chunk_type_array[1] = 72;
37876       self->private_impl.f_chunk_type_array[2] = 68;
37877       self->private_impl.f_chunk_type_array[3] = 82;
37878       wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
37879           sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
37880       wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
37881       while (true) {
37882         v_mark = ((uint64_t)(iop_a_src - io0_a_src));
37883         {
37884           if (a_src) {
37885             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37886           }
37887           wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src);
37888           v_status = t_2;
37889           if (a_src) {
37890             iop_a_src = a_src->data.ptr + a_src->meta.ri;
37891           }
37892         }
37893         if ( ! self->private_impl.f_ignore_checksum) {
37894           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));
37895         }
37896         if (wuffs_base__status__is_ok(&v_status)) {
37897           goto label__0__break;
37898         }
37899         status = v_status;
37900         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
37901       }
37902       label__0__break:;
37903       {
37904         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
37905         uint32_t t_3;
37906         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
37907           t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37908           iop_a_src += 4;
37909         } else {
37910           self->private_data.s_decode_image_config[0].scratch = 0;
37911           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
37912           while (true) {
37913             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37914               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37915               goto suspend;
37916             }
37917             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37918             uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
37919             *scratch >>= 8;
37920             *scratch <<= 8;
37921             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
37922             if (num_bits_3 == 24) {
37923               t_3 = ((uint32_t)(*scratch >> 32));
37924               break;
37925             }
37926             num_bits_3 += 8;
37927             *scratch |= ((uint64_t)(num_bits_3));
37928           }
37929         }
37930         v_checksum_want = t_3;
37931       }
37932       if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) {
37933         status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
37934         goto exit;
37935       }
37936     }
37937     while (true) {
37938       while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
37939         if (a_src && a_src->meta.closed) {
37940           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37941           goto exit;
37942         }
37943         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37944         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
37945       }
37946       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37947       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
37948       if (self->private_impl.f_chunk_type == 1413563465) {
37949         if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) {
37950           goto label__1__break;
37951         }
37952         self->private_impl.f_seen_idat = true;
37953       } else if (self->private_impl.f_chunk_type == 1413571686) {
37954         if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) {
37955           goto label__1__break;
37956         }
37957         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37958         goto exit;
37959       }
37960       iop_a_src += 8;
37961       if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0)) {
37962         self->private_impl.f_chunk_type_array[0] = ((uint8_t)(((self->private_impl.f_chunk_type >> 0) & 255)));
37963         self->private_impl.f_chunk_type_array[1] = ((uint8_t)(((self->private_impl.f_chunk_type >> 8) & 255)));
37964         self->private_impl.f_chunk_type_array[2] = ((uint8_t)(((self->private_impl.f_chunk_type >> 16) & 255)));
37965         self->private_impl.f_chunk_type_array[3] = ((uint8_t)(((self->private_impl.f_chunk_type >> 24) & 255)));
37966         wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
37967             sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
37968         wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
37969       }
37970       while (true) {
37971         v_mark = ((uint64_t)(iop_a_src - io0_a_src));
37972         {
37973           if (a_src) {
37974             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37975           }
37976           wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src);
37977           v_status = t_4;
37978           if (a_src) {
37979             iop_a_src = a_src->data.ptr + a_src->meta.ri;
37980           }
37981         }
37982         if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0)) {
37983           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));
37984         }
37985         if (wuffs_base__status__is_ok(&v_status)) {
37986           goto label__2__break;
37987         }
37988         status = v_status;
37989         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
37990       }
37991       label__2__break:;
37992       if (self->private_impl.f_metadata_fourcc != 0) {
37993         self->private_impl.f_call_sequence = 1;
37994         status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
37995         goto ok;
37996       }
37997       {
37998         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
37999         uint32_t t_5;
38000         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38001           t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38002           iop_a_src += 4;
38003         } else {
38004           self->private_data.s_decode_image_config[0].scratch = 0;
38005           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
38006           while (true) {
38007             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38008               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38009               goto suspend;
38010             }
38011             uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
38012             uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
38013             *scratch >>= 8;
38014             *scratch <<= 8;
38015             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
38016             if (num_bits_5 == 24) {
38017               t_5 = ((uint32_t)(*scratch >> 32));
38018               break;
38019             }
38020             num_bits_5 += 8;
38021             *scratch |= ((uint64_t)(num_bits_5));
38022           }
38023         }
38024         v_checksum_want = t_5;
38025       }
38026       if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0) && (v_checksum_have != v_checksum_want)) {
38027         status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
38028         goto exit;
38029       }
38030     }
38031     label__1__break:;
38032     if ((self->private_impl.f_color_type == 3) &&  ! self->private_impl.f_seen_plte) {
38033       status = wuffs_base__make_status(wuffs_png__error__missing_palette);
38034       goto exit;
38035     }
38036     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)));
38037     self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position;
38038     if (a_dst != NULL) {
38039       wuffs_base__image_config__set(
38040           a_dst,
38041           self->private_impl.f_dst_pixfmt,
38042           0,
38043           self->private_impl.f_width,
38044           self->private_impl.f_height,
38045           self->private_impl.f_first_config_io_position,
38046           ((self->private_impl.f_color_type <= 3) &&  ! self->private_impl.f_seen_trns));
38047     }
38048     if ( ! self->private_impl.f_seen_actl) {
38049       self->private_impl.f_num_animation_frames_value = 1;
38050       self->private_impl.f_first_rect_x0 = 0;
38051       self->private_impl.f_first_rect_y0 = 0;
38052       self->private_impl.f_first_rect_x1 = self->private_impl.f_width;
38053       self->private_impl.f_first_rect_y1 = self->private_impl.f_height;
38054       self->private_impl.f_first_duration = 0;
38055       self->private_impl.f_first_disposal = 0;
38056       self->private_impl.f_first_overwrite_instead_of_blend = false;
38057     }
38058     self->private_impl.f_call_sequence = 3;
38059 
38060     ok:
38061     self->private_impl.p_decode_image_config[0] = 0;
38062     goto exit;
38063   }
38064 
38065   goto suspend;
38066   suspend:
38067   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38068   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
38069   self->private_data.s_decode_image_config[0].v_checksum_have = v_checksum_have;
38070 
38071   goto exit;
38072   exit:
38073   if (a_src) {
38074     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38075   }
38076 
38077   if (wuffs_base__status__is_error(&status)) {
38078     self->private_impl.magic = WUFFS_BASE__DISABLED;
38079   }
38080   return status;
38081 }
38082 
38083 // -------- func png.decoder.decode_ihdr
38084 
38085 static wuffs_base__status
wuffs_png__decoder__decode_ihdr(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38086 wuffs_png__decoder__decode_ihdr(
38087     wuffs_png__decoder* self,
38088     wuffs_base__io_buffer* a_src) {
38089   wuffs_base__status status = wuffs_base__make_status(NULL);
38090 
38091   uint32_t v_a32 = 0;
38092   uint8_t v_a8 = 0;
38093 
38094   const uint8_t* iop_a_src = NULL;
38095   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38096   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38097   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38098   if (a_src) {
38099     io0_a_src = a_src->data.ptr;
38100     io1_a_src = io0_a_src + a_src->meta.ri;
38101     iop_a_src = io1_a_src;
38102     io2_a_src = io0_a_src + a_src->meta.wi;
38103   }
38104 
38105   uint32_t coro_susp_point = self->private_impl.p_decode_ihdr[0];
38106   switch (coro_susp_point) {
38107     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38108 
38109     {
38110       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38111       uint32_t t_0;
38112       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38113         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38114         iop_a_src += 4;
38115       } else {
38116         self->private_data.s_decode_ihdr[0].scratch = 0;
38117         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38118         while (true) {
38119           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38120             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38121             goto suspend;
38122           }
38123           uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
38124           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38125           *scratch >>= 8;
38126           *scratch <<= 8;
38127           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38128           if (num_bits_0 == 24) {
38129             t_0 = ((uint32_t)(*scratch >> 32));
38130             break;
38131           }
38132           num_bits_0 += 8;
38133           *scratch |= ((uint64_t)(num_bits_0));
38134         }
38135       }
38136       v_a32 = t_0;
38137     }
38138     if ((v_a32 == 0) || (v_a32 >= 2147483648)) {
38139       status = wuffs_base__make_status(wuffs_png__error__bad_header);
38140       goto exit;
38141     } else if (v_a32 >= 16777216) {
38142       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38143       goto exit;
38144     }
38145     self->private_impl.f_width = v_a32;
38146     {
38147       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38148       uint32_t t_1;
38149       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38150         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38151         iop_a_src += 4;
38152       } else {
38153         self->private_data.s_decode_ihdr[0].scratch = 0;
38154         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38155         while (true) {
38156           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38157             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38158             goto suspend;
38159           }
38160           uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
38161           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38162           *scratch >>= 8;
38163           *scratch <<= 8;
38164           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38165           if (num_bits_1 == 24) {
38166             t_1 = ((uint32_t)(*scratch >> 32));
38167             break;
38168           }
38169           num_bits_1 += 8;
38170           *scratch |= ((uint64_t)(num_bits_1));
38171         }
38172       }
38173       v_a32 = t_1;
38174     }
38175     if ((v_a32 == 0) || (v_a32 >= 2147483648)) {
38176       status = wuffs_base__make_status(wuffs_png__error__bad_header);
38177       goto exit;
38178     } else if (v_a32 >= 16777216) {
38179       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38180       goto exit;
38181     }
38182     self->private_impl.f_height = v_a32;
38183     {
38184       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38185       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38186         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38187         goto suspend;
38188       }
38189       uint8_t t_2 = *iop_a_src++;
38190       v_a8 = t_2;
38191     }
38192     if (v_a8 > 16) {
38193       status = wuffs_base__make_status(wuffs_png__error__bad_header);
38194       goto exit;
38195     }
38196     self->private_impl.f_depth = v_a8;
38197     {
38198       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38199       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38200         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38201         goto suspend;
38202       }
38203       uint8_t t_3 = *iop_a_src++;
38204       v_a8 = t_3;
38205     }
38206     if ((v_a8 == 1) || (v_a8 == 5) || (v_a8 > 6)) {
38207       status = wuffs_base__make_status(wuffs_png__error__bad_header);
38208       goto exit;
38209     }
38210     self->private_impl.f_color_type = v_a8;
38211     {
38212       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38213       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38214         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38215         goto suspend;
38216       }
38217       uint8_t t_4 = *iop_a_src++;
38218       v_a8 = t_4;
38219     }
38220     if (v_a8 != 0) {
38221       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
38222       goto exit;
38223     }
38224     {
38225       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38226       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38227         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38228         goto suspend;
38229       }
38230       uint8_t t_5 = *iop_a_src++;
38231       v_a8 = t_5;
38232     }
38233     if (v_a8 != 0) {
38234       status = wuffs_base__make_status(wuffs_png__error__bad_header);
38235       goto exit;
38236     }
38237     {
38238       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38239       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38240         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38241         goto suspend;
38242       }
38243       uint8_t t_6 = *iop_a_src++;
38244       v_a8 = t_6;
38245     }
38246     if (v_a8 == 0) {
38247       self->private_impl.f_interlace_pass = 0;
38248     } else if (v_a8 == 1) {
38249       self->private_impl.f_interlace_pass = 1;
38250       self->private_impl.choosy_filter_and_swizzle = (
38251           &wuffs_png__decoder__filter_and_swizzle_tricky);
38252     } else {
38253       status = wuffs_base__make_status(wuffs_png__error__bad_header);
38254       goto exit;
38255     }
38256     self->private_impl.f_filter_distance = 0;
38257     wuffs_png__decoder__assign_filter_distance(self);
38258     if (self->private_impl.f_filter_distance == 0) {
38259       status = wuffs_base__make_status(wuffs_png__error__bad_header);
38260       goto exit;
38261     }
38262     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)));
38263     wuffs_png__decoder__choose_filter_implementations(self);
38264 
38265     goto ok;
38266     ok:
38267     self->private_impl.p_decode_ihdr[0] = 0;
38268     goto exit;
38269   }
38270 
38271   goto suspend;
38272   suspend:
38273   self->private_impl.p_decode_ihdr[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38274 
38275   goto exit;
38276   exit:
38277   if (a_src) {
38278     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38279   }
38280 
38281   return status;
38282 }
38283 
38284 // -------- func png.decoder.assign_filter_distance
38285 
38286 static wuffs_base__empty_struct
wuffs_png__decoder__assign_filter_distance(wuffs_png__decoder * self)38287 wuffs_png__decoder__assign_filter_distance(
38288     wuffs_png__decoder* self) {
38289   if (self->private_impl.f_depth < 8) {
38290     if ((self->private_impl.f_depth != 1) && (self->private_impl.f_depth != 2) && (self->private_impl.f_depth != 4)) {
38291       return wuffs_base__make_empty_struct();
38292     } else if (self->private_impl.f_color_type == 0) {
38293       self->private_impl.f_dst_pixfmt = 536870920;
38294       self->private_impl.f_src_pixfmt = 536870920;
38295     } else if (self->private_impl.f_color_type == 3) {
38296       self->private_impl.f_dst_pixfmt = 2198077448;
38297       self->private_impl.f_src_pixfmt = 2198077448;
38298     } else {
38299       return wuffs_base__make_empty_struct();
38300     }
38301     self->private_impl.f_filter_distance = 1;
38302     self->private_impl.choosy_filter_and_swizzle = (
38303         &wuffs_png__decoder__filter_and_swizzle_tricky);
38304   } else if (self->private_impl.f_color_type == 0) {
38305     if (self->private_impl.f_depth == 8) {
38306       self->private_impl.f_dst_pixfmt = 536870920;
38307       self->private_impl.f_src_pixfmt = 536870920;
38308       self->private_impl.f_filter_distance = 1;
38309     } else if (self->private_impl.f_depth == 16) {
38310       if (self->private_impl.f_interlace_pass == 0) {
38311         self->private_impl.f_dst_pixfmt = 536870923;
38312         self->private_impl.f_src_pixfmt = 537919499;
38313       } else {
38314         self->private_impl.f_dst_pixfmt = 2164308923;
38315         self->private_impl.f_src_pixfmt = 2164308923;
38316       }
38317       self->private_impl.f_filter_distance = 2;
38318     }
38319   } else if (self->private_impl.f_color_type == 2) {
38320     if (self->private_impl.f_depth == 8) {
38321       self->private_impl.f_dst_pixfmt = 2147485832;
38322       self->private_impl.f_src_pixfmt = 2684356744;
38323       self->private_impl.f_filter_distance = 3;
38324     } else if (self->private_impl.f_depth == 16) {
38325       self->private_impl.f_dst_pixfmt = 2164308923;
38326       self->private_impl.f_src_pixfmt = 2164308923;
38327       self->private_impl.f_filter_distance = 6;
38328       self->private_impl.choosy_filter_and_swizzle = (
38329           &wuffs_png__decoder__filter_and_swizzle_tricky);
38330     }
38331   } else if (self->private_impl.f_color_type == 3) {
38332     if (self->private_impl.f_depth == 8) {
38333       self->private_impl.f_dst_pixfmt = 2198077448;
38334       self->private_impl.f_src_pixfmt = 2198077448;
38335       self->private_impl.f_filter_distance = 1;
38336     }
38337   } else if (self->private_impl.f_color_type == 4) {
38338     if (self->private_impl.f_depth == 8) {
38339       self->private_impl.f_dst_pixfmt = 2164295816;
38340       self->private_impl.f_src_pixfmt = 2164295816;
38341       self->private_impl.f_filter_distance = 2;
38342       self->private_impl.choosy_filter_and_swizzle = (
38343           &wuffs_png__decoder__filter_and_swizzle_tricky);
38344     } else if (self->private_impl.f_depth == 16) {
38345       self->private_impl.f_dst_pixfmt = 2164308923;
38346       self->private_impl.f_src_pixfmt = 2164308923;
38347       self->private_impl.f_filter_distance = 4;
38348       self->private_impl.choosy_filter_and_swizzle = (
38349           &wuffs_png__decoder__filter_and_swizzle_tricky);
38350     }
38351   } else if (self->private_impl.f_color_type == 6) {
38352     if (self->private_impl.f_depth == 8) {
38353       self->private_impl.f_dst_pixfmt = 2164295816;
38354       self->private_impl.f_src_pixfmt = 2701166728;
38355       self->private_impl.f_filter_distance = 4;
38356     } else if (self->private_impl.f_depth == 16) {
38357       self->private_impl.f_dst_pixfmt = 2164308923;
38358       self->private_impl.f_src_pixfmt = 2164308923;
38359       self->private_impl.f_filter_distance = 8;
38360       self->private_impl.choosy_filter_and_swizzle = (
38361           &wuffs_png__decoder__filter_and_swizzle_tricky);
38362     }
38363   }
38364   return wuffs_base__make_empty_struct();
38365 }
38366 
38367 // -------- func png.decoder.calculate_bytes_per_row
38368 
38369 static uint64_t
wuffs_png__decoder__calculate_bytes_per_row(const wuffs_png__decoder * self,uint32_t a_width)38370 wuffs_png__decoder__calculate_bytes_per_row(
38371     const wuffs_png__decoder* self,
38372     uint32_t a_width) {
38373   uint64_t v_bytes_per_channel = 0;
38374 
38375   if (self->private_impl.f_depth == 1) {
38376     return ((uint64_t)(((a_width + 7) / 8)));
38377   } else if (self->private_impl.f_depth == 2) {
38378     return ((uint64_t)(((a_width + 3) / 4)));
38379   } else if (self->private_impl.f_depth == 4) {
38380     return ((uint64_t)(((a_width + 1) / 2)));
38381   }
38382   v_bytes_per_channel = ((uint64_t)((self->private_impl.f_depth >> 3)));
38383   return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])));
38384 }
38385 
38386 // -------- func png.decoder.choose_filter_implementations
38387 
38388 static wuffs_base__empty_struct
wuffs_png__decoder__choose_filter_implementations(wuffs_png__decoder * self)38389 wuffs_png__decoder__choose_filter_implementations(
38390     wuffs_png__decoder* self) {
38391   if (self->private_impl.f_filter_distance == 3) {
38392     self->private_impl.choosy_filter_1 = (
38393         &wuffs_png__decoder__filter_1_distance_3_fallback);
38394     self->private_impl.choosy_filter_3 = (
38395         &wuffs_png__decoder__filter_3_distance_3_fallback);
38396     self->private_impl.choosy_filter_4 = (
38397 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38398         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon :
38399 #endif
38400 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38401         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 :
38402 #endif
38403         &wuffs_png__decoder__filter_4_distance_3_fallback);
38404   } else if (self->private_impl.f_filter_distance == 4) {
38405     self->private_impl.choosy_filter_1 = (
38406 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38407         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon :
38408 #endif
38409 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38410         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 :
38411 #endif
38412         &wuffs_png__decoder__filter_1_distance_4_fallback);
38413     self->private_impl.choosy_filter_3 = (
38414 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38415         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon :
38416 #endif
38417 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38418         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 :
38419 #endif
38420         &wuffs_png__decoder__filter_3_distance_4_fallback);
38421     self->private_impl.choosy_filter_4 = (
38422 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38423         wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon :
38424 #endif
38425 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38426         wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 :
38427 #endif
38428         &wuffs_png__decoder__filter_4_distance_4_fallback);
38429   }
38430   return wuffs_base__make_empty_struct();
38431 }
38432 
38433 // -------- func png.decoder.decode_other_chunk
38434 
38435 static wuffs_base__status
wuffs_png__decoder__decode_other_chunk(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38436 wuffs_png__decoder__decode_other_chunk(
38437     wuffs_png__decoder* self,
38438     wuffs_base__io_buffer* a_src) {
38439   wuffs_base__status status = wuffs_base__make_status(NULL);
38440 
38441   const uint8_t* iop_a_src = NULL;
38442   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38443   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38444   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38445   if (a_src) {
38446     io0_a_src = a_src->data.ptr;
38447     io1_a_src = io0_a_src + a_src->meta.ri;
38448     iop_a_src = io1_a_src;
38449     io2_a_src = io0_a_src + a_src->meta.wi;
38450   }
38451 
38452   uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk[0];
38453   switch (coro_susp_point) {
38454     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38455 
38456     if (self->private_impl.f_chunk_type == 1163152464) {
38457       if (self->private_impl.f_seen_plte) {
38458         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38459         goto exit;
38460       } else if (self->private_impl.f_color_type == 3) {
38461         if (a_src) {
38462           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38463         }
38464         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38465         status = wuffs_png__decoder__decode_plte(self, a_src);
38466         if (a_src) {
38467           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38468         }
38469         if (status.repr) {
38470           goto suspend;
38471         }
38472       } else if ((self->private_impl.f_color_type == 2) || (self->private_impl.f_color_type == 6)) {
38473       } else {
38474         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38475         goto exit;
38476       }
38477       self->private_impl.f_seen_plte = true;
38478     } else if ((self->private_impl.f_chunk_type & 32) == 0) {
38479       if (self->private_impl.f_chunk_type != 1413563465) {
38480         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38481         goto exit;
38482       }
38483     } else if (self->private_impl.f_chunk_type == 1280598881) {
38484       if (self->private_impl.f_seen_actl) {
38485         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38486         goto exit;
38487       }
38488       if (a_src) {
38489         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38490       }
38491       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38492       status = wuffs_png__decoder__decode_actl(self, a_src);
38493       if (a_src) {
38494         iop_a_src = a_src->data.ptr + a_src->meta.ri;
38495       }
38496       if (status.repr) {
38497         goto suspend;
38498       }
38499       self->private_impl.f_seen_actl = true;
38500     } else if (self->private_impl.f_chunk_type == 1297238115) {
38501       if (self->private_impl.f_report_metadata_chrm) {
38502         if (self->private_impl.f_seen_chrm) {
38503           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38504           goto exit;
38505         }
38506         if (a_src) {
38507           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38508         }
38509         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38510         status = wuffs_png__decoder__decode_chrm(self, a_src);
38511         if (a_src) {
38512           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38513         }
38514         if (status.repr) {
38515           goto suspend;
38516         }
38517         self->private_impl.f_seen_chrm = true;
38518       }
38519     } else if (self->private_impl.f_chunk_type == 1716082789) {
38520       if (self->private_impl.f_report_metadata_exif) {
38521         if (self->private_impl.f_seen_exif) {
38522           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38523           goto exit;
38524         }
38525         if (a_src) {
38526           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38527         }
38528         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38529         status = wuffs_png__decoder__decode_exif(self, a_src);
38530         if (a_src) {
38531           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38532         }
38533         if (status.repr) {
38534           goto suspend;
38535         }
38536         self->private_impl.f_seen_exif = true;
38537       }
38538     } else if (self->private_impl.f_chunk_type == 1280598886) {
38539       if (self->private_impl.f_seen_fctl) {
38540         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38541         goto exit;
38542       }
38543       if (a_src) {
38544         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38545       }
38546       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38547       status = wuffs_png__decoder__decode_fctl(self, a_src);
38548       if (a_src) {
38549         iop_a_src = a_src->data.ptr + a_src->meta.ri;
38550       }
38551       if (status.repr) {
38552         goto suspend;
38553       }
38554       self->private_impl.f_seen_fctl = true;
38555     } else if (self->private_impl.f_chunk_type == 1095582055) {
38556       if (self->private_impl.f_report_metadata_gama) {
38557         if (self->private_impl.f_seen_gama) {
38558           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38559           goto exit;
38560         }
38561         if (a_src) {
38562           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38563         }
38564         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38565         status = wuffs_png__decoder__decode_gama(self, a_src);
38566         if (a_src) {
38567           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38568         }
38569         if (status.repr) {
38570           goto suspend;
38571         }
38572         self->private_impl.f_seen_gama = true;
38573       }
38574     } else if (self->private_impl.f_chunk_type == 1346585449) {
38575       if (self->private_impl.f_report_metadata_iccp) {
38576         if (self->private_impl.f_seen_iccp) {
38577           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38578           goto exit;
38579         }
38580         if (a_src) {
38581           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38582         }
38583         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38584         status = wuffs_png__decoder__decode_iccp(self, a_src);
38585         if (a_src) {
38586           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38587         }
38588         if (status.repr) {
38589           goto suspend;
38590         }
38591         self->private_impl.f_seen_iccp = true;
38592       }
38593     } else if (self->private_impl.f_chunk_type == 1111970419) {
38594       if (self->private_impl.f_report_metadata_srgb) {
38595         if (self->private_impl.f_seen_srgb) {
38596           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38597           goto exit;
38598         }
38599         if (a_src) {
38600           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38601         }
38602         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38603         status = wuffs_png__decoder__decode_srgb(self, a_src);
38604         if (a_src) {
38605           iop_a_src = a_src->data.ptr + a_src->meta.ri;
38606         }
38607         if (status.repr) {
38608           goto suspend;
38609         }
38610         self->private_impl.f_seen_srgb = true;
38611       }
38612     } else if (self->private_impl.f_chunk_type == 1397641844) {
38613       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)) {
38614         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38615         goto exit;
38616       }
38617       if (a_src) {
38618         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38619       }
38620       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38621       status = wuffs_png__decoder__decode_trns(self, a_src);
38622       if (a_src) {
38623         iop_a_src = a_src->data.ptr + a_src->meta.ri;
38624       }
38625       if (status.repr) {
38626         goto suspend;
38627       }
38628       self->private_impl.f_seen_trns = true;
38629     } else if ((self->private_impl.f_chunk_type == 1951945833) || (self->private_impl.f_chunk_type == 1951942004) || (self->private_impl.f_chunk_type == 1951945850)) {
38630       if (self->private_impl.f_report_metadata_kvp) {
38631         self->private_impl.f_metadata_flavor = 4;
38632         self->private_impl.f_metadata_fourcc = 1263947851;
38633         self->private_impl.f_metadata_x = 0;
38634         self->private_impl.f_metadata_y = 0;
38635         self->private_impl.f_metadata_z = 0;
38636       }
38637     }
38638     if (self->private_impl.f_metadata_fourcc == 0) {
38639       self->private_data.s_decode_other_chunk[0].scratch = self->private_impl.f_chunk_length;
38640       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
38641       if (self->private_data.s_decode_other_chunk[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
38642         self->private_data.s_decode_other_chunk[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
38643         iop_a_src = io2_a_src;
38644         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38645         goto suspend;
38646       }
38647       iop_a_src += self->private_data.s_decode_other_chunk[0].scratch;
38648     }
38649 
38650     goto ok;
38651     ok:
38652     self->private_impl.p_decode_other_chunk[0] = 0;
38653     goto exit;
38654   }
38655 
38656   goto suspend;
38657   suspend:
38658   self->private_impl.p_decode_other_chunk[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38659 
38660   goto exit;
38661   exit:
38662   if (a_src) {
38663     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38664   }
38665 
38666   return status;
38667 }
38668 
38669 // -------- func png.decoder.decode_actl
38670 
38671 static wuffs_base__status
wuffs_png__decoder__decode_actl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38672 wuffs_png__decoder__decode_actl(
38673     wuffs_png__decoder* self,
38674     wuffs_base__io_buffer* a_src) {
38675   wuffs_base__status status = wuffs_base__make_status(NULL);
38676 
38677   const uint8_t* iop_a_src = NULL;
38678   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38679   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38680   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38681   if (a_src) {
38682     io0_a_src = a_src->data.ptr;
38683     io1_a_src = io0_a_src + a_src->meta.ri;
38684     iop_a_src = io1_a_src;
38685     io2_a_src = io0_a_src + a_src->meta.wi;
38686   }
38687 
38688   uint32_t coro_susp_point = self->private_impl.p_decode_actl[0];
38689   switch (coro_susp_point) {
38690     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38691 
38692     if (self->private_impl.f_chunk_length != 8) {
38693       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38694       goto exit;
38695     } else if (self->private_impl.f_interlace_pass > 0) {
38696       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38697       goto exit;
38698     }
38699     self->private_impl.f_chunk_length = 0;
38700     {
38701       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38702       uint32_t t_0;
38703       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38704         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38705         iop_a_src += 4;
38706       } else {
38707         self->private_data.s_decode_actl[0].scratch = 0;
38708         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38709         while (true) {
38710           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38711             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38712             goto suspend;
38713           }
38714           uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
38715           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38716           *scratch >>= 8;
38717           *scratch <<= 8;
38718           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38719           if (num_bits_0 == 24) {
38720             t_0 = ((uint32_t)(*scratch >> 32));
38721             break;
38722           }
38723           num_bits_0 += 8;
38724           *scratch |= ((uint64_t)(num_bits_0));
38725         }
38726       }
38727       self->private_impl.f_num_animation_frames_value = t_0;
38728     }
38729     if (self->private_impl.f_num_animation_frames_value == 0) {
38730       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38731       goto exit;
38732     }
38733     {
38734       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38735       uint32_t t_1;
38736       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38737         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38738         iop_a_src += 4;
38739       } else {
38740         self->private_data.s_decode_actl[0].scratch = 0;
38741         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38742         while (true) {
38743           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38744             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38745             goto suspend;
38746           }
38747           uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
38748           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38749           *scratch >>= 8;
38750           *scratch <<= 8;
38751           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38752           if (num_bits_1 == 24) {
38753             t_1 = ((uint32_t)(*scratch >> 32));
38754             break;
38755           }
38756           num_bits_1 += 8;
38757           *scratch |= ((uint64_t)(num_bits_1));
38758         }
38759       }
38760       self->private_impl.f_num_animation_loops_value = t_1;
38761     }
38762 
38763     goto ok;
38764     ok:
38765     self->private_impl.p_decode_actl[0] = 0;
38766     goto exit;
38767   }
38768 
38769   goto suspend;
38770   suspend:
38771   self->private_impl.p_decode_actl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38772 
38773   goto exit;
38774   exit:
38775   if (a_src) {
38776     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38777   }
38778 
38779   return status;
38780 }
38781 
38782 // -------- func png.decoder.decode_chrm
38783 
38784 static wuffs_base__status
wuffs_png__decoder__decode_chrm(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38785 wuffs_png__decoder__decode_chrm(
38786     wuffs_png__decoder* self,
38787     wuffs_base__io_buffer* a_src) {
38788   wuffs_base__status status = wuffs_base__make_status(NULL);
38789 
38790   uint64_t v_u = 0;
38791 
38792   const uint8_t* iop_a_src = NULL;
38793   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38794   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38795   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38796   if (a_src) {
38797     io0_a_src = a_src->data.ptr;
38798     io1_a_src = io0_a_src + a_src->meta.ri;
38799     iop_a_src = io1_a_src;
38800     io2_a_src = io0_a_src + a_src->meta.wi;
38801   }
38802 
38803   uint32_t coro_susp_point = self->private_impl.p_decode_chrm[0];
38804   switch (coro_susp_point) {
38805     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38806 
38807     if (self->private_impl.f_chunk_length != 32) {
38808       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38809       goto exit;
38810     }
38811     self->private_impl.f_chunk_length = 0;
38812     self->private_impl.f_metadata_flavor = 5;
38813     self->private_impl.f_metadata_fourcc = 1128813133;
38814     self->private_impl.f_metadata_x = 0;
38815     self->private_impl.f_metadata_y = 0;
38816     self->private_impl.f_metadata_z = 0;
38817     {
38818       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38819       uint64_t t_0;
38820       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38821         t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38822         iop_a_src += 4;
38823       } else {
38824         self->private_data.s_decode_chrm[0].scratch = 0;
38825         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38826         while (true) {
38827           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38828             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38829             goto suspend;
38830           }
38831           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38832           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38833           *scratch >>= 8;
38834           *scratch <<= 8;
38835           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38836           if (num_bits_0 == 24) {
38837             t_0 = ((uint64_t)(*scratch >> 32));
38838             break;
38839           }
38840           num_bits_0 += 8;
38841           *scratch |= ((uint64_t)(num_bits_0));
38842         }
38843       }
38844       v_u = t_0;
38845     }
38846     self->private_impl.f_metadata_x |= ((16777215 & v_u) << 0);
38847     {
38848       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38849       uint64_t t_1;
38850       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38851         t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38852         iop_a_src += 4;
38853       } else {
38854         self->private_data.s_decode_chrm[0].scratch = 0;
38855         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38856         while (true) {
38857           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38858             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38859             goto suspend;
38860           }
38861           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38862           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38863           *scratch >>= 8;
38864           *scratch <<= 8;
38865           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38866           if (num_bits_1 == 24) {
38867             t_1 = ((uint64_t)(*scratch >> 32));
38868             break;
38869           }
38870           num_bits_1 += 8;
38871           *scratch |= ((uint64_t)(num_bits_1));
38872         }
38873       }
38874       v_u = t_1;
38875     }
38876     self->private_impl.f_metadata_x |= ((16777215 & v_u) << 24);
38877     {
38878       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38879       uint64_t t_2;
38880       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38881         t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38882         iop_a_src += 4;
38883       } else {
38884         self->private_data.s_decode_chrm[0].scratch = 0;
38885         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38886         while (true) {
38887           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38888             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38889             goto suspend;
38890           }
38891           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38892           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
38893           *scratch >>= 8;
38894           *scratch <<= 8;
38895           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
38896           if (num_bits_2 == 24) {
38897             t_2 = ((uint64_t)(*scratch >> 32));
38898             break;
38899           }
38900           num_bits_2 += 8;
38901           *scratch |= ((uint64_t)(num_bits_2));
38902         }
38903       }
38904       v_u = t_2;
38905     }
38906     self->private_impl.f_metadata_x |= ((uint64_t)((16777215 & v_u) << 48));
38907     self->private_impl.f_metadata_y |= ((16777215 & v_u) >> 16);
38908     {
38909       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38910       uint64_t t_3;
38911       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38912         t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38913         iop_a_src += 4;
38914       } else {
38915         self->private_data.s_decode_chrm[0].scratch = 0;
38916         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38917         while (true) {
38918           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38919             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38920             goto suspend;
38921           }
38922           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38923           uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
38924           *scratch >>= 8;
38925           *scratch <<= 8;
38926           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
38927           if (num_bits_3 == 24) {
38928             t_3 = ((uint64_t)(*scratch >> 32));
38929             break;
38930           }
38931           num_bits_3 += 8;
38932           *scratch |= ((uint64_t)(num_bits_3));
38933         }
38934       }
38935       v_u = t_3;
38936     }
38937     self->private_impl.f_metadata_y |= ((16777215 & v_u) << 8);
38938     {
38939       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38940       uint64_t t_4;
38941       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38942         t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38943         iop_a_src += 4;
38944       } else {
38945         self->private_data.s_decode_chrm[0].scratch = 0;
38946         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
38947         while (true) {
38948           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38949             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38950             goto suspend;
38951           }
38952           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38953           uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
38954           *scratch >>= 8;
38955           *scratch <<= 8;
38956           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
38957           if (num_bits_4 == 24) {
38958             t_4 = ((uint64_t)(*scratch >> 32));
38959             break;
38960           }
38961           num_bits_4 += 8;
38962           *scratch |= ((uint64_t)(num_bits_4));
38963         }
38964       }
38965       v_u = t_4;
38966     }
38967     self->private_impl.f_metadata_y |= ((16777215 & v_u) << 32);
38968     {
38969       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
38970       uint64_t t_5;
38971       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38972         t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38973         iop_a_src += 4;
38974       } else {
38975         self->private_data.s_decode_chrm[0].scratch = 0;
38976         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
38977         while (true) {
38978           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38979             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38980             goto suspend;
38981           }
38982           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38983           uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
38984           *scratch >>= 8;
38985           *scratch <<= 8;
38986           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
38987           if (num_bits_5 == 24) {
38988             t_5 = ((uint64_t)(*scratch >> 32));
38989             break;
38990           }
38991           num_bits_5 += 8;
38992           *scratch |= ((uint64_t)(num_bits_5));
38993         }
38994       }
38995       v_u = t_5;
38996     }
38997     self->private_impl.f_metadata_y |= ((uint64_t)((16777215 & v_u) << 56));
38998     self->private_impl.f_metadata_z |= ((16777215 & v_u) >> 8);
38999     {
39000       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
39001       uint64_t t_6;
39002       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39003         t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
39004         iop_a_src += 4;
39005       } else {
39006         self->private_data.s_decode_chrm[0].scratch = 0;
39007         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
39008         while (true) {
39009           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39010             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39011             goto suspend;
39012           }
39013           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
39014           uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFF));
39015           *scratch >>= 8;
39016           *scratch <<= 8;
39017           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
39018           if (num_bits_6 == 24) {
39019             t_6 = ((uint64_t)(*scratch >> 32));
39020             break;
39021           }
39022           num_bits_6 += 8;
39023           *scratch |= ((uint64_t)(num_bits_6));
39024         }
39025       }
39026       v_u = t_6;
39027     }
39028     self->private_impl.f_metadata_z |= ((16777215 & v_u) << 16);
39029     {
39030       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
39031       uint64_t t_7;
39032       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39033         t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
39034         iop_a_src += 4;
39035       } else {
39036         self->private_data.s_decode_chrm[0].scratch = 0;
39037         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
39038         while (true) {
39039           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39040             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39041             goto suspend;
39042           }
39043           uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
39044           uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFF));
39045           *scratch >>= 8;
39046           *scratch <<= 8;
39047           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7);
39048           if (num_bits_7 == 24) {
39049             t_7 = ((uint64_t)(*scratch >> 32));
39050             break;
39051           }
39052           num_bits_7 += 8;
39053           *scratch |= ((uint64_t)(num_bits_7));
39054         }
39055       }
39056       v_u = t_7;
39057     }
39058     self->private_impl.f_metadata_z |= ((16777215 & v_u) << 40);
39059 
39060     goto ok;
39061     ok:
39062     self->private_impl.p_decode_chrm[0] = 0;
39063     goto exit;
39064   }
39065 
39066   goto suspend;
39067   suspend:
39068   self->private_impl.p_decode_chrm[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39069 
39070   goto exit;
39071   exit:
39072   if (a_src) {
39073     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39074   }
39075 
39076   return status;
39077 }
39078 
39079 // -------- func png.decoder.decode_exif
39080 
39081 static wuffs_base__status
wuffs_png__decoder__decode_exif(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39082 wuffs_png__decoder__decode_exif(
39083     wuffs_png__decoder* self,
39084     wuffs_base__io_buffer* a_src) {
39085   wuffs_base__status status = wuffs_base__make_status(NULL);
39086 
39087   const uint8_t* iop_a_src = NULL;
39088   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39089   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39090   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39091   if (a_src) {
39092     io0_a_src = a_src->data.ptr;
39093     io1_a_src = io0_a_src + a_src->meta.ri;
39094     iop_a_src = io1_a_src;
39095     io2_a_src = io0_a_src + a_src->meta.wi;
39096   }
39097 
39098   if (self->private_impl.f_chunk_length < 4) {
39099     status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39100     goto exit;
39101   }
39102   self->private_impl.f_metadata_flavor = 3;
39103   self->private_impl.f_metadata_fourcc = 1163413830;
39104   self->private_impl.f_metadata_x = 0;
39105   self->private_impl.f_metadata_y = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
39106   self->private_impl.f_metadata_z = wuffs_base__u64__sat_add(self->private_impl.f_metadata_y, ((uint64_t)(self->private_impl.f_chunk_length)));
39107   self->private_impl.f_chunk_length = 0;
39108 
39109   goto ok;
39110   ok:
39111   goto exit;
39112   exit:
39113   if (a_src) {
39114     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39115   }
39116 
39117   return status;
39118 }
39119 
39120 // -------- func png.decoder.decode_fctl
39121 
39122 static wuffs_base__status
wuffs_png__decoder__decode_fctl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39123 wuffs_png__decoder__decode_fctl(
39124     wuffs_png__decoder* self,
39125     wuffs_base__io_buffer* a_src) {
39126   wuffs_base__status status = wuffs_base__make_status(NULL);
39127 
39128   uint32_t v_x0 = 0;
39129   uint32_t v_y0 = 0;
39130   uint32_t v_x1 = 0;
39131   uint32_t v_y1 = 0;
39132 
39133   const uint8_t* iop_a_src = NULL;
39134   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39135   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39136   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39137   if (a_src) {
39138     io0_a_src = a_src->data.ptr;
39139     io1_a_src = io0_a_src + a_src->meta.ri;
39140     iop_a_src = io1_a_src;
39141     io2_a_src = io0_a_src + a_src->meta.wi;
39142   }
39143 
39144   uint32_t coro_susp_point = self->private_impl.p_decode_fctl[0];
39145   if (coro_susp_point) {
39146     v_x0 = self->private_data.s_decode_fctl[0].v_x0;
39147     v_x1 = self->private_data.s_decode_fctl[0].v_x1;
39148     v_y1 = self->private_data.s_decode_fctl[0].v_y1;
39149   }
39150   switch (coro_susp_point) {
39151     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39152 
39153     if (self->private_impl.f_chunk_length != 26) {
39154       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39155       goto exit;
39156     }
39157     self->private_impl.f_chunk_length = 0;
39158     {
39159       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39160       uint32_t t_0;
39161       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39162         t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39163         iop_a_src += 4;
39164       } else {
39165         self->private_data.s_decode_fctl[0].scratch = 0;
39166         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39167         while (true) {
39168           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39169             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39170             goto suspend;
39171           }
39172           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39173           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39174           *scratch >>= 8;
39175           *scratch <<= 8;
39176           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39177           if (num_bits_0 == 24) {
39178             t_0 = ((uint32_t)(*scratch >> 32));
39179             break;
39180           }
39181           num_bits_0 += 8;
39182           *scratch |= ((uint64_t)(num_bits_0));
39183         }
39184       }
39185       v_x0 = t_0;
39186     }
39187     if (v_x0 != self->private_impl.f_next_animation_seq_num) {
39188       status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
39189       goto exit;
39190     } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
39191       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
39192       goto exit;
39193     }
39194     self->private_impl.f_next_animation_seq_num += 1;
39195     {
39196       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39197       uint32_t t_1;
39198       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39199         t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39200         iop_a_src += 4;
39201       } else {
39202         self->private_data.s_decode_fctl[0].scratch = 0;
39203         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39204         while (true) {
39205           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39206             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39207             goto suspend;
39208           }
39209           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39210           uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
39211           *scratch >>= 8;
39212           *scratch <<= 8;
39213           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
39214           if (num_bits_1 == 24) {
39215             t_1 = ((uint32_t)(*scratch >> 32));
39216             break;
39217           }
39218           num_bits_1 += 8;
39219           *scratch |= ((uint64_t)(num_bits_1));
39220         }
39221       }
39222       v_x1 = t_1;
39223     }
39224     {
39225       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39226       uint32_t t_2;
39227       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39228         t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39229         iop_a_src += 4;
39230       } else {
39231         self->private_data.s_decode_fctl[0].scratch = 0;
39232         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
39233         while (true) {
39234           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39235             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39236             goto suspend;
39237           }
39238           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39239           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
39240           *scratch >>= 8;
39241           *scratch <<= 8;
39242           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
39243           if (num_bits_2 == 24) {
39244             t_2 = ((uint32_t)(*scratch >> 32));
39245             break;
39246           }
39247           num_bits_2 += 8;
39248           *scratch |= ((uint64_t)(num_bits_2));
39249         }
39250       }
39251       v_y1 = t_2;
39252     }
39253     {
39254       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
39255       uint32_t t_3;
39256       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39257         t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39258         iop_a_src += 4;
39259       } else {
39260         self->private_data.s_decode_fctl[0].scratch = 0;
39261         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
39262         while (true) {
39263           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39264             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39265             goto suspend;
39266           }
39267           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39268           uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
39269           *scratch >>= 8;
39270           *scratch <<= 8;
39271           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
39272           if (num_bits_3 == 24) {
39273             t_3 = ((uint32_t)(*scratch >> 32));
39274             break;
39275           }
39276           num_bits_3 += 8;
39277           *scratch |= ((uint64_t)(num_bits_3));
39278         }
39279       }
39280       v_x0 = t_3;
39281     }
39282     {
39283       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
39284       uint32_t t_4;
39285       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39286         t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39287         iop_a_src += 4;
39288       } else {
39289         self->private_data.s_decode_fctl[0].scratch = 0;
39290         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
39291         while (true) {
39292           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39293             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39294             goto suspend;
39295           }
39296           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39297           uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
39298           *scratch >>= 8;
39299           *scratch <<= 8;
39300           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
39301           if (num_bits_4 == 24) {
39302             t_4 = ((uint32_t)(*scratch >> 32));
39303             break;
39304           }
39305           num_bits_4 += 8;
39306           *scratch |= ((uint64_t)(num_bits_4));
39307         }
39308       }
39309       v_y0 = t_4;
39310     }
39311     v_x1 += v_x0;
39312     v_y1 += v_y0;
39313     if ((v_x0 >= v_x1) ||
39314         (v_x0 > self->private_impl.f_width) ||
39315         (v_x1 > self->private_impl.f_width) ||
39316         (v_y0 >= v_y1) ||
39317         (v_y0 > self->private_impl.f_height) ||
39318         (v_y1 > self->private_impl.f_height)) {
39319       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39320       goto exit;
39321     }
39322     self->private_impl.f_frame_rect_x0 = v_x0;
39323     self->private_impl.f_frame_rect_y0 = v_y0;
39324     self->private_impl.f_frame_rect_x1 = v_x1;
39325     self->private_impl.f_frame_rect_y1 = v_y1;
39326     {
39327       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
39328       uint32_t t_5;
39329       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39330         t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
39331         iop_a_src += 2;
39332       } else {
39333         self->private_data.s_decode_fctl[0].scratch = 0;
39334         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
39335         while (true) {
39336           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39337             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39338             goto suspend;
39339           }
39340           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39341           uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
39342           *scratch >>= 8;
39343           *scratch <<= 8;
39344           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
39345           if (num_bits_5 == 8) {
39346             t_5 = ((uint32_t)(*scratch >> 48));
39347             break;
39348           }
39349           num_bits_5 += 8;
39350           *scratch |= ((uint64_t)(num_bits_5));
39351         }
39352       }
39353       v_x0 = t_5;
39354     }
39355     {
39356       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
39357       uint32_t t_6;
39358       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39359         t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
39360         iop_a_src += 2;
39361       } else {
39362         self->private_data.s_decode_fctl[0].scratch = 0;
39363         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
39364         while (true) {
39365           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39366             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39367             goto suspend;
39368           }
39369           uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39370           uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFF));
39371           *scratch >>= 8;
39372           *scratch <<= 8;
39373           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
39374           if (num_bits_6 == 8) {
39375             t_6 = ((uint32_t)(*scratch >> 48));
39376             break;
39377           }
39378           num_bits_6 += 8;
39379           *scratch |= ((uint64_t)(num_bits_6));
39380         }
39381       }
39382       v_x1 = t_6;
39383     }
39384     if (v_x1 <= 0) {
39385       self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000);
39386     } else {
39387       self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000) / ((uint64_t)(v_x1)));
39388     }
39389     {
39390       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
39391       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39392         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39393         goto suspend;
39394       }
39395       uint32_t t_7 = *iop_a_src++;
39396       v_x0 = t_7;
39397     }
39398     if (v_x0 == 0) {
39399       self->private_impl.f_frame_disposal = 0;
39400     } else if (v_x0 == 1) {
39401       self->private_impl.f_frame_disposal = 1;
39402     } else if (v_x0 == 2) {
39403       self->private_impl.f_frame_disposal = 2;
39404     } else {
39405       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39406       goto exit;
39407     }
39408     {
39409       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
39410       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39411         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39412         goto suspend;
39413       }
39414       uint32_t t_8 = *iop_a_src++;
39415       v_x0 = t_8;
39416     }
39417     if (v_x0 == 0) {
39418       self->private_impl.f_frame_overwrite_instead_of_blend = true;
39419     } else if (v_x0 == 1) {
39420       self->private_impl.f_frame_overwrite_instead_of_blend = false;
39421     } else {
39422       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39423       goto exit;
39424     }
39425     if (self->private_impl.f_num_decoded_frame_configs_value == 0) {
39426       self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0;
39427       self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0;
39428       self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1;
39429       self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1;
39430       self->private_impl.f_first_duration = self->private_impl.f_frame_duration;
39431       self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal;
39432       self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend;
39433     }
39434 
39435     goto ok;
39436     ok:
39437     self->private_impl.p_decode_fctl[0] = 0;
39438     goto exit;
39439   }
39440 
39441   goto suspend;
39442   suspend:
39443   self->private_impl.p_decode_fctl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39444   self->private_data.s_decode_fctl[0].v_x0 = v_x0;
39445   self->private_data.s_decode_fctl[0].v_x1 = v_x1;
39446   self->private_data.s_decode_fctl[0].v_y1 = v_y1;
39447 
39448   goto exit;
39449   exit:
39450   if (a_src) {
39451     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39452   }
39453 
39454   return status;
39455 }
39456 
39457 // -------- func png.decoder.decode_gama
39458 
39459 static wuffs_base__status
wuffs_png__decoder__decode_gama(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39460 wuffs_png__decoder__decode_gama(
39461     wuffs_png__decoder* self,
39462     wuffs_base__io_buffer* a_src) {
39463   wuffs_base__status status = wuffs_base__make_status(NULL);
39464 
39465   const uint8_t* iop_a_src = NULL;
39466   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39467   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39468   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39469   if (a_src) {
39470     io0_a_src = a_src->data.ptr;
39471     io1_a_src = io0_a_src + a_src->meta.ri;
39472     iop_a_src = io1_a_src;
39473     io2_a_src = io0_a_src + a_src->meta.wi;
39474   }
39475 
39476   uint32_t coro_susp_point = self->private_impl.p_decode_gama[0];
39477   switch (coro_susp_point) {
39478     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39479 
39480     if (self->private_impl.f_chunk_length != 4) {
39481       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39482       goto exit;
39483     }
39484     self->private_impl.f_chunk_length = 0;
39485     self->private_impl.f_metadata_flavor = 5;
39486     self->private_impl.f_metadata_fourcc = 1195461953;
39487     {
39488       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39489       uint64_t t_0;
39490       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39491         t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
39492         iop_a_src += 4;
39493       } else {
39494         self->private_data.s_decode_gama[0].scratch = 0;
39495         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39496         while (true) {
39497           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39498             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39499             goto suspend;
39500           }
39501           uint64_t* scratch = &self->private_data.s_decode_gama[0].scratch;
39502           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39503           *scratch >>= 8;
39504           *scratch <<= 8;
39505           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39506           if (num_bits_0 == 24) {
39507             t_0 = ((uint64_t)(*scratch >> 32));
39508             break;
39509           }
39510           num_bits_0 += 8;
39511           *scratch |= ((uint64_t)(num_bits_0));
39512         }
39513       }
39514       self->private_impl.f_metadata_x = t_0;
39515     }
39516     self->private_impl.f_metadata_y = 0;
39517     self->private_impl.f_metadata_z = 0;
39518 
39519     goto ok;
39520     ok:
39521     self->private_impl.p_decode_gama[0] = 0;
39522     goto exit;
39523   }
39524 
39525   goto suspend;
39526   suspend:
39527   self->private_impl.p_decode_gama[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39528 
39529   goto exit;
39530   exit:
39531   if (a_src) {
39532     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39533   }
39534 
39535   return status;
39536 }
39537 
39538 // -------- func png.decoder.decode_iccp
39539 
39540 static wuffs_base__status
wuffs_png__decoder__decode_iccp(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39541 wuffs_png__decoder__decode_iccp(
39542     wuffs_png__decoder* self,
39543     wuffs_base__io_buffer* a_src) {
39544   wuffs_base__status status = wuffs_base__make_status(NULL);
39545 
39546   uint8_t v_c = 0;
39547 
39548   const uint8_t* iop_a_src = NULL;
39549   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39550   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39551   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39552   if (a_src) {
39553     io0_a_src = a_src->data.ptr;
39554     io1_a_src = io0_a_src + a_src->meta.ri;
39555     iop_a_src = io1_a_src;
39556     io2_a_src = io0_a_src + a_src->meta.wi;
39557   }
39558 
39559   uint32_t coro_susp_point = self->private_impl.p_decode_iccp[0];
39560   switch (coro_susp_point) {
39561     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39562 
39563     while (true) {
39564       if (self->private_impl.f_chunk_length <= 0) {
39565         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39566         goto exit;
39567       }
39568       self->private_impl.f_chunk_length -= 1;
39569       {
39570         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39571         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39572           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39573           goto suspend;
39574         }
39575         uint8_t t_0 = *iop_a_src++;
39576         v_c = t_0;
39577       }
39578       if (v_c == 0) {
39579         goto label__0__break;
39580       }
39581     }
39582     label__0__break:;
39583     if (self->private_impl.f_chunk_length <= 0) {
39584       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39585       goto exit;
39586     }
39587     self->private_impl.f_chunk_length -= 1;
39588     {
39589       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39590       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39591         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39592         goto suspend;
39593       }
39594       uint8_t t_1 = *iop_a_src++;
39595       v_c = t_1;
39596     }
39597     if (v_c != 0) {
39598       status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
39599       goto exit;
39600     }
39601     self->private_impl.f_metadata_is_zlib_compressed = true;
39602     self->private_impl.f_metadata_flavor = 4;
39603     self->private_impl.f_metadata_fourcc = 1229144912;
39604     self->private_impl.f_metadata_x = 0;
39605     self->private_impl.f_metadata_y = 0;
39606     self->private_impl.f_metadata_z = 0;
39607 
39608     goto ok;
39609     ok:
39610     self->private_impl.p_decode_iccp[0] = 0;
39611     goto exit;
39612   }
39613 
39614   goto suspend;
39615   suspend:
39616   self->private_impl.p_decode_iccp[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39617 
39618   goto exit;
39619   exit:
39620   if (a_src) {
39621     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39622   }
39623 
39624   return status;
39625 }
39626 
39627 // -------- func png.decoder.decode_plte
39628 
39629 static wuffs_base__status
wuffs_png__decoder__decode_plte(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39630 wuffs_png__decoder__decode_plte(
39631     wuffs_png__decoder* self,
39632     wuffs_base__io_buffer* a_src) {
39633   wuffs_base__status status = wuffs_base__make_status(NULL);
39634 
39635   uint32_t v_num_entries = 0;
39636   uint32_t v_i = 0;
39637   uint32_t v_argb = 0;
39638 
39639   const uint8_t* iop_a_src = NULL;
39640   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39641   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39642   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39643   if (a_src) {
39644     io0_a_src = a_src->data.ptr;
39645     io1_a_src = io0_a_src + a_src->meta.ri;
39646     iop_a_src = io1_a_src;
39647     io2_a_src = io0_a_src + a_src->meta.wi;
39648   }
39649 
39650   uint32_t coro_susp_point = self->private_impl.p_decode_plte[0];
39651   if (coro_susp_point) {
39652     v_num_entries = self->private_data.s_decode_plte[0].v_num_entries;
39653     v_i = self->private_data.s_decode_plte[0].v_i;
39654   }
39655   switch (coro_susp_point) {
39656     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39657 
39658     if ((self->private_impl.f_chunk_length > 768) || ((self->private_impl.f_chunk_length % 3) != 0)) {
39659       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39660       goto exit;
39661     }
39662     v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3);
39663     self->private_impl.f_chunk_length = 0;
39664     while (v_i < v_num_entries) {
39665       {
39666         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39667         uint32_t t_0;
39668         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
39669           t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
39670           iop_a_src += 3;
39671         } else {
39672           self->private_data.s_decode_plte[0].scratch = 0;
39673           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39674           while (true) {
39675             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39676               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39677               goto suspend;
39678             }
39679             uint64_t* scratch = &self->private_data.s_decode_plte[0].scratch;
39680             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39681             *scratch >>= 8;
39682             *scratch <<= 8;
39683             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39684             if (num_bits_0 == 16) {
39685               t_0 = ((uint32_t)(*scratch >> 40));
39686               break;
39687             }
39688             num_bits_0 += 8;
39689             *scratch |= ((uint64_t)(num_bits_0));
39690           }
39691         }
39692         v_argb = t_0;
39693       }
39694       v_argb |= 4278190080;
39695       self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
39696       self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
39697       self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
39698       self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
39699       v_i += 1;
39700     }
39701     while (v_i < 256) {
39702       self->private_data.f_src_palette[((4 * v_i) + 0)] = 0;
39703       self->private_data.f_src_palette[((4 * v_i) + 1)] = 0;
39704       self->private_data.f_src_palette[((4 * v_i) + 2)] = 0;
39705       self->private_data.f_src_palette[((4 * v_i) + 3)] = 255;
39706       v_i += 1;
39707     }
39708 
39709     goto ok;
39710     ok:
39711     self->private_impl.p_decode_plte[0] = 0;
39712     goto exit;
39713   }
39714 
39715   goto suspend;
39716   suspend:
39717   self->private_impl.p_decode_plte[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39718   self->private_data.s_decode_plte[0].v_num_entries = v_num_entries;
39719   self->private_data.s_decode_plte[0].v_i = v_i;
39720 
39721   goto exit;
39722   exit:
39723   if (a_src) {
39724     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39725   }
39726 
39727   return status;
39728 }
39729 
39730 // -------- func png.decoder.decode_srgb
39731 
39732 static wuffs_base__status
wuffs_png__decoder__decode_srgb(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39733 wuffs_png__decoder__decode_srgb(
39734     wuffs_png__decoder* self,
39735     wuffs_base__io_buffer* a_src) {
39736   wuffs_base__status status = wuffs_base__make_status(NULL);
39737 
39738   const uint8_t* iop_a_src = NULL;
39739   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39740   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39741   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39742   if (a_src) {
39743     io0_a_src = a_src->data.ptr;
39744     io1_a_src = io0_a_src + a_src->meta.ri;
39745     iop_a_src = io1_a_src;
39746     io2_a_src = io0_a_src + a_src->meta.wi;
39747   }
39748 
39749   uint32_t coro_susp_point = self->private_impl.p_decode_srgb[0];
39750   switch (coro_susp_point) {
39751     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39752 
39753     if (self->private_impl.f_chunk_length != 1) {
39754       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39755       goto exit;
39756     }
39757     self->private_impl.f_chunk_length = 0;
39758     self->private_impl.f_metadata_flavor = 5;
39759     self->private_impl.f_metadata_fourcc = 1397901122;
39760     {
39761       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39762       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39763         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39764         goto suspend;
39765       }
39766       uint64_t t_0 = *iop_a_src++;
39767       self->private_impl.f_metadata_x = t_0;
39768     }
39769     self->private_impl.f_metadata_y = 0;
39770     self->private_impl.f_metadata_z = 0;
39771 
39772     goto ok;
39773     ok:
39774     self->private_impl.p_decode_srgb[0] = 0;
39775     goto exit;
39776   }
39777 
39778   goto suspend;
39779   suspend:
39780   self->private_impl.p_decode_srgb[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39781 
39782   goto exit;
39783   exit:
39784   if (a_src) {
39785     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39786   }
39787 
39788   return status;
39789 }
39790 
39791 // -------- func png.decoder.decode_trns
39792 
39793 static wuffs_base__status
wuffs_png__decoder__decode_trns(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39794 wuffs_png__decoder__decode_trns(
39795     wuffs_png__decoder* self,
39796     wuffs_base__io_buffer* a_src) {
39797   wuffs_base__status status = wuffs_base__make_status(NULL);
39798 
39799   uint32_t v_i = 0;
39800   uint32_t v_n = 0;
39801   uint64_t v_u = 0;
39802 
39803   const uint8_t* iop_a_src = NULL;
39804   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39805   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39806   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39807   if (a_src) {
39808     io0_a_src = a_src->data.ptr;
39809     io1_a_src = io0_a_src + a_src->meta.ri;
39810     iop_a_src = io1_a_src;
39811     io2_a_src = io0_a_src + a_src->meta.wi;
39812   }
39813 
39814   uint32_t coro_susp_point = self->private_impl.p_decode_trns[0];
39815   if (coro_susp_point) {
39816     v_i = self->private_data.s_decode_trns[0].v_i;
39817     v_n = self->private_data.s_decode_trns[0].v_n;
39818   }
39819   switch (coro_susp_point) {
39820     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39821 
39822     if (self->private_impl.f_color_type == 0) {
39823       self->private_impl.choosy_filter_and_swizzle = (
39824           &wuffs_png__decoder__filter_and_swizzle_tricky);
39825       if (self->private_impl.f_depth <= 8) {
39826         self->private_impl.f_dst_pixfmt = 2164295816;
39827         self->private_impl.f_src_pixfmt = 2164295816;
39828       } else {
39829         self->private_impl.f_dst_pixfmt = 2164308923;
39830         self->private_impl.f_src_pixfmt = 2164308923;
39831       }
39832       if (self->private_impl.f_chunk_length != 2) {
39833         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39834         goto exit;
39835       }
39836       self->private_impl.f_chunk_length = 0;
39837       {
39838         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39839         uint64_t t_0;
39840         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39841           t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
39842           iop_a_src += 2;
39843         } else {
39844           self->private_data.s_decode_trns[0].scratch = 0;
39845           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39846           while (true) {
39847             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39848               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39849               goto suspend;
39850             }
39851             uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
39852             uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39853             *scratch >>= 8;
39854             *scratch <<= 8;
39855             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39856             if (num_bits_0 == 8) {
39857               t_0 = ((uint64_t)(*scratch >> 48));
39858               break;
39859             }
39860             num_bits_0 += 8;
39861             *scratch |= ((uint64_t)(num_bits_0));
39862           }
39863         }
39864         v_u = t_0;
39865       }
39866       if (self->private_impl.f_depth <= 1) {
39867         self->private_impl.f_remap_transparency = (((v_u & 1) * 16777215) | 4278190080);
39868       } else if (self->private_impl.f_depth <= 2) {
39869         self->private_impl.f_remap_transparency = (((v_u & 3) * 5592405) | 4278190080);
39870       } else if (self->private_impl.f_depth <= 4) {
39871         self->private_impl.f_remap_transparency = (((v_u & 15) * 1118481) | 4278190080);
39872       } else if (self->private_impl.f_depth <= 8) {
39873         self->private_impl.f_remap_transparency = (((v_u & 255) * 65793) | 4278190080);
39874       } else {
39875         self->private_impl.f_remap_transparency = ((v_u * 4295032833) | 18446462598732840960u);
39876       }
39877     } else if (self->private_impl.f_color_type == 2) {
39878       self->private_impl.choosy_filter_and_swizzle = (
39879           &wuffs_png__decoder__filter_and_swizzle_tricky);
39880       if (self->private_impl.f_depth <= 8) {
39881         self->private_impl.f_dst_pixfmt = 2164295816;
39882         self->private_impl.f_src_pixfmt = 2164295816;
39883       } else {
39884         self->private_impl.f_dst_pixfmt = 2164308923;
39885         self->private_impl.f_src_pixfmt = 2164308923;
39886       }
39887       if (self->private_impl.f_chunk_length != 6) {
39888         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39889         goto exit;
39890       }
39891       self->private_impl.f_chunk_length = 0;
39892       {
39893         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39894         uint64_t t_1;
39895         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
39896           t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src)));
39897           iop_a_src += 6;
39898         } else {
39899           self->private_data.s_decode_trns[0].scratch = 0;
39900           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39901           while (true) {
39902             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39903               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39904               goto suspend;
39905             }
39906             uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
39907             uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
39908             *scratch >>= 8;
39909             *scratch <<= 8;
39910             *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
39911             if (num_bits_1 == 40) {
39912               t_1 = ((uint64_t)(*scratch >> 16));
39913               break;
39914             }
39915             num_bits_1 += 8;
39916             *scratch |= ((uint64_t)(num_bits_1));
39917           }
39918         }
39919         v_u = t_1;
39920       }
39921       if (self->private_impl.f_depth <= 8) {
39922         self->private_impl.f_remap_transparency = ((255 & (v_u >> 0)) |
39923             (65280 & (v_u >> 8)) |
39924             (16711680 & (v_u >> 16)) |
39925             4278190080);
39926       } else {
39927         self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u);
39928       }
39929     } else if (self->private_impl.f_color_type == 3) {
39930       self->private_impl.f_dst_pixfmt = 2164523016;
39931       self->private_impl.f_src_pixfmt = 2164523016;
39932       if (self->private_impl.f_chunk_length > 256) {
39933         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39934         goto exit;
39935       }
39936       v_n = ((uint32_t)(self->private_impl.f_chunk_length));
39937       self->private_impl.f_chunk_length = 0;
39938       while (v_i < v_n) {
39939         {
39940           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39941           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39942             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39943             goto suspend;
39944           }
39945           uint8_t t_2 = *iop_a_src++;
39946           self->private_data.f_src_palette[((4 * v_i) + 3)] = t_2;
39947         }
39948         v_i += 1;
39949       }
39950     } else {
39951       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39952       goto exit;
39953     }
39954 
39955     goto ok;
39956     ok:
39957     self->private_impl.p_decode_trns[0] = 0;
39958     goto exit;
39959   }
39960 
39961   goto suspend;
39962   suspend:
39963   self->private_impl.p_decode_trns[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39964   self->private_data.s_decode_trns[0].v_i = v_i;
39965   self->private_data.s_decode_trns[0].v_n = v_n;
39966 
39967   goto exit;
39968   exit:
39969   if (a_src) {
39970     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39971   }
39972 
39973   return status;
39974 }
39975 
39976 // -------- func png.decoder.decode_frame_config
39977 
39978 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)39979 wuffs_png__decoder__decode_frame_config(
39980     wuffs_png__decoder* self,
39981     wuffs_base__frame_config* a_dst,
39982     wuffs_base__io_buffer* a_src) {
39983   if (!self) {
39984     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
39985   }
39986   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
39987     return wuffs_base__make_status(
39988         (self->private_impl.magic == WUFFS_BASE__DISABLED)
39989         ? wuffs_base__error__disabled_by_previous_error
39990         : wuffs_base__error__initialize_not_called);
39991   }
39992   if (!a_src) {
39993     self->private_impl.magic = WUFFS_BASE__DISABLED;
39994     return wuffs_base__make_status(wuffs_base__error__bad_argument);
39995   }
39996   if ((self->private_impl.active_coroutine != 0) &&
39997       (self->private_impl.active_coroutine != 2)) {
39998     self->private_impl.magic = WUFFS_BASE__DISABLED;
39999     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
40000   }
40001   self->private_impl.active_coroutine = 0;
40002   wuffs_base__status status = wuffs_base__make_status(NULL);
40003 
40004   const uint8_t* iop_a_src = NULL;
40005   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40006   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40007   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40008   if (a_src) {
40009     io0_a_src = a_src->data.ptr;
40010     io1_a_src = io0_a_src + a_src->meta.ri;
40011     iop_a_src = io1_a_src;
40012     io2_a_src = io0_a_src + a_src->meta.wi;
40013   }
40014 
40015   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
40016   switch (coro_susp_point) {
40017     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40018 
40019     if (self->private_impl.f_call_sequence == 255) {
40020       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
40021       goto ok;
40022     } else if (self->private_impl.f_call_sequence < 3) {
40023       if (a_src) {
40024         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40025       }
40026       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40027       status = wuffs_png__decoder__decode_image_config(self, NULL, a_src);
40028       if (a_src) {
40029         iop_a_src = a_src->data.ptr + a_src->meta.ri;
40030       }
40031       if (status.repr) {
40032         goto suspend;
40033       }
40034     } else if (self->private_impl.f_call_sequence == 3) {
40035       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)))) {
40036         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
40037         goto exit;
40038       }
40039     } else if (self->private_impl.f_call_sequence == 4) {
40040       if (a_src) {
40041         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40042       }
40043       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40044       status = wuffs_png__decoder__skip_frame(self, a_src);
40045       if (a_src) {
40046         iop_a_src = a_src->data.ptr + a_src->meta.ri;
40047       }
40048       if (status.repr) {
40049         goto suspend;
40050       }
40051       if (self->private_impl.f_call_sequence == 255) {
40052         status = wuffs_base__make_status(wuffs_base__note__end_of_data);
40053         goto ok;
40054       }
40055     }
40056     if (self->private_impl.f_num_decoded_frame_configs_value == 0) {
40057       self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0;
40058       self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0;
40059       self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1;
40060       self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1;
40061       self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position;
40062       self->private_impl.f_frame_duration = self->private_impl.f_first_duration;
40063       self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal;
40064       self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend;
40065     } else {
40066       while (true) {
40067         {
40068           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40069           uint32_t t_0;
40070           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40071             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40072             iop_a_src += 4;
40073           } else {
40074             self->private_data.s_decode_frame_config[0].scratch = 0;
40075             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40076             while (true) {
40077               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40078                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40079                 goto suspend;
40080               }
40081               uint64_t* scratch = &self->private_data.s_decode_frame_config[0].scratch;
40082               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
40083               *scratch >>= 8;
40084               *scratch <<= 8;
40085               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
40086               if (num_bits_0 == 24) {
40087                 t_0 = ((uint32_t)(*scratch >> 32));
40088                 break;
40089               }
40090               num_bits_0 += 8;
40091               *scratch |= ((uint64_t)(num_bits_0));
40092             }
40093           }
40094           self->private_impl.f_chunk_length = t_0;
40095         }
40096         {
40097           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40098           uint32_t t_1;
40099           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40100             t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
40101             iop_a_src += 4;
40102           } else {
40103             self->private_data.s_decode_frame_config[0].scratch = 0;
40104             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40105             while (true) {
40106               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40107                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40108                 goto suspend;
40109               }
40110               uint64_t* scratch = &self->private_data.s_decode_frame_config[0].scratch;
40111               uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
40112               *scratch <<= 8;
40113               *scratch >>= 8;
40114               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
40115               if (num_bits_1 == 24) {
40116                 t_1 = ((uint32_t)(*scratch));
40117                 break;
40118               }
40119               num_bits_1 += 8;
40120               *scratch |= ((uint64_t)(num_bits_1)) << 56;
40121             }
40122           }
40123           self->private_impl.f_chunk_type = t_1;
40124         }
40125         if (self->private_impl.f_chunk_type == 1413571686) {
40126           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40127           goto exit;
40128         } else if (self->private_impl.f_chunk_type == 1280598886) {
40129           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));
40130           if (a_src) {
40131             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40132           }
40133           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
40134           status = wuffs_png__decoder__decode_fctl(self, a_src);
40135           if (a_src) {
40136             iop_a_src = a_src->data.ptr + a_src->meta.ri;
40137           }
40138           if (status.repr) {
40139             goto suspend;
40140           }
40141           self->private_data.s_decode_frame_config[0].scratch = 4;
40142           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
40143           if (self->private_data.s_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40144             self->private_data.s_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40145             iop_a_src = io2_a_src;
40146             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40147             goto suspend;
40148           }
40149           iop_a_src += self->private_data.s_decode_frame_config[0].scratch;
40150           goto label__0__break;
40151         }
40152         self->private_data.s_decode_frame_config[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4);
40153         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
40154         if (self->private_data.s_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40155           self->private_data.s_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40156           iop_a_src = io2_a_src;
40157           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40158           goto suspend;
40159         }
40160         iop_a_src += self->private_data.s_decode_frame_config[0].scratch;
40161         self->private_impl.f_chunk_length = 0;
40162       }
40163       label__0__break:;
40164     }
40165     if (a_dst != NULL) {
40166       wuffs_base__frame_config__set(
40167           a_dst,
40168           wuffs_base__utility__make_rect_ie_u32(
40169           self->private_impl.f_frame_rect_x0,
40170           self->private_impl.f_frame_rect_y0,
40171           self->private_impl.f_frame_rect_x1,
40172           self->private_impl.f_frame_rect_y1),
40173           ((wuffs_base__flicks)(self->private_impl.f_frame_duration)),
40174           ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)),
40175           self->private_impl.f_frame_config_io_position,
40176           self->private_impl.f_frame_disposal,
40177           ((self->private_impl.f_color_type <= 3) &&  ! self->private_impl.f_seen_trns),
40178           self->private_impl.f_frame_overwrite_instead_of_blend,
40179           0);
40180     }
40181     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
40182     self->private_impl.f_call_sequence = 4;
40183 
40184     ok:
40185     self->private_impl.p_decode_frame_config[0] = 0;
40186     goto exit;
40187   }
40188 
40189   goto suspend;
40190   suspend:
40191   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40192   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
40193 
40194   goto exit;
40195   exit:
40196   if (a_src) {
40197     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40198   }
40199 
40200   if (wuffs_base__status__is_error(&status)) {
40201     self->private_impl.magic = WUFFS_BASE__DISABLED;
40202   }
40203   return status;
40204 }
40205 
40206 // -------- func png.decoder.skip_frame
40207 
40208 static wuffs_base__status
wuffs_png__decoder__skip_frame(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)40209 wuffs_png__decoder__skip_frame(
40210     wuffs_png__decoder* self,
40211     wuffs_base__io_buffer* a_src) {
40212   wuffs_base__status status = wuffs_base__make_status(NULL);
40213 
40214   uint32_t v_seq_num = 0;
40215 
40216   const uint8_t* iop_a_src = NULL;
40217   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40218   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40219   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40220   if (a_src) {
40221     io0_a_src = a_src->data.ptr;
40222     io1_a_src = io0_a_src + a_src->meta.ri;
40223     iop_a_src = io1_a_src;
40224     io2_a_src = io0_a_src + a_src->meta.wi;
40225   }
40226 
40227   uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
40228   switch (coro_susp_point) {
40229     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40230 
40231     self->private_impl.f_chunk_type_array[0] = 0;
40232     self->private_impl.f_chunk_type_array[1] = 0;
40233     self->private_impl.f_chunk_type_array[2] = 0;
40234     self->private_impl.f_chunk_type_array[3] = 0;
40235     label__0__continue:;
40236     while (true) {
40237       while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
40238         if (a_src && a_src->meta.closed) {
40239           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40240           goto exit;
40241         }
40242         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40243         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
40244       }
40245       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40246       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
40247       if (self->private_impl.f_chunk_type == 1413563465) {
40248         if (self->private_impl.f_chunk_type_array[0] == 102) {
40249           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40250           goto exit;
40251         }
40252         self->private_impl.f_chunk_type_array[0] = 73;
40253         self->private_impl.f_chunk_type_array[1] = 68;
40254         self->private_impl.f_chunk_type_array[2] = 65;
40255         self->private_impl.f_chunk_type_array[3] = 84;
40256       } else if (self->private_impl.f_chunk_type == 1413571686) {
40257         if (self->private_impl.f_chunk_type_array[0] == 73) {
40258           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40259           goto exit;
40260         }
40261         self->private_impl.f_chunk_type_array[0] = 102;
40262         self->private_impl.f_chunk_type_array[1] = 100;
40263         self->private_impl.f_chunk_type_array[2] = 65;
40264         self->private_impl.f_chunk_type_array[3] = 84;
40265         if (self->private_impl.f_chunk_length < 4) {
40266           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40267           goto exit;
40268         }
40269         self->private_impl.f_chunk_length -= 4;
40270         iop_a_src += 8;
40271         {
40272           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40273           uint32_t t_0;
40274           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40275             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40276             iop_a_src += 4;
40277           } else {
40278             self->private_data.s_skip_frame[0].scratch = 0;
40279             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40280             while (true) {
40281               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40282                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40283                 goto suspend;
40284               }
40285               uint64_t* scratch = &self->private_data.s_skip_frame[0].scratch;
40286               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
40287               *scratch >>= 8;
40288               *scratch <<= 8;
40289               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
40290               if (num_bits_0 == 24) {
40291                 t_0 = ((uint32_t)(*scratch >> 32));
40292                 break;
40293               }
40294               num_bits_0 += 8;
40295               *scratch |= ((uint64_t)(num_bits_0));
40296             }
40297           }
40298           v_seq_num = t_0;
40299         }
40300         if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
40301           status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
40302           goto exit;
40303         } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
40304           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
40305           goto exit;
40306         }
40307         self->private_impl.f_next_animation_seq_num += 1;
40308         self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4);
40309         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40310         if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40311           self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40312           iop_a_src = io2_a_src;
40313           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40314           goto suspend;
40315         }
40316         iop_a_src += self->private_data.s_skip_frame[0].scratch;
40317         self->private_impl.f_chunk_length = 0;
40318         goto label__0__continue;
40319       } else if (self->private_impl.f_chunk_type_array[0] != 0) {
40320         goto label__0__break;
40321       } else if (self->private_impl.f_chunk_type == 1280598886) {
40322         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40323         goto exit;
40324       }
40325       self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12);
40326       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40327       if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40328         self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40329         iop_a_src = io2_a_src;
40330         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40331         goto suspend;
40332       }
40333       iop_a_src += self->private_data.s_skip_frame[0].scratch;
40334       self->private_impl.f_chunk_length = 0;
40335     }
40336     label__0__break:;
40337     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
40338     if (self->private_impl.f_num_decoded_frames_value < self->private_impl.f_num_animation_frames_value) {
40339       self->private_impl.f_call_sequence = 5;
40340     } else {
40341       self->private_impl.f_call_sequence = 255;
40342     }
40343 
40344     ok:
40345     self->private_impl.p_skip_frame[0] = 0;
40346     goto exit;
40347   }
40348 
40349   goto suspend;
40350   suspend:
40351   self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40352 
40353   goto exit;
40354   exit:
40355   if (a_src) {
40356     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40357   }
40358 
40359   return status;
40360 }
40361 
40362 // -------- func png.decoder.decode_frame
40363 
40364 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)40365 wuffs_png__decoder__decode_frame(
40366     wuffs_png__decoder* self,
40367     wuffs_base__pixel_buffer* a_dst,
40368     wuffs_base__io_buffer* a_src,
40369     wuffs_base__pixel_blend a_blend,
40370     wuffs_base__slice_u8 a_workbuf,
40371     wuffs_base__decode_frame_options* a_opts) {
40372   if (!self) {
40373     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40374   }
40375   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
40376     return wuffs_base__make_status(
40377         (self->private_impl.magic == WUFFS_BASE__DISABLED)
40378         ? wuffs_base__error__disabled_by_previous_error
40379         : wuffs_base__error__initialize_not_called);
40380   }
40381   if (!a_dst || !a_src) {
40382     self->private_impl.magic = WUFFS_BASE__DISABLED;
40383     return wuffs_base__make_status(wuffs_base__error__bad_argument);
40384   }
40385   if ((self->private_impl.active_coroutine != 0) &&
40386       (self->private_impl.active_coroutine != 3)) {
40387     self->private_impl.magic = WUFFS_BASE__DISABLED;
40388     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
40389   }
40390   self->private_impl.active_coroutine = 0;
40391   wuffs_base__status status = wuffs_base__make_status(NULL);
40392 
40393   uint32_t v_seq_num = 0;
40394   wuffs_base__status v_status = wuffs_base__make_status(NULL);
40395   uint32_t v_pass_width = 0;
40396   uint32_t v_pass_height = 0;
40397 
40398   const uint8_t* iop_a_src = NULL;
40399   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40400   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40401   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40402   if (a_src) {
40403     io0_a_src = a_src->data.ptr;
40404     io1_a_src = io0_a_src + a_src->meta.ri;
40405     iop_a_src = io1_a_src;
40406     io2_a_src = io0_a_src + a_src->meta.wi;
40407   }
40408 
40409   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
40410   switch (coro_susp_point) {
40411     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40412 
40413     if (self->private_impl.f_call_sequence == 255) {
40414       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
40415       goto ok;
40416     } else if (self->private_impl.f_call_sequence != 4) {
40417       if (a_src) {
40418         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40419       }
40420       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40421       status = wuffs_png__decoder__decode_frame_config(self, NULL, a_src);
40422       if (a_src) {
40423         iop_a_src = a_src->data.ptr + a_src->meta.ri;
40424       }
40425       if (status.repr) {
40426         goto suspend;
40427       }
40428     }
40429     while (true) {
40430       while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
40431         if (a_src && a_src->meta.closed) {
40432           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40433           goto exit;
40434         }
40435         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40436         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
40437       }
40438       self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40439       self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
40440       if (self->private_impl.f_chunk_type == 1413563465) {
40441         self->private_impl.f_chunk_type_array[0] = 73;
40442         self->private_impl.f_chunk_type_array[1] = 68;
40443         self->private_impl.f_chunk_type_array[2] = 65;
40444         self->private_impl.f_chunk_type_array[3] = 84;
40445         iop_a_src += 8;
40446         if ( ! self->private_impl.f_ignore_checksum) {
40447           wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
40448               sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40449           wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
40450         }
40451         goto label__0__break;
40452       } else if (self->private_impl.f_chunk_type == 1413571686) {
40453         self->private_impl.f_chunk_type_array[0] = 102;
40454         self->private_impl.f_chunk_type_array[1] = 100;
40455         self->private_impl.f_chunk_type_array[2] = 65;
40456         self->private_impl.f_chunk_type_array[3] = 84;
40457         if (self->private_impl.f_chunk_length < 4) {
40458           status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40459           goto exit;
40460         }
40461         self->private_impl.f_chunk_length -= 4;
40462         iop_a_src += 8;
40463         {
40464           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40465           uint32_t t_0;
40466           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40467             t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40468             iop_a_src += 4;
40469           } else {
40470             self->private_data.s_decode_frame[0].scratch = 0;
40471             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40472             while (true) {
40473               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40474                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40475                 goto suspend;
40476               }
40477               uint64_t* scratch = &self->private_data.s_decode_frame[0].scratch;
40478               uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
40479               *scratch >>= 8;
40480               *scratch <<= 8;
40481               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
40482               if (num_bits_0 == 24) {
40483                 t_0 = ((uint32_t)(*scratch >> 32));
40484                 break;
40485               }
40486               num_bits_0 += 8;
40487               *scratch |= ((uint64_t)(num_bits_0));
40488             }
40489           }
40490           v_seq_num = t_0;
40491         }
40492         if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
40493           status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
40494           goto exit;
40495         } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
40496           status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
40497           goto exit;
40498         }
40499         self->private_impl.f_next_animation_seq_num += 1;
40500         goto label__0__break;
40501       } else if (self->private_impl.f_chunk_type == 1280598886) {
40502         status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40503         goto exit;
40504       }
40505       self->private_data.s_decode_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12);
40506       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40507       if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40508         self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40509         iop_a_src = io2_a_src;
40510         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40511         goto suspend;
40512       }
40513       iop_a_src += self->private_data.s_decode_frame[0].scratch;
40514       self->private_impl.f_chunk_length = 0;
40515     }
40516     label__0__break:;
40517     if (self->private_impl.f_zlib_is_dirty) {
40518       wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
40519           sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40520       if (self->private_impl.f_ignore_checksum) {
40521         wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, 1, true);
40522       }
40523     }
40524     self->private_impl.f_zlib_is_dirty = true;
40525     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
40526         wuffs_base__pixel_buffer__pixel_format(a_dst),
40527         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
40528         wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
40529         wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
40530         a_blend);
40531     if ( ! wuffs_base__status__is_ok(&v_status)) {
40532       status = v_status;
40533       if (wuffs_base__status__is_error(&status)) {
40534         goto exit;
40535       } else if (wuffs_base__status__is_suspension(&status)) {
40536         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40537         goto exit;
40538       }
40539       goto ok;
40540     }
40541     self->private_impl.f_workbuf_hist_pos_base = 0;
40542     while (true) {
40543       if (self->private_impl.f_chunk_type_array[0] == 73) {
40544         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]));
40545         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]));
40546       } else {
40547         v_pass_width = (16777215 & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0)));
40548         v_pass_height = (16777215 & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0)));
40549       }
40550       if ((v_pass_width > 0) && (v_pass_height > 0)) {
40551         self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width);
40552         self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1 + self->private_impl.f_pass_bytes_per_row));
40553         if (a_src) {
40554           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40555         }
40556         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40557         status = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf);
40558         if (a_src) {
40559           iop_a_src = a_src->data.ptr + a_src->meta.ri;
40560         }
40561         if (status.repr) {
40562           goto suspend;
40563         }
40564         v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf);
40565         if ( ! wuffs_base__status__is_ok(&v_status)) {
40566           status = v_status;
40567           if (wuffs_base__status__is_error(&status)) {
40568             goto exit;
40569           } else if (wuffs_base__status__is_suspension(&status)) {
40570             status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40571             goto exit;
40572           }
40573           goto ok;
40574         }
40575         self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length;
40576       }
40577       if ((self->private_impl.f_interlace_pass == 0) || (self->private_impl.f_interlace_pass >= 7)) {
40578         goto label__1__break;
40579       }
40580 #if defined(__GNUC__)
40581 #pragma GCC diagnostic push
40582 #pragma GCC diagnostic ignored "-Wconversion"
40583 #endif
40584       self->private_impl.f_interlace_pass += 1;
40585 #if defined(__GNUC__)
40586 #pragma GCC diagnostic pop
40587 #endif
40588     }
40589     label__1__break:;
40590     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
40591     if (self->private_impl.f_num_decoded_frames_value < self->private_impl.f_num_animation_frames_value) {
40592       self->private_impl.f_call_sequence = 5;
40593     } else {
40594       self->private_impl.f_call_sequence = 255;
40595     }
40596 
40597     ok:
40598     self->private_impl.p_decode_frame[0] = 0;
40599     goto exit;
40600   }
40601 
40602   goto suspend;
40603   suspend:
40604   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40605   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
40606 
40607   goto exit;
40608   exit:
40609   if (a_src) {
40610     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40611   }
40612 
40613   if (wuffs_base__status__is_error(&status)) {
40614     self->private_impl.magic = WUFFS_BASE__DISABLED;
40615   }
40616   return status;
40617 }
40618 
40619 // -------- func png.decoder.decode_pass
40620 
40621 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)40622 wuffs_png__decoder__decode_pass(
40623     wuffs_png__decoder* self,
40624     wuffs_base__io_buffer* a_src,
40625     wuffs_base__slice_u8 a_workbuf) {
40626   wuffs_base__status status = wuffs_base__make_status(NULL);
40627 
40628   wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
40629   wuffs_base__io_buffer* v_w = &u_w;
40630   uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40631   uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40632   uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40633   uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40634   uint64_t v_w_mark = 0;
40635   uint64_t v_r_mark = 0;
40636   wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
40637   uint32_t v_checksum_have = 0;
40638   uint32_t v_checksum_want = 0;
40639   uint32_t v_seq_num = 0;
40640 
40641   const uint8_t* iop_a_src = NULL;
40642   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40643   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40644   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40645   if (a_src) {
40646     io0_a_src = a_src->data.ptr;
40647     io1_a_src = io0_a_src + a_src->meta.ri;
40648     iop_a_src = io1_a_src;
40649     io2_a_src = io0_a_src + a_src->meta.wi;
40650   }
40651 
40652   uint32_t coro_susp_point = self->private_impl.p_decode_pass[0];
40653   switch (coro_susp_point) {
40654     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40655 
40656     self->private_impl.f_workbuf_wi = 0;
40657     label__0__continue:;
40658     while (true) {
40659       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)))) {
40660         status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
40661         goto exit;
40662       }
40663       {
40664         wuffs_base__io_buffer* o_0_v_w = v_w;
40665         uint8_t *o_0_iop_v_w = iop_v_w;
40666         uint8_t *o_0_io0_v_w = io0_v_w;
40667         uint8_t *o_0_io1_v_w = io1_v_w;
40668         uint8_t *o_0_io2_v_w = io2_v_w;
40669         v_w = wuffs_base__io_writer__set(
40670             &u_w,
40671             &iop_v_w,
40672             &io0_v_w,
40673             &io1_v_w,
40674             &io2_v_w,
40675             wuffs_base__slice_u8__subslice_ij(a_workbuf,
40676             self->private_impl.f_workbuf_wi,
40677             self->private_impl.f_pass_workbuf_length),
40678             ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi)));
40679         {
40680           const uint8_t *o_1_io2_a_src = io2_a_src;
40681           wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
40682               ((uint64_t)(self->private_impl.f_chunk_length)));
40683           if (a_src) {
40684             a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40685           }
40686           v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
40687           v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
40688           {
40689             u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
40690             if (a_src) {
40691               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40692             }
40693             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());
40694             v_zlib_status = t_0;
40695             iop_v_w = u_w.data.ptr + u_w.meta.wi;
40696             if (a_src) {
40697               iop_a_src = a_src->data.ptr + a_src->meta.ri;
40698             }
40699           }
40700           if ( ! self->private_impl.f_ignore_checksum) {
40701             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));
40702           }
40703           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))));
40704           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))));
40705           io2_a_src = o_1_io2_a_src;
40706           if (a_src) {
40707             a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40708           }
40709         }
40710         v_w = o_0_v_w;
40711         iop_v_w = o_0_iop_v_w;
40712         io0_v_w = o_0_io0_v_w;
40713         io1_v_w = o_0_io1_v_w;
40714         io2_v_w = o_0_io2_v_w;
40715       }
40716       if (wuffs_base__status__is_ok(&v_zlib_status)) {
40717         if (self->private_impl.f_chunk_length > 0) {
40718           status = wuffs_base__make_status(wuffs_base__error__too_much_data);
40719           goto exit;
40720         }
40721         {
40722           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40723           uint32_t t_1;
40724           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40725             t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40726             iop_a_src += 4;
40727           } else {
40728             self->private_data.s_decode_pass[0].scratch = 0;
40729             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40730             while (true) {
40731               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40732                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40733                 goto suspend;
40734               }
40735               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40736               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
40737               *scratch >>= 8;
40738               *scratch <<= 8;
40739               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
40740               if (num_bits_1 == 24) {
40741                 t_1 = ((uint32_t)(*scratch >> 32));
40742                 break;
40743               }
40744               num_bits_1 += 8;
40745               *scratch |= ((uint64_t)(num_bits_1));
40746             }
40747           }
40748           v_checksum_want = t_1;
40749         }
40750         if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0] == 73)) {
40751           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
40752           if (v_checksum_have != v_checksum_want) {
40753             status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
40754             goto exit;
40755           }
40756         }
40757         goto label__0__break;
40758       } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) {
40759         if ((1 <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6)) {
40760           goto label__0__break;
40761         }
40762         status = wuffs_base__make_status(wuffs_base__error__too_much_data);
40763         goto exit;
40764       } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) {
40765         status = v_zlib_status;
40766         if (wuffs_base__status__is_error(&status)) {
40767           goto exit;
40768         } else if (wuffs_base__status__is_suspension(&status)) {
40769           status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40770           goto exit;
40771         }
40772         goto ok;
40773       } else if (self->private_impl.f_chunk_length == 0) {
40774         {
40775           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40776           uint32_t t_2;
40777           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40778             t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40779             iop_a_src += 4;
40780           } else {
40781             self->private_data.s_decode_pass[0].scratch = 0;
40782             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40783             while (true) {
40784               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40785                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40786                 goto suspend;
40787               }
40788               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40789               uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
40790               *scratch >>= 8;
40791               *scratch <<= 8;
40792               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
40793               if (num_bits_2 == 24) {
40794                 t_2 = ((uint32_t)(*scratch >> 32));
40795                 break;
40796               }
40797               num_bits_2 += 8;
40798               *scratch |= ((uint64_t)(num_bits_2));
40799             }
40800           }
40801           v_checksum_want = t_2;
40802         }
40803         if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0] == 73)) {
40804           v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
40805           if (v_checksum_have != v_checksum_want) {
40806             status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
40807             goto exit;
40808           }
40809         }
40810         {
40811           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40812           uint32_t t_3;
40813           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40814             t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40815             iop_a_src += 4;
40816           } else {
40817             self->private_data.s_decode_pass[0].scratch = 0;
40818             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40819             while (true) {
40820               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40821                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40822                 goto suspend;
40823               }
40824               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40825               uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
40826               *scratch >>= 8;
40827               *scratch <<= 8;
40828               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
40829               if (num_bits_3 == 24) {
40830                 t_3 = ((uint32_t)(*scratch >> 32));
40831                 break;
40832               }
40833               num_bits_3 += 8;
40834               *scratch |= ((uint64_t)(num_bits_3));
40835             }
40836           }
40837           self->private_impl.f_chunk_length = t_3;
40838         }
40839         {
40840           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
40841           uint32_t t_4;
40842           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40843             t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
40844             iop_a_src += 4;
40845           } else {
40846             self->private_data.s_decode_pass[0].scratch = 0;
40847             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
40848             while (true) {
40849               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40850                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40851                 goto suspend;
40852               }
40853               uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40854               uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
40855               *scratch <<= 8;
40856               *scratch >>= 8;
40857               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
40858               if (num_bits_4 == 24) {
40859                 t_4 = ((uint32_t)(*scratch));
40860                 break;
40861               }
40862               num_bits_4 += 8;
40863               *scratch |= ((uint64_t)(num_bits_4)) << 56;
40864             }
40865           }
40866           self->private_impl.f_chunk_type = t_4;
40867         }
40868         if (self->private_impl.f_chunk_type_array[0] == 73) {
40869           if (self->private_impl.f_chunk_type != 1413563465) {
40870             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40871             goto exit;
40872           }
40873           if ( ! self->private_impl.f_ignore_checksum) {
40874             wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
40875                 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40876             wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
40877           }
40878         } else {
40879           if ((self->private_impl.f_chunk_type != 1413571686) || (self->private_impl.f_chunk_length < 4)) {
40880             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40881             goto exit;
40882           }
40883           self->private_impl.f_chunk_length -= 4;
40884           {
40885             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
40886             uint32_t t_5;
40887             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40888               t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40889               iop_a_src += 4;
40890             } else {
40891               self->private_data.s_decode_pass[0].scratch = 0;
40892               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
40893               while (true) {
40894                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40895                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40896                   goto suspend;
40897                 }
40898                 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40899                 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
40900                 *scratch >>= 8;
40901                 *scratch <<= 8;
40902                 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
40903                 if (num_bits_5 == 24) {
40904                   t_5 = ((uint32_t)(*scratch >> 32));
40905                   break;
40906                 }
40907                 num_bits_5 += 8;
40908                 *scratch |= ((uint64_t)(num_bits_5));
40909               }
40910             }
40911             v_seq_num = t_5;
40912           }
40913           if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
40914             status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
40915             goto exit;
40916           } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
40917             status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
40918             goto exit;
40919           }
40920           self->private_impl.f_next_animation_seq_num += 1;
40921         }
40922         goto label__0__continue;
40923       } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0) {
40924         status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input);
40925         goto exit;
40926       }
40927       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40928       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
40929     }
40930     label__0__break:;
40931     if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) {
40932       status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
40933       goto exit;
40934     } else if (0 < ((uint64_t)(a_workbuf.len))) {
40935       if (a_workbuf.ptr[0] == 4) {
40936         a_workbuf.ptr[0] = 1;
40937       }
40938     }
40939 
40940     ok:
40941     self->private_impl.p_decode_pass[0] = 0;
40942     goto exit;
40943   }
40944 
40945   goto suspend;
40946   suspend:
40947   self->private_impl.p_decode_pass[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40948 
40949   goto exit;
40950   exit:
40951   if (a_src) {
40952     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40953   }
40954 
40955   return status;
40956 }
40957 
40958 // -------- func png.decoder.frame_dirty_rect
40959 
40960 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_png__decoder__frame_dirty_rect(const wuffs_png__decoder * self)40961 wuffs_png__decoder__frame_dirty_rect(
40962     const wuffs_png__decoder* self) {
40963   if (!self) {
40964     return wuffs_base__utility__empty_rect_ie_u32();
40965   }
40966   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40967       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40968     return wuffs_base__utility__empty_rect_ie_u32();
40969   }
40970 
40971   return wuffs_base__utility__make_rect_ie_u32(
40972       self->private_impl.f_frame_rect_x0,
40973       self->private_impl.f_frame_rect_y0,
40974       self->private_impl.f_frame_rect_x1,
40975       self->private_impl.f_frame_rect_y1);
40976 }
40977 
40978 // -------- func png.decoder.num_animation_loops
40979 
40980 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_png__decoder__num_animation_loops(const wuffs_png__decoder * self)40981 wuffs_png__decoder__num_animation_loops(
40982     const wuffs_png__decoder* self) {
40983   if (!self) {
40984     return 0;
40985   }
40986   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40987       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40988     return 0;
40989   }
40990 
40991   return self->private_impl.f_num_animation_loops_value;
40992 }
40993 
40994 // -------- func png.decoder.num_decoded_frame_configs
40995 
40996 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frame_configs(const wuffs_png__decoder * self)40997 wuffs_png__decoder__num_decoded_frame_configs(
40998     const wuffs_png__decoder* self) {
40999   if (!self) {
41000     return 0;
41001   }
41002   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41003       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41004     return 0;
41005   }
41006 
41007   return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value));
41008 }
41009 
41010 // -------- func png.decoder.num_decoded_frames
41011 
41012 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frames(const wuffs_png__decoder * self)41013 wuffs_png__decoder__num_decoded_frames(
41014     const wuffs_png__decoder* self) {
41015   if (!self) {
41016     return 0;
41017   }
41018   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41019       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41020     return 0;
41021   }
41022 
41023   return ((uint64_t)(self->private_impl.f_num_decoded_frames_value));
41024 }
41025 
41026 // -------- func png.decoder.restart_frame
41027 
41028 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)41029 wuffs_png__decoder__restart_frame(
41030     wuffs_png__decoder* self,
41031     uint64_t a_index,
41032     uint64_t a_io_position) {
41033   if (!self) {
41034     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41035   }
41036   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41037     return wuffs_base__make_status(
41038         (self->private_impl.magic == WUFFS_BASE__DISABLED)
41039         ? wuffs_base__error__disabled_by_previous_error
41040         : wuffs_base__error__initialize_not_called);
41041   }
41042 
41043   if (self->private_impl.f_call_sequence < 3) {
41044     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41045   } 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))) {
41046     return wuffs_base__make_status(wuffs_base__error__bad_argument);
41047   }
41048   self->private_impl.f_call_sequence = 3;
41049   if (self->private_impl.f_interlace_pass >= 1) {
41050     self->private_impl.f_interlace_pass = 1;
41051   }
41052   self->private_impl.f_frame_config_io_position = a_io_position;
41053   self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)((a_index & 4294967295)));
41054   self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value;
41055   return wuffs_base__make_status(NULL);
41056 }
41057 
41058 // -------- func png.decoder.set_report_metadata
41059 
41060 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)41061 wuffs_png__decoder__set_report_metadata(
41062     wuffs_png__decoder* self,
41063     uint32_t a_fourcc,
41064     bool a_report) {
41065   if (!self) {
41066     return wuffs_base__make_empty_struct();
41067   }
41068   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41069     return wuffs_base__make_empty_struct();
41070   }
41071 
41072   if (a_fourcc == 1128813133) {
41073     self->private_impl.f_report_metadata_chrm = a_report;
41074   } else if (a_fourcc == 1163413830) {
41075     self->private_impl.f_report_metadata_exif = a_report;
41076   } else if (a_fourcc == 1195461953) {
41077     self->private_impl.f_report_metadata_gama = a_report;
41078   } else if (a_fourcc == 1229144912) {
41079     self->private_impl.f_report_metadata_iccp = a_report;
41080   } else if (a_fourcc == 1263947808) {
41081     self->private_impl.f_report_metadata_kvp = a_report;
41082   } else if (a_fourcc == 1397901122) {
41083     self->private_impl.f_report_metadata_srgb = a_report;
41084   }
41085   return wuffs_base__make_empty_struct();
41086 }
41087 
41088 // -------- func png.decoder.tell_me_more
41089 
41090 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)41091 wuffs_png__decoder__tell_me_more(
41092     wuffs_png__decoder* self,
41093     wuffs_base__io_buffer* a_dst,
41094     wuffs_base__more_information* a_minfo,
41095     wuffs_base__io_buffer* a_src) {
41096   if (!self) {
41097     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41098   }
41099   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41100     return wuffs_base__make_status(
41101         (self->private_impl.magic == WUFFS_BASE__DISABLED)
41102         ? wuffs_base__error__disabled_by_previous_error
41103         : wuffs_base__error__initialize_not_called);
41104   }
41105   if (!a_dst || !a_src) {
41106     self->private_impl.magic = WUFFS_BASE__DISABLED;
41107     return wuffs_base__make_status(wuffs_base__error__bad_argument);
41108   }
41109   if ((self->private_impl.active_coroutine != 0) &&
41110       (self->private_impl.active_coroutine != 4)) {
41111     self->private_impl.magic = WUFFS_BASE__DISABLED;
41112     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41113   }
41114   self->private_impl.active_coroutine = 0;
41115   wuffs_base__status status = wuffs_base__make_status(NULL);
41116 
41117   uint8_t v_c = 0;
41118   uint16_t v_c2 = 0;
41119   wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
41120   wuffs_base__io_buffer* v_w = &u_w;
41121   uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41122   uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41123   uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41124   uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41125   uint64_t v_num_written = 0;
41126   uint64_t v_w_mark = 0;
41127   uint64_t v_r_mark = 0;
41128   wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
41129 
41130   uint8_t* iop_a_dst = NULL;
41131   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41132   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41133   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41134   if (a_dst) {
41135     io0_a_dst = a_dst->data.ptr;
41136     io1_a_dst = io0_a_dst + a_dst->meta.wi;
41137     iop_a_dst = io1_a_dst;
41138     io2_a_dst = io0_a_dst + a_dst->data.len;
41139     if (a_dst->meta.closed) {
41140       io2_a_dst = iop_a_dst;
41141     }
41142   }
41143   const uint8_t* iop_a_src = NULL;
41144   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41145   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41146   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41147   if (a_src) {
41148     io0_a_src = a_src->data.ptr;
41149     io1_a_src = io0_a_src + a_src->meta.ri;
41150     iop_a_src = io1_a_src;
41151     io2_a_src = io0_a_src + a_src->meta.wi;
41152   }
41153 
41154   uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
41155   if (coro_susp_point) {
41156     v_zlib_status = self->private_data.s_tell_me_more[0].v_zlib_status;
41157   }
41158   switch (coro_susp_point) {
41159     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41160 
41161     if (self->private_impl.f_call_sequence != 1) {
41162       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41163       goto exit;
41164     }
41165     if (self->private_impl.f_metadata_fourcc == 0) {
41166       status = wuffs_base__make_status(wuffs_base__error__no_more_information);
41167       goto exit;
41168     }
41169     while (true) {
41170       if (self->private_impl.f_metadata_flavor == 3) {
41171         while (true) {
41172           if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_y) {
41173             status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
41174             goto exit;
41175           } else if (a_minfo != NULL) {
41176             wuffs_base__more_information__set(a_minfo,
41177                 self->private_impl.f_metadata_flavor,
41178                 self->private_impl.f_metadata_fourcc,
41179                 self->private_impl.f_metadata_x,
41180                 self->private_impl.f_metadata_y,
41181                 self->private_impl.f_metadata_z);
41182           }
41183           if (self->private_impl.f_metadata_y >= self->private_impl.f_metadata_z) {
41184             goto label__goto_done__break;
41185           }
41186           self->private_impl.f_metadata_y = self->private_impl.f_metadata_z;
41187           status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
41188           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
41189         }
41190       }
41191       if (self->private_impl.f_metadata_is_zlib_compressed) {
41192         if (self->private_impl.f_zlib_is_dirty) {
41193           wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
41194               sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
41195           if (self->private_impl.f_ignore_checksum) {
41196             wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, 1, true);
41197           }
41198         }
41199         self->private_impl.f_zlib_is_dirty = true;
41200         self->private_impl.f_ztxt_hist_pos = 0;
41201       }
41202       label__loop__continue:;
41203       while (true) {
41204         if (a_minfo != NULL) {
41205           wuffs_base__more_information__set(a_minfo,
41206               self->private_impl.f_metadata_flavor,
41207               self->private_impl.f_metadata_fourcc,
41208               self->private_impl.f_metadata_x,
41209               self->private_impl.f_metadata_y,
41210               self->private_impl.f_metadata_z);
41211         }
41212         if (self->private_impl.f_metadata_flavor != 4) {
41213           goto label__loop__break;
41214         }
41215         if (self->private_impl.f_metadata_is_zlib_compressed) {
41216           if (self->private_impl.f_chunk_type == 1346585449) {
41217             {
41218               const uint8_t *o_0_io2_a_src = io2_a_src;
41219               wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
41220                   ((uint64_t)(self->private_impl.f_chunk_length)));
41221               if (a_src) {
41222                 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41223               }
41224               v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
41225               {
41226                 if (a_dst) {
41227                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
41228                 }
41229                 if (a_src) {
41230                   a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41231                 }
41232                 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());
41233                 v_zlib_status = t_0;
41234                 if (a_dst) {
41235                   iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
41236                 }
41237                 if (a_src) {
41238                   iop_a_src = a_src->data.ptr + a_src->meta.ri;
41239                 }
41240               }
41241               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))));
41242               io2_a_src = o_0_io2_a_src;
41243               if (a_src) {
41244                 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41245               }
41246             }
41247             if (wuffs_base__status__is_ok(&v_zlib_status)) {
41248               self->private_impl.f_metadata_is_zlib_compressed = false;
41249               goto label__loop__break;
41250             } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
41251               status = v_zlib_status;
41252               if (wuffs_base__status__is_error(&status)) {
41253                 goto exit;
41254               } else if (wuffs_base__status__is_suspension(&status)) {
41255                 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
41256                 goto exit;
41257               }
41258               goto ok;
41259             }
41260             status = v_zlib_status;
41261             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
41262           } else if (self->private_impl.f_chunk_type == 1951945833) {
41263             {
41264               const uint8_t *o_1_io2_a_src = io2_a_src;
41265               wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
41266                   ((uint64_t)(self->private_impl.f_chunk_length)));
41267               if (a_src) {
41268                 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41269               }
41270               v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
41271               {
41272                 if (a_dst) {
41273                   a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
41274                 }
41275                 if (a_src) {
41276                   a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41277                 }
41278                 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());
41279                 v_zlib_status = t_1;
41280                 if (a_dst) {
41281                   iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
41282                 }
41283                 if (a_src) {
41284                   iop_a_src = a_src->data.ptr + a_src->meta.ri;
41285                 }
41286               }
41287               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))));
41288               io2_a_src = o_1_io2_a_src;
41289               if (a_src) {
41290                 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41291               }
41292             }
41293             if (wuffs_base__status__is_ok(&v_zlib_status)) {
41294               self->private_impl.f_metadata_is_zlib_compressed = false;
41295               goto label__loop__break;
41296             } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
41297               status = v_zlib_status;
41298               if (wuffs_base__status__is_error(&status)) {
41299                 goto exit;
41300               } else if (wuffs_base__status__is_suspension(&status)) {
41301                 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
41302                 goto exit;
41303               }
41304               goto ok;
41305             }
41306             status = v_zlib_status;
41307             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
41308           } else if (self->private_impl.f_chunk_type == 1951945850) {
41309             if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) {
41310               {
41311                 wuffs_base__io_buffer* o_2_v_w = v_w;
41312                 uint8_t *o_2_iop_v_w = iop_v_w;
41313                 uint8_t *o_2_io0_v_w = io0_v_w;
41314                 uint8_t *o_2_io1_v_w = io1_v_w;
41315                 uint8_t *o_2_io2_v_w = io2_v_w;
41316                 v_w = wuffs_base__io_writer__set(
41317                     &u_w,
41318                     &iop_v_w,
41319                     &io0_v_w,
41320                     &io1_v_w,
41321                     &io2_v_w,
41322                     wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024),
41323                     self->private_impl.f_ztxt_hist_pos);
41324                 {
41325                   const uint8_t *o_3_io2_a_src = io2_a_src;
41326                   wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
41327                       ((uint64_t)(self->private_impl.f_chunk_length)));
41328                   if (a_src) {
41329                     a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41330                   }
41331                   v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
41332                   v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
41333                   {
41334                     u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
41335                     if (a_src) {
41336                       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41337                     }
41338                     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());
41339                     v_zlib_status = t_2;
41340                     iop_v_w = u_w.data.ptr + u_w.meta.wi;
41341                     if (a_src) {
41342                       iop_a_src = a_src->data.ptr + a_src->meta.ri;
41343                     }
41344                   }
41345                   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))));
41346                   v_num_written = wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)));
41347                   io2_a_src = o_3_io2_a_src;
41348                   if (a_src) {
41349                     a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41350                   }
41351                 }
41352                 v_w = o_2_v_w;
41353                 iop_v_w = o_2_iop_v_w;
41354                 io0_v_w = o_2_io0_v_w;
41355                 io1_v_w = o_2_io1_v_w;
41356                 io2_v_w = o_2_io2_v_w;
41357               }
41358               if (v_num_written > 1024) {
41359                 status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o);
41360                 goto exit;
41361               }
41362               self->private_impl.f_ztxt_ri = 0;
41363               self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written));
41364               wuffs_base__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written);
41365             }
41366             while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) {
41367               v_c2 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]];
41368               if (v_c2 == 0) {
41369                 status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
41370                 goto exit;
41371               } else if (v_c2 <= 127) {
41372                 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
41373                   status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41374                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
41375                   v_c2 = 0;
41376                   goto label__loop__continue;
41377                 }
41378                 self->private_impl.f_ztxt_ri += 1;
41379                 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
41380               } else {
41381                 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
41382                   status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41383                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
41384                   v_c2 = 0;
41385                   goto label__loop__continue;
41386                 }
41387                 self->private_impl.f_ztxt_ri += 1;
41388                 (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
41389               }
41390             }
41391             if (wuffs_base__status__is_ok(&v_zlib_status)) {
41392               self->private_impl.f_metadata_is_zlib_compressed = false;
41393               goto label__loop__break;
41394             } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
41395               status = v_zlib_status;
41396               if (wuffs_base__status__is_error(&status)) {
41397                 goto exit;
41398               } else if (wuffs_base__status__is_suspension(&status)) {
41399                 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
41400                 goto exit;
41401               }
41402               goto ok;
41403             } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) {
41404               status = v_zlib_status;
41405               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
41406             }
41407           } else {
41408             status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type);
41409             goto exit;
41410           }
41411         } else if ((self->private_impl.f_chunk_type == 1951945833) && (self->private_impl.f_metadata_fourcc == 1263947862)) {
41412           while (true) {
41413             if (self->private_impl.f_chunk_length <= 0) {
41414               goto label__loop__break;
41415             } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
41416               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41417               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
41418               goto label__loop__continue;
41419             } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
41420               status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41421               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
41422               goto label__loop__continue;
41423             }
41424             self->private_impl.f_chunk_length -= 1;
41425             v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
41426             iop_a_src += 1;
41427             (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c), iop_a_dst += 1);
41428           }
41429         } else {
41430           while (true) {
41431             if (self->private_impl.f_chunk_length <= 0) {
41432               if (self->private_impl.f_metadata_fourcc == 1263947851) {
41433                 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41434                 goto exit;
41435               }
41436               goto label__loop__break;
41437             } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
41438               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41439               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
41440               goto label__loop__continue;
41441             }
41442             v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
41443             if (v_c == 0) {
41444               self->private_impl.f_chunk_length -= 1;
41445               iop_a_src += 1;
41446               goto label__loop__break;
41447             }
41448             v_c2 = WUFFS_PNG__LATIN_1[v_c];
41449             if (v_c2 == 0) {
41450               status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
41451               goto exit;
41452             } else if (v_c2 <= 127) {
41453               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
41454                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41455                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
41456                 v_c2 = 0;
41457                 goto label__loop__continue;
41458               }
41459               self->private_impl.f_chunk_length -= 1;
41460               iop_a_src += 1;
41461               (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
41462             } else {
41463               if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
41464                 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41465                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
41466                 v_c2 = 0;
41467                 goto label__loop__continue;
41468               }
41469               self->private_impl.f_chunk_length -= 1;
41470               iop_a_src += 1;
41471               (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
41472             }
41473           }
41474         }
41475       }
41476       label__loop__break:;
41477       if (self->private_impl.f_metadata_fourcc == 1263947851) {
41478         self->private_impl.f_metadata_fourcc = 1263947862;
41479         if (self->private_impl.f_chunk_type == 1951945833) {
41480           if (self->private_impl.f_chunk_length <= 1) {
41481             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41482             goto exit;
41483           }
41484           self->private_impl.f_chunk_length -= 2;
41485           {
41486             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
41487             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41488               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41489               goto suspend;
41490             }
41491             uint8_t t_3 = *iop_a_src++;
41492             v_c = t_3;
41493           }
41494           if (v_c == 0) {
41495             self->private_impl.f_metadata_is_zlib_compressed = false;
41496           } else if (v_c == 1) {
41497             self->private_impl.f_metadata_is_zlib_compressed = true;
41498           } else {
41499             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41500             goto exit;
41501           }
41502           {
41503             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
41504             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41505               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41506               goto suspend;
41507             }
41508             uint8_t t_4 = *iop_a_src++;
41509             v_c = t_4;
41510           }
41511           if ((v_c != 0) && self->private_impl.f_metadata_is_zlib_compressed) {
41512             status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
41513             goto exit;
41514           }
41515           self->private_impl.f_metadata_fourcc -= 2;
41516           while (self->private_impl.f_metadata_fourcc != 1263947862) {
41517             self->private_impl.f_metadata_fourcc += 1;
41518             while (true) {
41519               if (self->private_impl.f_chunk_length <= 0) {
41520                 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41521                 goto exit;
41522               }
41523               self->private_impl.f_chunk_length -= 1;
41524               {
41525                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
41526                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41527                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41528                   goto suspend;
41529                 }
41530                 uint8_t t_5 = *iop_a_src++;
41531                 v_c = t_5;
41532               }
41533               if (v_c == 0) {
41534                 goto label__0__break;
41535               }
41536             }
41537             label__0__break:;
41538           }
41539         } else if (self->private_impl.f_chunk_type == 1951945850) {
41540           if (self->private_impl.f_chunk_length <= 0) {
41541             status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41542             goto exit;
41543           }
41544           self->private_impl.f_chunk_length -= 1;
41545           {
41546             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
41547             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41548               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41549               goto suspend;
41550             }
41551             uint8_t t_6 = *iop_a_src++;
41552             v_c = t_6;
41553           }
41554           if (v_c != 0) {
41555             status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
41556             goto exit;
41557           }
41558           self->private_impl.f_metadata_is_zlib_compressed = true;
41559         }
41560         self->private_impl.f_call_sequence = 2;
41561         status = wuffs_base__make_status(NULL);
41562         goto ok;
41563       }
41564       goto label__goto_done__break;
41565     }
41566     label__goto_done__break:;
41567     if (self->private_impl.f_chunk_length != 0) {
41568       status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41569       goto exit;
41570     }
41571     self->private_data.s_tell_me_more[0].scratch = 4;
41572     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
41573     if (self->private_data.s_tell_me_more[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
41574       self->private_data.s_tell_me_more[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
41575       iop_a_src = io2_a_src;
41576       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41577       goto suspend;
41578     }
41579     iop_a_src += self->private_data.s_tell_me_more[0].scratch;
41580     self->private_impl.f_metadata_flavor = 0;
41581     self->private_impl.f_metadata_fourcc = 0;
41582     self->private_impl.f_metadata_x = 0;
41583     self->private_impl.f_metadata_y = 0;
41584     self->private_impl.f_metadata_z = 0;
41585     self->private_impl.f_call_sequence = 2;
41586     status = wuffs_base__make_status(NULL);
41587     goto ok;
41588 
41589     ok:
41590     self->private_impl.p_tell_me_more[0] = 0;
41591     goto exit;
41592   }
41593 
41594   goto suspend;
41595   suspend:
41596   self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41597   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
41598   self->private_data.s_tell_me_more[0].v_zlib_status = v_zlib_status;
41599 
41600   goto exit;
41601   exit:
41602   if (a_dst) {
41603     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
41604   }
41605   if (a_src) {
41606     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41607   }
41608 
41609   if (wuffs_base__status__is_error(&status)) {
41610     self->private_impl.magic = WUFFS_BASE__DISABLED;
41611   }
41612   return status;
41613 }
41614 
41615 // -------- func png.decoder.workbuf_len
41616 
41617 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_png__decoder__workbuf_len(const wuffs_png__decoder * self)41618 wuffs_png__decoder__workbuf_len(
41619     const wuffs_png__decoder* self) {
41620   if (!self) {
41621     return wuffs_base__utility__empty_range_ii_u64();
41622   }
41623   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41624       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41625     return wuffs_base__utility__empty_range_ii_u64();
41626   }
41627 
41628   return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length);
41629 }
41630 
41631 // -------- func png.decoder.filter_and_swizzle
41632 
41633 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)41634 wuffs_png__decoder__filter_and_swizzle(
41635     wuffs_png__decoder* self,
41636     wuffs_base__pixel_buffer* a_dst,
41637     wuffs_base__slice_u8 a_workbuf) {
41638   return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf);
41639 }
41640 
41641 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)41642 wuffs_png__decoder__filter_and_swizzle__choosy_default(
41643     wuffs_png__decoder* self,
41644     wuffs_base__pixel_buffer* a_dst,
41645     wuffs_base__slice_u8 a_workbuf) {
41646   wuffs_base__pixel_format v_dst_pixfmt = {0};
41647   uint32_t v_dst_bits_per_pixel = 0;
41648   uint64_t v_dst_bytes_per_pixel = 0;
41649   uint64_t v_dst_bytes_per_row0 = 0;
41650   uint64_t v_dst_bytes_per_row1 = 0;
41651   wuffs_base__slice_u8 v_dst_palette = {0};
41652   wuffs_base__table_u8 v_tab = {0};
41653   uint32_t v_y = 0;
41654   wuffs_base__slice_u8 v_dst = {0};
41655   uint8_t v_filter = 0;
41656   wuffs_base__slice_u8 v_curr_row = {0};
41657   wuffs_base__slice_u8 v_prev_row = {0};
41658 
41659   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
41660   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
41661   if ((v_dst_bits_per_pixel & 7) != 0) {
41662     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
41663   }
41664   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
41665   v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel);
41666   v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
41667   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
41668   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41669   if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) {
41670     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41671         0,
41672         0,
41673         v_dst_bytes_per_row1,
41674         ((uint64_t)(v_tab.height)));
41675   }
41676   if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) {
41677     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41678         v_dst_bytes_per_row0,
41679         0,
41680         ((uint64_t)(v_tab.width)),
41681         ((uint64_t)(v_tab.height)));
41682   } else {
41683     v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41684         0,
41685         0,
41686         0,
41687         0);
41688   }
41689   v_y = self->private_impl.f_frame_rect_y0;
41690   while (v_y < self->private_impl.f_frame_rect_y1) {
41691     v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
41692     if (1 > ((uint64_t)(a_workbuf.len))) {
41693       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41694     }
41695     v_filter = a_workbuf.ptr[0];
41696     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1);
41697     if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
41698       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41699     }
41700     v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41701     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41702     if (v_filter == 0) {
41703     } else if (v_filter == 1) {
41704       wuffs_png__decoder__filter_1(self, v_curr_row);
41705     } else if (v_filter == 2) {
41706       wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
41707     } else if (v_filter == 3) {
41708       wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
41709     } else if (v_filter == 4) {
41710       wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
41711     } else {
41712       return wuffs_base__make_status(wuffs_png__error__bad_filter);
41713     }
41714     wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row);
41715     v_prev_row = v_curr_row;
41716     v_y += 1;
41717   }
41718   return wuffs_base__make_status(NULL);
41719 }
41720 
41721 // -------- func png.decoder.filter_and_swizzle_tricky
41722 
41723 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)41724 wuffs_png__decoder__filter_and_swizzle_tricky(
41725     wuffs_png__decoder* self,
41726     wuffs_base__pixel_buffer* a_dst,
41727     wuffs_base__slice_u8 a_workbuf) {
41728   wuffs_base__pixel_format v_dst_pixfmt = {0};
41729   uint32_t v_dst_bits_per_pixel = 0;
41730   uint64_t v_dst_bytes_per_pixel = 0;
41731   uint64_t v_dst_bytes_per_row1 = 0;
41732   wuffs_base__slice_u8 v_dst_palette = {0};
41733   wuffs_base__table_u8 v_tab = {0};
41734   uint64_t v_src_bytes_per_pixel = 0;
41735   uint32_t v_x = 0;
41736   uint32_t v_y = 0;
41737   uint64_t v_i = 0;
41738   wuffs_base__slice_u8 v_dst = {0};
41739   uint8_t v_filter = 0;
41740   wuffs_base__slice_u8 v_s = {0};
41741   wuffs_base__slice_u8 v_curr_row = {0};
41742   wuffs_base__slice_u8 v_prev_row = {0};
41743   uint8_t v_bits_unpacked[8] = {0};
41744   uint8_t v_bits_packed = 0;
41745   uint8_t v_packs_remaining = 0;
41746   uint8_t v_multiplier = 0;
41747   uint8_t v_shift = 0;
41748 
41749   v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
41750   v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
41751   if ((v_dst_bits_per_pixel & 7) != 0) {
41752     return wuffs_base__make_status(wuffs_base__error__unsupported_option);
41753   }
41754   v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
41755   v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
41756   v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
41757   v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41758   v_src_bytes_per_pixel = 1;
41759   if (self->private_impl.f_depth >= 8) {
41760     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))));
41761   }
41762   if (self->private_impl.f_chunk_type_array[0] == 73) {
41763     v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5]));
41764   } else {
41765     v_y = self->private_impl.f_frame_rect_y0;
41766   }
41767   while (v_y < self->private_impl.f_frame_rect_y1) {
41768     v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
41769     if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) {
41770       v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1);
41771     }
41772     if (1 > ((uint64_t)(a_workbuf.len))) {
41773       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41774     }
41775     v_filter = a_workbuf.ptr[0];
41776     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1);
41777     if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
41778       return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41779     }
41780     v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41781     a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41782     if (v_filter == 0) {
41783     } else if (v_filter == 1) {
41784       wuffs_png__decoder__filter_1(self, v_curr_row);
41785     } else if (v_filter == 2) {
41786       wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
41787     } else if (v_filter == 3) {
41788       wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
41789     } else if (v_filter == 4) {
41790       wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
41791     } else {
41792       return wuffs_base__make_status(wuffs_png__error__bad_filter);
41793     }
41794     v_s = v_curr_row;
41795     if (self->private_impl.f_chunk_type_array[0] == 73) {
41796       v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2]));
41797     } else {
41798       v_x = self->private_impl.f_frame_rect_x0;
41799     }
41800     if (self->private_impl.f_depth == 8) {
41801       while (v_x < self->private_impl.f_frame_rect_x1) {
41802         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41803         if (v_i <= ((uint64_t)(v_dst.len))) {
41804           if (self->private_impl.f_color_type == 4) {
41805             if (2 <= ((uint64_t)(v_s.len))) {
41806               v_bits_unpacked[0] = v_s.ptr[0];
41807               v_bits_unpacked[1] = v_s.ptr[0];
41808               v_bits_unpacked[2] = v_s.ptr[0];
41809               v_bits_unpacked[3] = v_s.ptr[1];
41810               v_s = wuffs_base__slice_u8__subslice_i(v_s, 2);
41811               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));
41812             }
41813           } else if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) != 0) {
41814             if (self->private_impl.f_color_type == 0) {
41815               if (1 <= ((uint64_t)(v_s.len))) {
41816                 v_bits_unpacked[0] = v_s.ptr[0];
41817                 v_bits_unpacked[1] = v_s.ptr[0];
41818                 v_bits_unpacked[2] = v_s.ptr[0];
41819                 v_bits_unpacked[3] = 255;
41820                 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1);
41821                 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41822                     (((uint32_t)(v_bits_unpacked[1])) << 8) |
41823                     (((uint32_t)(v_bits_unpacked[2])) << 16) |
41824                     (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41825                   v_bits_unpacked[0] = 0;
41826                   v_bits_unpacked[1] = 0;
41827                   v_bits_unpacked[2] = 0;
41828                   v_bits_unpacked[3] = 0;
41829                 }
41830                 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));
41831               }
41832             } else {
41833               if (3 <= ((uint64_t)(v_s.len))) {
41834                 v_bits_unpacked[0] = v_s.ptr[2];
41835                 v_bits_unpacked[1] = v_s.ptr[1];
41836                 v_bits_unpacked[2] = v_s.ptr[0];
41837                 v_bits_unpacked[3] = 255;
41838                 v_s = wuffs_base__slice_u8__subslice_i(v_s, 3);
41839                 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41840                     (((uint32_t)(v_bits_unpacked[1])) << 8) |
41841                     (((uint32_t)(v_bits_unpacked[2])) << 16) |
41842                     (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41843                   v_bits_unpacked[0] = 0;
41844                   v_bits_unpacked[1] = 0;
41845                   v_bits_unpacked[2] = 0;
41846                   v_bits_unpacked[3] = 0;
41847                 }
41848                 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));
41849               }
41850             }
41851           } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) {
41852             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));
41853             v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel);
41854           }
41855         }
41856         v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41857       }
41858     } else if (self->private_impl.f_depth < 8) {
41859       v_multiplier = 1;
41860       if (self->private_impl.f_color_type == 0) {
41861         v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth];
41862       }
41863       v_shift = ((8 - self->private_impl.f_depth) & 7);
41864       v_packs_remaining = 0;
41865       while (v_x < self->private_impl.f_frame_rect_x1) {
41866         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41867         if (v_i <= ((uint64_t)(v_dst.len))) {
41868           if ((v_packs_remaining == 0) && (1 <= ((uint64_t)(v_s.len)))) {
41869             v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth];
41870             v_bits_packed = v_s.ptr[0];
41871             v_s = wuffs_base__slice_u8__subslice_i(v_s, 1);
41872           }
41873           v_bits_unpacked[0] = ((uint8_t)((v_bits_packed >> v_shift) * v_multiplier));
41874           v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth));
41875           v_packs_remaining = ((uint8_t)(v_packs_remaining - 1));
41876           if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) != 0) {
41877             v_bits_unpacked[1] = v_bits_unpacked[0];
41878             v_bits_unpacked[2] = v_bits_unpacked[0];
41879             v_bits_unpacked[3] = 255;
41880             if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41881                 (((uint32_t)(v_bits_unpacked[1])) << 8) |
41882                 (((uint32_t)(v_bits_unpacked[2])) << 16) |
41883                 (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41884               v_bits_unpacked[0] = 0;
41885               v_bits_unpacked[1] = 0;
41886               v_bits_unpacked[2] = 0;
41887               v_bits_unpacked[3] = 0;
41888             }
41889             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));
41890           } else {
41891             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));
41892           }
41893         }
41894         v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41895       }
41896     } else {
41897       while (v_x < self->private_impl.f_frame_rect_x1) {
41898         v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41899         if (v_i <= ((uint64_t)(v_dst.len))) {
41900           if (self->private_impl.f_color_type == 0) {
41901             if (2 <= ((uint64_t)(v_s.len))) {
41902               v_bits_unpacked[0] = v_s.ptr[1];
41903               v_bits_unpacked[1] = v_s.ptr[0];
41904               v_bits_unpacked[2] = v_s.ptr[1];
41905               v_bits_unpacked[3] = v_s.ptr[0];
41906               v_bits_unpacked[4] = v_s.ptr[1];
41907               v_bits_unpacked[5] = v_s.ptr[0];
41908               v_bits_unpacked[6] = 255;
41909               v_bits_unpacked[7] = 255;
41910               v_s = wuffs_base__slice_u8__subslice_i(v_s, 2);
41911               if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0])) << 0) |
41912                   (((uint64_t)(v_bits_unpacked[1])) << 8) |
41913                   (((uint64_t)(v_bits_unpacked[2])) << 16) |
41914                   (((uint64_t)(v_bits_unpacked[3])) << 24) |
41915                   (((uint64_t)(v_bits_unpacked[4])) << 32) |
41916                   (((uint64_t)(v_bits_unpacked[5])) << 40) |
41917                   (((uint64_t)(v_bits_unpacked[6])) << 48) |
41918                   (((uint64_t)(v_bits_unpacked[7])) << 56))) {
41919                 v_bits_unpacked[0] = 0;
41920                 v_bits_unpacked[1] = 0;
41921                 v_bits_unpacked[2] = 0;
41922                 v_bits_unpacked[3] = 0;
41923                 v_bits_unpacked[4] = 0;
41924                 v_bits_unpacked[5] = 0;
41925                 v_bits_unpacked[6] = 0;
41926                 v_bits_unpacked[7] = 0;
41927               }
41928             }
41929           } else if (self->private_impl.f_color_type == 2) {
41930             if (6 <= ((uint64_t)(v_s.len))) {
41931               v_bits_unpacked[0] = v_s.ptr[5];
41932               v_bits_unpacked[1] = v_s.ptr[4];
41933               v_bits_unpacked[2] = v_s.ptr[3];
41934               v_bits_unpacked[3] = v_s.ptr[2];
41935               v_bits_unpacked[4] = v_s.ptr[1];
41936               v_bits_unpacked[5] = v_s.ptr[0];
41937               v_bits_unpacked[6] = 255;
41938               v_bits_unpacked[7] = 255;
41939               v_s = wuffs_base__slice_u8__subslice_i(v_s, 6);
41940               if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0])) << 0) |
41941                   (((uint64_t)(v_bits_unpacked[1])) << 8) |
41942                   (((uint64_t)(v_bits_unpacked[2])) << 16) |
41943                   (((uint64_t)(v_bits_unpacked[3])) << 24) |
41944                   (((uint64_t)(v_bits_unpacked[4])) << 32) |
41945                   (((uint64_t)(v_bits_unpacked[5])) << 40) |
41946                   (((uint64_t)(v_bits_unpacked[6])) << 48) |
41947                   (((uint64_t)(v_bits_unpacked[7])) << 56))) {
41948                 v_bits_unpacked[0] = 0;
41949                 v_bits_unpacked[1] = 0;
41950                 v_bits_unpacked[2] = 0;
41951                 v_bits_unpacked[3] = 0;
41952                 v_bits_unpacked[4] = 0;
41953                 v_bits_unpacked[5] = 0;
41954                 v_bits_unpacked[6] = 0;
41955                 v_bits_unpacked[7] = 0;
41956               }
41957             }
41958           } else if (self->private_impl.f_color_type == 4) {
41959             if (4 <= ((uint64_t)(v_s.len))) {
41960               v_bits_unpacked[0] = v_s.ptr[1];
41961               v_bits_unpacked[1] = v_s.ptr[0];
41962               v_bits_unpacked[2] = v_s.ptr[1];
41963               v_bits_unpacked[3] = v_s.ptr[0];
41964               v_bits_unpacked[4] = v_s.ptr[1];
41965               v_bits_unpacked[5] = v_s.ptr[0];
41966               v_bits_unpacked[6] = v_s.ptr[3];
41967               v_bits_unpacked[7] = v_s.ptr[2];
41968               v_s = wuffs_base__slice_u8__subslice_i(v_s, 4);
41969             }
41970           } else {
41971             if (8 <= ((uint64_t)(v_s.len))) {
41972               v_bits_unpacked[0] = v_s.ptr[5];
41973               v_bits_unpacked[1] = v_s.ptr[4];
41974               v_bits_unpacked[2] = v_s.ptr[3];
41975               v_bits_unpacked[3] = v_s.ptr[2];
41976               v_bits_unpacked[4] = v_s.ptr[1];
41977               v_bits_unpacked[5] = v_s.ptr[0];
41978               v_bits_unpacked[6] = v_s.ptr[7];
41979               v_bits_unpacked[7] = v_s.ptr[6];
41980               v_s = wuffs_base__slice_u8__subslice_i(v_s, 8);
41981             }
41982           }
41983           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));
41984         }
41985         v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41986       }
41987     }
41988     v_prev_row = v_curr_row;
41989     v_y += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3]);
41990   }
41991   return wuffs_base__make_status(NULL);
41992 }
41993 
41994 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
41995 
41996 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
41997 
41998 // ---------------- Status Codes Implementations
41999 
42000 const char wuffs_tga__error__bad_header[] = "#tga: bad header";
42001 const char wuffs_tga__error__bad_run_length_encoding[] = "#tga: bad run length encoding";
42002 const char wuffs_tga__error__unsupported_tga_file[] = "#tga: unsupported TGA file";
42003 
42004 // ---------------- Private Consts
42005 
42006 // ---------------- Private Initializer Prototypes
42007 
42008 // ---------------- Private Function Prototypes
42009 
42010 // ---------------- VTables
42011 
42012 const wuffs_base__image_decoder__func_ptrs
42013 wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder = {
42014   (wuffs_base__status(*)(void*,
42015       wuffs_base__pixel_buffer*,
42016       wuffs_base__io_buffer*,
42017       wuffs_base__pixel_blend,
42018       wuffs_base__slice_u8,
42019       wuffs_base__decode_frame_options*))(&wuffs_tga__decoder__decode_frame),
42020   (wuffs_base__status(*)(void*,
42021       wuffs_base__frame_config*,
42022       wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_frame_config),
42023   (wuffs_base__status(*)(void*,
42024       wuffs_base__image_config*,
42025       wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_image_config),
42026   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_tga__decoder__frame_dirty_rect),
42027   (uint32_t(*)(const void*))(&wuffs_tga__decoder__num_animation_loops),
42028   (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frame_configs),
42029   (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frames),
42030   (wuffs_base__status(*)(void*,
42031       uint64_t,
42032       uint64_t))(&wuffs_tga__decoder__restart_frame),
42033   (wuffs_base__empty_struct(*)(void*,
42034       uint32_t,
42035       bool))(&wuffs_tga__decoder__set_quirk_enabled),
42036   (wuffs_base__empty_struct(*)(void*,
42037       uint32_t,
42038       bool))(&wuffs_tga__decoder__set_report_metadata),
42039   (wuffs_base__status(*)(void*,
42040       wuffs_base__io_buffer*,
42041       wuffs_base__more_information*,
42042       wuffs_base__io_buffer*))(&wuffs_tga__decoder__tell_me_more),
42043   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_tga__decoder__workbuf_len),
42044 };
42045 
42046 // ---------------- Initializer Implementations
42047 
42048 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_tga__decoder__initialize(wuffs_tga__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)42049 wuffs_tga__decoder__initialize(
42050     wuffs_tga__decoder* self,
42051     size_t sizeof_star_self,
42052     uint64_t wuffs_version,
42053     uint32_t options){
42054   if (!self) {
42055     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42056   }
42057   if (sizeof(*self) != sizeof_star_self) {
42058     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
42059   }
42060   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
42061       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
42062     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
42063   }
42064 
42065   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
42066     // The whole point of this if-check is to detect an uninitialized *self.
42067     // We disable the warning on GCC. Clang-5.0 does not have this warning.
42068 #if !defined(__clang__) && defined(__GNUC__)
42069 #pragma GCC diagnostic push
42070 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
42071 #endif
42072     if (self->private_impl.magic != 0) {
42073       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
42074     }
42075 #if !defined(__clang__) && defined(__GNUC__)
42076 #pragma GCC diagnostic pop
42077 #endif
42078   } else {
42079     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
42080       memset(self, 0, sizeof(*self));
42081       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
42082     } else {
42083       memset(&(self->private_impl), 0, sizeof(self->private_impl));
42084     }
42085   }
42086 
42087   self->private_impl.magic = WUFFS_BASE__MAGIC;
42088   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
42089       wuffs_base__image_decoder__vtable_name;
42090   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
42091       (const void*)(&wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder);
42092   return wuffs_base__make_status(NULL);
42093 }
42094 
42095 wuffs_tga__decoder*
wuffs_tga__decoder__alloc()42096 wuffs_tga__decoder__alloc() {
42097   wuffs_tga__decoder* x =
42098       (wuffs_tga__decoder*)(calloc(sizeof(wuffs_tga__decoder), 1));
42099   if (!x) {
42100     return NULL;
42101   }
42102   if (wuffs_tga__decoder__initialize(
42103       x, sizeof(wuffs_tga__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
42104     free(x);
42105     return NULL;
42106   }
42107   return x;
42108 }
42109 
42110 size_t
sizeof__wuffs_tga__decoder()42111 sizeof__wuffs_tga__decoder() {
42112   return sizeof(wuffs_tga__decoder);
42113 }
42114 
42115 // ---------------- Function Implementations
42116 
42117 // -------- func tga.decoder.set_quirk_enabled
42118 
42119 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_tga__decoder__set_quirk_enabled(wuffs_tga__decoder * self,uint32_t a_quirk,bool a_enabled)42120 wuffs_tga__decoder__set_quirk_enabled(
42121     wuffs_tga__decoder* self,
42122     uint32_t a_quirk,
42123     bool a_enabled) {
42124   return wuffs_base__make_empty_struct();
42125 }
42126 
42127 // -------- func tga.decoder.decode_image_config
42128 
42129 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_image_config(wuffs_tga__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)42130 wuffs_tga__decoder__decode_image_config(
42131     wuffs_tga__decoder* self,
42132     wuffs_base__image_config* a_dst,
42133     wuffs_base__io_buffer* a_src) {
42134   if (!self) {
42135     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42136   }
42137   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42138     return wuffs_base__make_status(
42139         (self->private_impl.magic == WUFFS_BASE__DISABLED)
42140         ? wuffs_base__error__disabled_by_previous_error
42141         : wuffs_base__error__initialize_not_called);
42142   }
42143   if (!a_src) {
42144     self->private_impl.magic = WUFFS_BASE__DISABLED;
42145     return wuffs_base__make_status(wuffs_base__error__bad_argument);
42146   }
42147   if ((self->private_impl.active_coroutine != 0) &&
42148       (self->private_impl.active_coroutine != 1)) {
42149     self->private_impl.magic = WUFFS_BASE__DISABLED;
42150     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42151   }
42152   self->private_impl.active_coroutine = 0;
42153   wuffs_base__status status = wuffs_base__make_status(NULL);
42154 
42155   uint32_t v_c = 0;
42156   uint32_t v_c5 = 0;
42157   uint32_t v_i = 0;
42158 
42159   const uint8_t* iop_a_src = NULL;
42160   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42161   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42162   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42163   if (a_src) {
42164     io0_a_src = a_src->data.ptr;
42165     io1_a_src = io0_a_src + a_src->meta.ri;
42166     iop_a_src = io1_a_src;
42167     io2_a_src = io0_a_src + a_src->meta.wi;
42168   }
42169 
42170   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
42171   if (coro_susp_point) {
42172     v_i = self->private_data.s_decode_image_config[0].v_i;
42173   }
42174   switch (coro_susp_point) {
42175     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42176 
42177     if (self->private_impl.f_call_sequence != 0) {
42178       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
42179       goto exit;
42180     }
42181     {
42182       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42183       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42184         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42185         goto suspend;
42186       }
42187       uint8_t t_0 = *iop_a_src++;
42188       self->private_impl.f_header_id_length = t_0;
42189     }
42190     {
42191       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42192       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42193         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42194         goto suspend;
42195       }
42196       uint8_t t_1 = *iop_a_src++;
42197       self->private_impl.f_header_color_map_type = t_1;
42198     }
42199     if (self->private_impl.f_header_color_map_type > 1) {
42200       status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42201       goto exit;
42202     }
42203     {
42204       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42205       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42206         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42207         goto suspend;
42208       }
42209       uint8_t t_2 = *iop_a_src++;
42210       self->private_impl.f_header_image_type = t_2;
42211     }
42212     if ((self->private_impl.f_header_image_type == 1) ||
42213         (self->private_impl.f_header_image_type == 2) ||
42214         (self->private_impl.f_header_image_type == 3) ||
42215         (self->private_impl.f_header_image_type == 9) ||
42216         (self->private_impl.f_header_image_type == 10) ||
42217         (self->private_impl.f_header_image_type == 11)) {
42218     } else {
42219       status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42220       goto exit;
42221     }
42222     {
42223       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42224       uint16_t t_3;
42225       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42226         t_3 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
42227         iop_a_src += 2;
42228       } else {
42229         self->private_data.s_decode_image_config[0].scratch = 0;
42230         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42231         while (true) {
42232           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42233             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42234             goto suspend;
42235           }
42236           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42237           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
42238           *scratch <<= 8;
42239           *scratch >>= 8;
42240           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
42241           if (num_bits_3 == 8) {
42242             t_3 = ((uint16_t)(*scratch));
42243             break;
42244           }
42245           num_bits_3 += 8;
42246           *scratch |= ((uint64_t)(num_bits_3)) << 56;
42247         }
42248       }
42249       self->private_impl.f_header_color_map_first_entry_index = t_3;
42250     }
42251     {
42252       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42253       uint16_t t_4;
42254       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42255         t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
42256         iop_a_src += 2;
42257       } else {
42258         self->private_data.s_decode_image_config[0].scratch = 0;
42259         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
42260         while (true) {
42261           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42262             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42263             goto suspend;
42264           }
42265           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42266           uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
42267           *scratch <<= 8;
42268           *scratch >>= 8;
42269           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
42270           if (num_bits_4 == 8) {
42271             t_4 = ((uint16_t)(*scratch));
42272             break;
42273           }
42274           num_bits_4 += 8;
42275           *scratch |= ((uint64_t)(num_bits_4)) << 56;
42276         }
42277       }
42278       self->private_impl.f_header_color_map_length = t_4;
42279     }
42280     {
42281       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
42282       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42283         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42284         goto suspend;
42285       }
42286       uint8_t t_5 = *iop_a_src++;
42287       self->private_impl.f_header_color_map_entry_size = t_5;
42288     }
42289     if (self->private_impl.f_header_color_map_type != 0) {
42290       if ((self->private_impl.f_header_color_map_first_entry_index != 0) || (self->private_impl.f_header_color_map_length > 256)) {
42291         status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42292         goto exit;
42293       } else if ((self->private_impl.f_header_color_map_entry_size != 15) &&
42294           (self->private_impl.f_header_color_map_entry_size != 16) &&
42295           (self->private_impl.f_header_color_map_entry_size != 24) &&
42296           (self->private_impl.f_header_color_map_entry_size != 32)) {
42297         status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42298         goto exit;
42299       }
42300     } else {
42301       if ((self->private_impl.f_header_color_map_first_entry_index != 0) || (self->private_impl.f_header_color_map_length != 0) || (self->private_impl.f_header_color_map_entry_size != 0)) {
42302         status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42303         goto exit;
42304       }
42305     }
42306     self->private_data.s_decode_image_config[0].scratch = 4;
42307     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
42308     if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42309       self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42310       iop_a_src = io2_a_src;
42311       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42312       goto suspend;
42313     }
42314     iop_a_src += self->private_data.s_decode_image_config[0].scratch;
42315     {
42316       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
42317       uint32_t t_6;
42318       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42319         t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42320         iop_a_src += 2;
42321       } else {
42322         self->private_data.s_decode_image_config[0].scratch = 0;
42323         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
42324         while (true) {
42325           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42326             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42327             goto suspend;
42328           }
42329           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42330           uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
42331           *scratch <<= 8;
42332           *scratch >>= 8;
42333           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
42334           if (num_bits_6 == 8) {
42335             t_6 = ((uint32_t)(*scratch));
42336             break;
42337           }
42338           num_bits_6 += 8;
42339           *scratch |= ((uint64_t)(num_bits_6)) << 56;
42340         }
42341       }
42342       self->private_impl.f_width = t_6;
42343     }
42344     {
42345       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
42346       uint32_t t_7;
42347       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42348         t_7 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42349         iop_a_src += 2;
42350       } else {
42351         self->private_data.s_decode_image_config[0].scratch = 0;
42352         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
42353         while (true) {
42354           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42355             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42356             goto suspend;
42357           }
42358           uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42359           uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
42360           *scratch <<= 8;
42361           *scratch >>= 8;
42362           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
42363           if (num_bits_7 == 8) {
42364             t_7 = ((uint32_t)(*scratch));
42365             break;
42366           }
42367           num_bits_7 += 8;
42368           *scratch |= ((uint64_t)(num_bits_7)) << 56;
42369         }
42370       }
42371       self->private_impl.f_height = t_7;
42372     }
42373     {
42374       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
42375       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42376         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42377         goto suspend;
42378       }
42379       uint8_t t_8 = *iop_a_src++;
42380       self->private_impl.f_header_pixel_depth = t_8;
42381     }
42382     if ((self->private_impl.f_header_pixel_depth != 1) &&
42383         (self->private_impl.f_header_pixel_depth != 8) &&
42384         (self->private_impl.f_header_pixel_depth != 15) &&
42385         (self->private_impl.f_header_pixel_depth != 16) &&
42386         (self->private_impl.f_header_pixel_depth != 24) &&
42387         (self->private_impl.f_header_pixel_depth != 32)) {
42388       status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42389       goto exit;
42390     }
42391     if ((self->private_impl.f_header_image_type | 8) == 9) {
42392       self->private_impl.f_scratch_bytes_per_pixel = 1;
42393       self->private_impl.f_src_bytes_per_pixel = 1;
42394       self->private_impl.f_src_pixfmt = 2164523016;
42395       self->private_impl.f_opaque = ((self->private_impl.f_header_color_map_entry_size == 15) || (self->private_impl.f_header_color_map_entry_size == 24));
42396     } else if ((self->private_impl.f_header_image_type | 8) == 10) {
42397       if ((self->private_impl.f_header_pixel_depth == 15) || (self->private_impl.f_header_pixel_depth == 16)) {
42398         self->private_impl.f_scratch_bytes_per_pixel = 4;
42399         self->private_impl.f_src_bytes_per_pixel = 0;
42400         self->private_impl.f_src_pixfmt = 2164295816;
42401       } else if (self->private_impl.f_header_pixel_depth == 24) {
42402         self->private_impl.f_scratch_bytes_per_pixel = 3;
42403         self->private_impl.f_src_bytes_per_pixel = 3;
42404         self->private_impl.f_src_pixfmt = 2147485832;
42405         self->private_impl.f_opaque = true;
42406       } else if (self->private_impl.f_header_pixel_depth == 32) {
42407         self->private_impl.f_scratch_bytes_per_pixel = 4;
42408         self->private_impl.f_src_bytes_per_pixel = 4;
42409         self->private_impl.f_src_pixfmt = 2164295816;
42410       } else {
42411         status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42412         goto exit;
42413       }
42414     } else {
42415       if (self->private_impl.f_header_pixel_depth == 8) {
42416         self->private_impl.f_scratch_bytes_per_pixel = 1;
42417         self->private_impl.f_src_bytes_per_pixel = 1;
42418         self->private_impl.f_src_pixfmt = 536870920;
42419         self->private_impl.f_opaque = true;
42420       } else {
42421         status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42422         goto exit;
42423       }
42424     }
42425     {
42426       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
42427       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42428         status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42429         goto suspend;
42430       }
42431       uint8_t t_9 = *iop_a_src++;
42432       self->private_impl.f_header_image_descriptor = t_9;
42433     }
42434     if ((self->private_impl.f_header_image_descriptor & 16) != 0) {
42435       status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42436       goto exit;
42437     }
42438     self->private_data.s_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_header_id_length));
42439     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
42440     if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42441       self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42442       iop_a_src = io2_a_src;
42443       status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42444       goto suspend;
42445     }
42446     iop_a_src += self->private_data.s_decode_image_config[0].scratch;
42447     if (self->private_impl.f_header_color_map_type != 0) {
42448       while (v_i < ((uint32_t)(self->private_impl.f_header_color_map_length))) {
42449         if (self->private_impl.f_header_color_map_entry_size == 24) {
42450           {
42451             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
42452             uint32_t t_10;
42453             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
42454               t_10 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
42455               iop_a_src += 3;
42456             } else {
42457               self->private_data.s_decode_image_config[0].scratch = 0;
42458               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
42459               while (true) {
42460                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42461                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42462                   goto suspend;
42463                 }
42464                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42465                 uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
42466                 *scratch <<= 8;
42467                 *scratch >>= 8;
42468                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
42469                 if (num_bits_10 == 16) {
42470                   t_10 = ((uint32_t)(*scratch));
42471                   break;
42472                 }
42473                 num_bits_10 += 8;
42474                 *scratch |= ((uint64_t)(num_bits_10)) << 56;
42475               }
42476             }
42477             v_c = t_10;
42478           }
42479           self->private_data.f_src_palette[(((v_i & 255) * 4) + 0)] = ((uint8_t)(((v_c >> 0) & 255)));
42480           self->private_data.f_src_palette[(((v_i & 255) * 4) + 1)] = ((uint8_t)(((v_c >> 8) & 255)));
42481           self->private_data.f_src_palette[(((v_i & 255) * 4) + 2)] = ((uint8_t)(((v_c >> 16) & 255)));
42482           self->private_data.f_src_palette[(((v_i & 255) * 4) + 3)] = 255;
42483         } else if (self->private_impl.f_header_color_map_entry_size == 32) {
42484           {
42485             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
42486             uint32_t t_11;
42487             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
42488               t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
42489               iop_a_src += 4;
42490             } else {
42491               self->private_data.s_decode_image_config[0].scratch = 0;
42492               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
42493               while (true) {
42494                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42495                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42496                   goto suspend;
42497                 }
42498                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42499                 uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
42500                 *scratch <<= 8;
42501                 *scratch >>= 8;
42502                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
42503                 if (num_bits_11 == 24) {
42504                   t_11 = ((uint32_t)(*scratch));
42505                   break;
42506                 }
42507                 num_bits_11 += 8;
42508                 *scratch |= ((uint64_t)(num_bits_11)) << 56;
42509               }
42510             }
42511             v_c = t_11;
42512           }
42513           self->private_data.f_src_palette[(((v_i & 255) * 4) + 0)] = ((uint8_t)(((v_c >> 0) & 255)));
42514           self->private_data.f_src_palette[(((v_i & 255) * 4) + 1)] = ((uint8_t)(((v_c >> 8) & 255)));
42515           self->private_data.f_src_palette[(((v_i & 255) * 4) + 2)] = ((uint8_t)(((v_c >> 16) & 255)));
42516           self->private_data.f_src_palette[(((v_i & 255) * 4) + 3)] = ((uint8_t)(((v_c >> 24) & 255)));
42517         } else {
42518           {
42519             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
42520             uint32_t t_12;
42521             if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42522               t_12 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42523               iop_a_src += 2;
42524             } else {
42525               self->private_data.s_decode_image_config[0].scratch = 0;
42526               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
42527               while (true) {
42528                 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42529                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42530                   goto suspend;
42531                 }
42532                 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42533                 uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
42534                 *scratch <<= 8;
42535                 *scratch >>= 8;
42536                 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
42537                 if (num_bits_12 == 8) {
42538                   t_12 = ((uint32_t)(*scratch));
42539                   break;
42540                 }
42541                 num_bits_12 += 8;
42542                 *scratch |= ((uint64_t)(num_bits_12)) << 56;
42543               }
42544             }
42545             v_c = t_12;
42546           }
42547           v_c5 = (31 & (v_c >> 0));
42548           self->private_data.f_src_palette[(((v_i & 255) * 4) + 0)] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42549           v_c5 = (31 & (v_c >> 5));
42550           self->private_data.f_src_palette[(((v_i & 255) * 4) + 1)] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42551           v_c5 = (31 & (v_c >> 10));
42552           self->private_data.f_src_palette[(((v_i & 255) * 4) + 2)] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42553           self->private_data.f_src_palette[(((v_i & 255) * 4) + 3)] = 255;
42554         }
42555         v_i += 1;
42556       }
42557       while (v_i < 256) {
42558         self->private_data.f_src_palette[((v_i * 4) + 0)] = 0;
42559         self->private_data.f_src_palette[((v_i * 4) + 1)] = 0;
42560         self->private_data.f_src_palette[((v_i * 4) + 2)] = 0;
42561         self->private_data.f_src_palette[((v_i * 4) + 3)] = 255;
42562         v_i += 1;
42563       }
42564     }
42565     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)));
42566     if (a_dst != NULL) {
42567       wuffs_base__image_config__set(
42568           a_dst,
42569           self->private_impl.f_src_pixfmt,
42570           0,
42571           self->private_impl.f_width,
42572           self->private_impl.f_height,
42573           self->private_impl.f_frame_config_io_position,
42574           self->private_impl.f_opaque);
42575     }
42576     self->private_impl.f_call_sequence = 3;
42577 
42578     goto ok;
42579     ok:
42580     self->private_impl.p_decode_image_config[0] = 0;
42581     goto exit;
42582   }
42583 
42584   goto suspend;
42585   suspend:
42586   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42587   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
42588   self->private_data.s_decode_image_config[0].v_i = v_i;
42589 
42590   goto exit;
42591   exit:
42592   if (a_src) {
42593     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42594   }
42595 
42596   if (wuffs_base__status__is_error(&status)) {
42597     self->private_impl.magic = WUFFS_BASE__DISABLED;
42598   }
42599   return status;
42600 }
42601 
42602 // -------- func tga.decoder.decode_frame_config
42603 
42604 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_frame_config(wuffs_tga__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)42605 wuffs_tga__decoder__decode_frame_config(
42606     wuffs_tga__decoder* self,
42607     wuffs_base__frame_config* a_dst,
42608     wuffs_base__io_buffer* a_src) {
42609   if (!self) {
42610     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42611   }
42612   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42613     return wuffs_base__make_status(
42614         (self->private_impl.magic == WUFFS_BASE__DISABLED)
42615         ? wuffs_base__error__disabled_by_previous_error
42616         : wuffs_base__error__initialize_not_called);
42617   }
42618   if (!a_src) {
42619     self->private_impl.magic = WUFFS_BASE__DISABLED;
42620     return wuffs_base__make_status(wuffs_base__error__bad_argument);
42621   }
42622   if ((self->private_impl.active_coroutine != 0) &&
42623       (self->private_impl.active_coroutine != 2)) {
42624     self->private_impl.magic = WUFFS_BASE__DISABLED;
42625     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42626   }
42627   self->private_impl.active_coroutine = 0;
42628   wuffs_base__status status = wuffs_base__make_status(NULL);
42629 
42630   const uint8_t* iop_a_src = NULL;
42631   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42632   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42633   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42634   if (a_src) {
42635     io0_a_src = a_src->data.ptr;
42636     io1_a_src = io0_a_src + a_src->meta.ri;
42637     iop_a_src = io1_a_src;
42638     io2_a_src = io0_a_src + a_src->meta.wi;
42639   }
42640 
42641   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
42642   switch (coro_susp_point) {
42643     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42644 
42645     if (self->private_impl.f_call_sequence < 3) {
42646       if (a_src) {
42647         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42648       }
42649       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42650       status = wuffs_tga__decoder__decode_image_config(self, NULL, a_src);
42651       if (a_src) {
42652         iop_a_src = a_src->data.ptr + a_src->meta.ri;
42653       }
42654       if (status.repr) {
42655         goto suspend;
42656       }
42657     } else if (self->private_impl.f_call_sequence == 3) {
42658       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)))) {
42659         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
42660         goto exit;
42661       }
42662     } else if (self->private_impl.f_call_sequence == 4) {
42663       self->private_impl.f_call_sequence = 255;
42664       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
42665       goto ok;
42666     } else {
42667       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
42668       goto ok;
42669     }
42670     if (a_dst != NULL) {
42671       wuffs_base__frame_config__set(
42672           a_dst,
42673           wuffs_base__utility__make_rect_ie_u32(
42674           0,
42675           0,
42676           self->private_impl.f_width,
42677           self->private_impl.f_height),
42678           ((wuffs_base__flicks)(0)),
42679           0,
42680           self->private_impl.f_frame_config_io_position,
42681           0,
42682           self->private_impl.f_opaque,
42683           false,
42684           4278190080);
42685     }
42686     self->private_impl.f_call_sequence = 4;
42687 
42688     ok:
42689     self->private_impl.p_decode_frame_config[0] = 0;
42690     goto exit;
42691   }
42692 
42693   goto suspend;
42694   suspend:
42695   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42696   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
42697 
42698   goto exit;
42699   exit:
42700   if (a_src) {
42701     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42702   }
42703 
42704   if (wuffs_base__status__is_error(&status)) {
42705     self->private_impl.magic = WUFFS_BASE__DISABLED;
42706   }
42707   return status;
42708 }
42709 
42710 // -------- func tga.decoder.decode_frame
42711 
42712 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_frame(wuffs_tga__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)42713 wuffs_tga__decoder__decode_frame(
42714     wuffs_tga__decoder* self,
42715     wuffs_base__pixel_buffer* a_dst,
42716     wuffs_base__io_buffer* a_src,
42717     wuffs_base__pixel_blend a_blend,
42718     wuffs_base__slice_u8 a_workbuf,
42719     wuffs_base__decode_frame_options* a_opts) {
42720   if (!self) {
42721     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42722   }
42723   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42724     return wuffs_base__make_status(
42725         (self->private_impl.magic == WUFFS_BASE__DISABLED)
42726         ? wuffs_base__error__disabled_by_previous_error
42727         : wuffs_base__error__initialize_not_called);
42728   }
42729   if (!a_dst || !a_src) {
42730     self->private_impl.magic = WUFFS_BASE__DISABLED;
42731     return wuffs_base__make_status(wuffs_base__error__bad_argument);
42732   }
42733   if ((self->private_impl.active_coroutine != 0) &&
42734       (self->private_impl.active_coroutine != 3)) {
42735     self->private_impl.magic = WUFFS_BASE__DISABLED;
42736     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42737   }
42738   self->private_impl.active_coroutine = 0;
42739   wuffs_base__status status = wuffs_base__make_status(NULL);
42740 
42741   wuffs_base__status v_status = wuffs_base__make_status(NULL);
42742   wuffs_base__pixel_format v_dst_pixfmt = {0};
42743   uint32_t v_dst_bits_per_pixel = 0;
42744   uint64_t v_dst_bytes_per_pixel = 0;
42745   uint32_t v_dst_x = 0;
42746   uint32_t v_dst_y = 0;
42747   wuffs_base__table_u8 v_tab = {0};
42748   wuffs_base__slice_u8 v_dst_palette = {0};
42749   wuffs_base__slice_u8 v_dst = {0};
42750   uint64_t v_dst_start = 0;
42751   wuffs_base__slice_u8 v_src_palette = {0};
42752   uint64_t v_mark = 0;
42753   uint64_t v_num_pixels64 = 0;
42754   uint32_t v_num_pixels32 = 0;
42755   uint32_t v_lit_length = 0;
42756   uint32_t v_run_length = 0;
42757   uint64_t v_num_dst_bytes = 0;
42758   uint32_t v_num_src_bytes = 0;
42759   uint32_t v_c = 0;
42760   uint32_t v_c5 = 0;
42761 
42762   const uint8_t* iop_a_src = NULL;
42763   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42764   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42765   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42766   if (a_src) {
42767     io0_a_src = a_src->data.ptr;
42768     io1_a_src = io0_a_src + a_src->meta.ri;
42769     iop_a_src = io1_a_src;
42770     io2_a_src = io0_a_src + a_src->meta.wi;
42771   }
42772 
42773   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
42774   if (coro_susp_point) {
42775     v_dst_bytes_per_pixel = self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel;
42776     v_dst_x = self->private_data.s_decode_frame[0].v_dst_x;
42777     v_dst_y = self->private_data.s_decode_frame[0].v_dst_y;
42778     v_mark = self->private_data.s_decode_frame[0].v_mark;
42779     v_num_pixels32 = self->private_data.s_decode_frame[0].v_num_pixels32;
42780     v_lit_length = self->private_data.s_decode_frame[0].v_lit_length;
42781     v_run_length = self->private_data.s_decode_frame[0].v_run_length;
42782     v_num_dst_bytes = self->private_data.s_decode_frame[0].v_num_dst_bytes;
42783   }
42784   switch (coro_susp_point) {
42785     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42786 
42787     if (self->private_impl.f_call_sequence < 4) {
42788       if (a_src) {
42789         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42790       }
42791       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42792       status = wuffs_tga__decoder__decode_frame_config(self, NULL, a_src);
42793       if (a_src) {
42794         iop_a_src = a_src->data.ptr + a_src->meta.ri;
42795       }
42796       if (status.repr) {
42797         goto suspend;
42798       }
42799     } else if (self->private_impl.f_call_sequence == 4) {
42800     } else {
42801       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
42802       goto ok;
42803     }
42804     if (self->private_impl.f_header_color_map_type != 0) {
42805       v_src_palette = wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024);
42806     }
42807     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
42808         wuffs_base__pixel_buffer__pixel_format(a_dst),
42809         wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
42810         wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
42811         v_src_palette,
42812         a_blend);
42813     if ( ! wuffs_base__status__is_ok(&v_status)) {
42814       status = v_status;
42815       if (wuffs_base__status__is_error(&status)) {
42816         goto exit;
42817       } else if (wuffs_base__status__is_suspension(&status)) {
42818         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
42819         goto exit;
42820       }
42821       goto ok;
42822     }
42823     v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
42824     v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
42825     if ((v_dst_bits_per_pixel & 7) != 0) {
42826       status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
42827       goto exit;
42828     }
42829     v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
42830     if ((self->private_impl.f_header_image_descriptor & 32) == 0) {
42831       v_dst_y = ((uint32_t)(self->private_impl.f_height - 1));
42832     }
42833     if ((self->private_impl.f_header_image_type & 8) == 0) {
42834       v_lit_length = self->private_impl.f_width;
42835     }
42836     label__resume__continue:;
42837     while (true) {
42838       v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
42839       v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
42840       while (v_dst_y < self->private_impl.f_height) {
42841         v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
42842         v_dst_start = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
42843         if (v_dst_start <= ((uint64_t)(v_dst.len))) {
42844           v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_start);
42845         } else {
42846           v_dst = wuffs_base__utility__empty_slice_u8();
42847         }
42848         while (v_dst_x < self->private_impl.f_width) {
42849           if (self->private_impl.f_src_bytes_per_pixel > 0) {
42850             if (v_lit_length > 0) {
42851               v_mark = ((uint64_t)(iop_a_src - io0_a_src));
42852               v_num_pixels64 = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(self->private_impl.f_src_bytes_per_pixel)));
42853               v_num_pixels32 = ((uint32_t)(wuffs_base__u64__min(v_num_pixels64, ((uint64_t)(v_lit_length)))));
42854               v_num_dst_bytes = (((uint64_t)(v_num_pixels32)) * v_dst_bytes_per_pixel);
42855               v_num_src_bytes = (v_num_pixels32 * self->private_impl.f_src_bytes_per_pixel);
42856               self->private_data.s_decode_frame[0].scratch = v_num_src_bytes;
42857               WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42858               if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42859                 self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42860                 iop_a_src = io2_a_src;
42861                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42862                 goto suspend;
42863               }
42864               iop_a_src += self->private_data.s_decode_frame[0].scratch;
42865               wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
42866               if (v_num_dst_bytes <= ((uint64_t)(v_dst.len))) {
42867                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_num_dst_bytes);
42868               } else {
42869                 v_dst = wuffs_base__utility__empty_slice_u8();
42870               }
42871               v_dst_x += v_num_pixels32;
42872               v_lit_length = (((uint32_t)(v_lit_length - v_num_pixels32)) & 65535);
42873               if (v_lit_length > 0) {
42874                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42875                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
42876                 goto label__resume__continue;
42877               }
42878             } else if (v_run_length > 0) {
42879               v_run_length -= 1;
42880               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, 4), self->private_impl.f_scratch_bytes_per_pixel));
42881               if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
42882                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
42883               }
42884               v_dst_x += 1;
42885             } else {
42886               if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
42887                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42888                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
42889                 goto label__resume__continue;
42890               }
42891               if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128) {
42892                 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1);
42893                 iop_a_src += 1;
42894                 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
42895                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
42896                   goto exit;
42897                 }
42898               } else {
42899                 if (self->private_impl.f_src_bytes_per_pixel == 1) {
42900                   if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
42901                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42902                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
42903                     goto label__resume__continue;
42904                   }
42905                   v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42906                   iop_a_src += 1;
42907                   self->private_data.f_scratch[0] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42908                   iop_a_src += 1;
42909                 } else if (self->private_impl.f_src_bytes_per_pixel == 3) {
42910                   if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
42911                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42912                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
42913                     goto label__resume__continue;
42914                   }
42915                   v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42916                   iop_a_src += 1;
42917                   self->private_data.f_scratch[0] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42918                   iop_a_src += 1;
42919                   self->private_data.f_scratch[1] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42920                   iop_a_src += 1;
42921                   self->private_data.f_scratch[2] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42922                   iop_a_src += 1;
42923                 } else {
42924                   if (((uint64_t)(io2_a_src - iop_a_src)) < 5) {
42925                     status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42926                     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
42927                     goto label__resume__continue;
42928                   }
42929                   v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42930                   iop_a_src += 1;
42931                   self->private_data.f_scratch[0] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42932                   iop_a_src += 1;
42933                   self->private_data.f_scratch[1] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42934                   iop_a_src += 1;
42935                   self->private_data.f_scratch[2] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42936                   iop_a_src += 1;
42937                   self->private_data.f_scratch[3] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42938                   iop_a_src += 1;
42939                 }
42940                 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
42941                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
42942                   goto exit;
42943                 }
42944               }
42945             }
42946           } else {
42947             if (v_lit_length > 0) {
42948               if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
42949                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42950                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
42951                 goto label__resume__continue;
42952               }
42953               v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42954               iop_a_src += 2;
42955               v_c5 = (31 & (v_c >> 0));
42956               self->private_data.f_scratch[0] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42957               v_c5 = (31 & (v_c >> 5));
42958               self->private_data.f_scratch[1] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42959               v_c5 = (31 & (v_c >> 10));
42960               self->private_data.f_scratch[2] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42961               self->private_data.f_scratch[3] = 255;
42962               wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, 4));
42963               if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
42964                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
42965               }
42966               v_dst_x += 1;
42967               v_lit_length -= 1;
42968             } else if (v_run_length > 0) {
42969               v_run_length -= 1;
42970               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, 4), self->private_impl.f_scratch_bytes_per_pixel));
42971               if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
42972                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
42973               }
42974               v_dst_x += 1;
42975             } else {
42976               if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
42977                 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42978                 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
42979                 goto label__resume__continue;
42980               }
42981               if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128) {
42982                 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1);
42983                 iop_a_src += 1;
42984                 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
42985                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
42986                   goto exit;
42987                 }
42988               } else {
42989                 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
42990                   status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42991                   WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
42992                   goto label__resume__continue;
42993                 }
42994                 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42995                 iop_a_src += 1;
42996                 v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42997                 iop_a_src += 2;
42998                 v_c5 = (31 & (v_c >> 0));
42999                 self->private_data.f_scratch[0] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
43000                 v_c5 = (31 & (v_c >> 5));
43001                 self->private_data.f_scratch[1] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
43002                 v_c5 = (31 & (v_c >> 10));
43003                 self->private_data.f_scratch[2] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
43004                 self->private_data.f_scratch[3] = 255;
43005                 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
43006                   status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
43007                   goto exit;
43008                 }
43009               }
43010             }
43011           }
43012         }
43013         v_dst_x = 0;
43014         if ((self->private_impl.f_header_image_descriptor & 32) == 0) {
43015           v_dst_y -= 1;
43016         } else {
43017           v_dst_y += 1;
43018         }
43019         if ((self->private_impl.f_header_image_type & 8) == 0) {
43020           v_lit_length = self->private_impl.f_width;
43021         }
43022       }
43023       goto label__resume__break;
43024     }
43025     label__resume__break:;
43026     self->private_impl.f_call_sequence = 255;
43027 
43028     ok:
43029     self->private_impl.p_decode_frame[0] = 0;
43030     goto exit;
43031   }
43032 
43033   goto suspend;
43034   suspend:
43035   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43036   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
43037   self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
43038   self->private_data.s_decode_frame[0].v_dst_x = v_dst_x;
43039   self->private_data.s_decode_frame[0].v_dst_y = v_dst_y;
43040   self->private_data.s_decode_frame[0].v_mark = v_mark;
43041   self->private_data.s_decode_frame[0].v_num_pixels32 = v_num_pixels32;
43042   self->private_data.s_decode_frame[0].v_lit_length = v_lit_length;
43043   self->private_data.s_decode_frame[0].v_run_length = v_run_length;
43044   self->private_data.s_decode_frame[0].v_num_dst_bytes = v_num_dst_bytes;
43045 
43046   goto exit;
43047   exit:
43048   if (a_src) {
43049     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43050   }
43051 
43052   if (wuffs_base__status__is_error(&status)) {
43053     self->private_impl.magic = WUFFS_BASE__DISABLED;
43054   }
43055   return status;
43056 }
43057 
43058 // -------- func tga.decoder.frame_dirty_rect
43059 
43060 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_tga__decoder__frame_dirty_rect(const wuffs_tga__decoder * self)43061 wuffs_tga__decoder__frame_dirty_rect(
43062     const wuffs_tga__decoder* self) {
43063   if (!self) {
43064     return wuffs_base__utility__empty_rect_ie_u32();
43065   }
43066   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43067       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43068     return wuffs_base__utility__empty_rect_ie_u32();
43069   }
43070 
43071   return wuffs_base__utility__make_rect_ie_u32(
43072       0,
43073       0,
43074       self->private_impl.f_width,
43075       self->private_impl.f_height);
43076 }
43077 
43078 // -------- func tga.decoder.num_animation_loops
43079 
43080 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_tga__decoder__num_animation_loops(const wuffs_tga__decoder * self)43081 wuffs_tga__decoder__num_animation_loops(
43082     const wuffs_tga__decoder* self) {
43083   if (!self) {
43084     return 0;
43085   }
43086   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43087       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43088     return 0;
43089   }
43090 
43091   return 0;
43092 }
43093 
43094 // -------- func tga.decoder.num_decoded_frame_configs
43095 
43096 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__num_decoded_frame_configs(const wuffs_tga__decoder * self)43097 wuffs_tga__decoder__num_decoded_frame_configs(
43098     const wuffs_tga__decoder* self) {
43099   if (!self) {
43100     return 0;
43101   }
43102   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43103       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43104     return 0;
43105   }
43106 
43107   if (self->private_impl.f_call_sequence > 3) {
43108     return 1;
43109   }
43110   return 0;
43111 }
43112 
43113 // -------- func tga.decoder.num_decoded_frames
43114 
43115 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__num_decoded_frames(const wuffs_tga__decoder * self)43116 wuffs_tga__decoder__num_decoded_frames(
43117     const wuffs_tga__decoder* self) {
43118   if (!self) {
43119     return 0;
43120   }
43121   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43122       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43123     return 0;
43124   }
43125 
43126   if (self->private_impl.f_call_sequence > 4) {
43127     return 1;
43128   }
43129   return 0;
43130 }
43131 
43132 // -------- func tga.decoder.restart_frame
43133 
43134 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__restart_frame(wuffs_tga__decoder * self,uint64_t a_index,uint64_t a_io_position)43135 wuffs_tga__decoder__restart_frame(
43136     wuffs_tga__decoder* self,
43137     uint64_t a_index,
43138     uint64_t a_io_position) {
43139   if (!self) {
43140     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43141   }
43142   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43143     return wuffs_base__make_status(
43144         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43145         ? wuffs_base__error__disabled_by_previous_error
43146         : wuffs_base__error__initialize_not_called);
43147   }
43148 
43149   if (self->private_impl.f_call_sequence < 3) {
43150     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
43151   }
43152   if (a_index != 0) {
43153     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43154   }
43155   self->private_impl.f_call_sequence = 3;
43156   self->private_impl.f_frame_config_io_position = a_io_position;
43157   return wuffs_base__make_status(NULL);
43158 }
43159 
43160 // -------- func tga.decoder.set_report_metadata
43161 
43162 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_tga__decoder__set_report_metadata(wuffs_tga__decoder * self,uint32_t a_fourcc,bool a_report)43163 wuffs_tga__decoder__set_report_metadata(
43164     wuffs_tga__decoder* self,
43165     uint32_t a_fourcc,
43166     bool a_report) {
43167   return wuffs_base__make_empty_struct();
43168 }
43169 
43170 // -------- func tga.decoder.tell_me_more
43171 
43172 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__tell_me_more(wuffs_tga__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)43173 wuffs_tga__decoder__tell_me_more(
43174     wuffs_tga__decoder* self,
43175     wuffs_base__io_buffer* a_dst,
43176     wuffs_base__more_information* a_minfo,
43177     wuffs_base__io_buffer* a_src) {
43178   if (!self) {
43179     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43180   }
43181   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43182     return wuffs_base__make_status(
43183         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43184         ? wuffs_base__error__disabled_by_previous_error
43185         : wuffs_base__error__initialize_not_called);
43186   }
43187   if (!a_dst || !a_src) {
43188     self->private_impl.magic = WUFFS_BASE__DISABLED;
43189     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43190   }
43191   if ((self->private_impl.active_coroutine != 0) &&
43192       (self->private_impl.active_coroutine != 4)) {
43193     self->private_impl.magic = WUFFS_BASE__DISABLED;
43194     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43195   }
43196   self->private_impl.active_coroutine = 0;
43197   wuffs_base__status status = wuffs_base__make_status(NULL);
43198 
43199   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
43200   goto exit;
43201 
43202   goto ok;
43203   ok:
43204   goto exit;
43205   exit:
43206   if (wuffs_base__status__is_error(&status)) {
43207     self->private_impl.magic = WUFFS_BASE__DISABLED;
43208   }
43209   return status;
43210 }
43211 
43212 // -------- func tga.decoder.workbuf_len
43213 
43214 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_tga__decoder__workbuf_len(const wuffs_tga__decoder * self)43215 wuffs_tga__decoder__workbuf_len(
43216     const wuffs_tga__decoder* self) {
43217   if (!self) {
43218     return wuffs_base__utility__empty_range_ii_u64();
43219   }
43220   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43221       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43222     return wuffs_base__utility__empty_range_ii_u64();
43223   }
43224 
43225   return wuffs_base__utility__make_range_ii_u64(0, 0);
43226 }
43227 
43228 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
43229 
43230 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
43231 
43232 // ---------------- Status Codes Implementations
43233 
43234 const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header";
43235 
43236 // ---------------- Private Consts
43237 
43238 // ---------------- Private Initializer Prototypes
43239 
43240 // ---------------- Private Function Prototypes
43241 
43242 // ---------------- VTables
43243 
43244 const wuffs_base__image_decoder__func_ptrs
43245 wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
43246   (wuffs_base__status(*)(void*,
43247       wuffs_base__pixel_buffer*,
43248       wuffs_base__io_buffer*,
43249       wuffs_base__pixel_blend,
43250       wuffs_base__slice_u8,
43251       wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame),
43252   (wuffs_base__status(*)(void*,
43253       wuffs_base__frame_config*,
43254       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config),
43255   (wuffs_base__status(*)(void*,
43256       wuffs_base__image_config*,
43257       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config),
43258   (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect),
43259   (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops),
43260   (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs),
43261   (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames),
43262   (wuffs_base__status(*)(void*,
43263       uint64_t,
43264       uint64_t))(&wuffs_wbmp__decoder__restart_frame),
43265   (wuffs_base__empty_struct(*)(void*,
43266       uint32_t,
43267       bool))(&wuffs_wbmp__decoder__set_quirk_enabled),
43268   (wuffs_base__empty_struct(*)(void*,
43269       uint32_t,
43270       bool))(&wuffs_wbmp__decoder__set_report_metadata),
43271   (wuffs_base__status(*)(void*,
43272       wuffs_base__io_buffer*,
43273       wuffs_base__more_information*,
43274       wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more),
43275   (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len),
43276 };
43277 
43278 // ---------------- Initializer Implementations
43279 
43280 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)43281 wuffs_wbmp__decoder__initialize(
43282     wuffs_wbmp__decoder* self,
43283     size_t sizeof_star_self,
43284     uint64_t wuffs_version,
43285     uint32_t options){
43286   if (!self) {
43287     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43288   }
43289   if (sizeof(*self) != sizeof_star_self) {
43290     return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
43291   }
43292   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
43293       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
43294     return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
43295   }
43296 
43297   if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
43298     // The whole point of this if-check is to detect an uninitialized *self.
43299     // We disable the warning on GCC. Clang-5.0 does not have this warning.
43300 #if !defined(__clang__) && defined(__GNUC__)
43301 #pragma GCC diagnostic push
43302 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
43303 #endif
43304     if (self->private_impl.magic != 0) {
43305       return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
43306     }
43307 #if !defined(__clang__) && defined(__GNUC__)
43308 #pragma GCC diagnostic pop
43309 #endif
43310   } else {
43311     if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
43312       memset(self, 0, sizeof(*self));
43313       options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
43314     } else {
43315       memset(&(self->private_impl), 0, sizeof(self->private_impl));
43316     }
43317   }
43318 
43319   self->private_impl.magic = WUFFS_BASE__MAGIC;
43320   self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
43321       wuffs_base__image_decoder__vtable_name;
43322   self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
43323       (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
43324   return wuffs_base__make_status(NULL);
43325 }
43326 
43327 wuffs_wbmp__decoder*
wuffs_wbmp__decoder__alloc()43328 wuffs_wbmp__decoder__alloc() {
43329   wuffs_wbmp__decoder* x =
43330       (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
43331   if (!x) {
43332     return NULL;
43333   }
43334   if (wuffs_wbmp__decoder__initialize(
43335       x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
43336     free(x);
43337     return NULL;
43338   }
43339   return x;
43340 }
43341 
43342 size_t
sizeof__wuffs_wbmp__decoder()43343 sizeof__wuffs_wbmp__decoder() {
43344   return sizeof(wuffs_wbmp__decoder);
43345 }
43346 
43347 // ---------------- Function Implementations
43348 
43349 // -------- func wbmp.decoder.set_quirk_enabled
43350 
43351 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)43352 wuffs_wbmp__decoder__set_quirk_enabled(
43353     wuffs_wbmp__decoder* self,
43354     uint32_t a_quirk,
43355     bool a_enabled) {
43356   return wuffs_base__make_empty_struct();
43357 }
43358 
43359 // -------- func wbmp.decoder.decode_image_config
43360 
43361 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)43362 wuffs_wbmp__decoder__decode_image_config(
43363     wuffs_wbmp__decoder* self,
43364     wuffs_base__image_config* a_dst,
43365     wuffs_base__io_buffer* a_src) {
43366   if (!self) {
43367     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43368   }
43369   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43370     return wuffs_base__make_status(
43371         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43372         ? wuffs_base__error__disabled_by_previous_error
43373         : wuffs_base__error__initialize_not_called);
43374   }
43375   if (!a_src) {
43376     self->private_impl.magic = WUFFS_BASE__DISABLED;
43377     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43378   }
43379   if ((self->private_impl.active_coroutine != 0) &&
43380       (self->private_impl.active_coroutine != 1)) {
43381     self->private_impl.magic = WUFFS_BASE__DISABLED;
43382     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43383   }
43384   self->private_impl.active_coroutine = 0;
43385   wuffs_base__status status = wuffs_base__make_status(NULL);
43386 
43387   uint8_t v_c = 0;
43388   uint32_t v_i = 0;
43389   uint32_t v_x32 = 0;
43390   uint64_t v_x64 = 0;
43391 
43392   const uint8_t* iop_a_src = NULL;
43393   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43394   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43395   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43396   if (a_src) {
43397     io0_a_src = a_src->data.ptr;
43398     io1_a_src = io0_a_src + a_src->meta.ri;
43399     iop_a_src = io1_a_src;
43400     io2_a_src = io0_a_src + a_src->meta.wi;
43401   }
43402 
43403   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
43404   if (coro_susp_point) {
43405     v_i = self->private_data.s_decode_image_config[0].v_i;
43406     v_x32 = self->private_data.s_decode_image_config[0].v_x32;
43407   }
43408   switch (coro_susp_point) {
43409     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43410 
43411     if (self->private_impl.f_call_sequence != 0) {
43412       status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
43413       goto exit;
43414     }
43415     v_i = 0;
43416     while (v_i < 2) {
43417       {
43418         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43419         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43420           status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43421           goto suspend;
43422         }
43423         uint8_t t_0 = *iop_a_src++;
43424         v_c = t_0;
43425       }
43426       if (v_c != 0) {
43427         status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
43428         goto exit;
43429       }
43430       v_i += 1;
43431     }
43432     v_i = 0;
43433     while (v_i < 2) {
43434       v_x32 = 0;
43435       while (true) {
43436         {
43437           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
43438           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43439             status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43440             goto suspend;
43441           }
43442           uint8_t t_1 = *iop_a_src++;
43443           v_c = t_1;
43444         }
43445         v_x32 |= ((uint32_t)((v_c & 127)));
43446         if ((v_c >> 7) == 0) {
43447           goto label__0__break;
43448         }
43449         v_x64 = (((uint64_t)(v_x32)) << 7);
43450         if (v_x64 > 4294967295) {
43451           status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
43452           goto exit;
43453         }
43454         v_x32 = ((uint32_t)(v_x64));
43455       }
43456       label__0__break:;
43457       if (v_i == 0) {
43458         self->private_impl.f_width = v_x32;
43459       } else {
43460         self->private_impl.f_height = v_x32;
43461       }
43462       v_i += 1;
43463     }
43464     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)));
43465     if (a_dst != NULL) {
43466       wuffs_base__image_config__set(
43467           a_dst,
43468           2198077448,
43469           0,
43470           self->private_impl.f_width,
43471           self->private_impl.f_height,
43472           self->private_impl.f_frame_config_io_position,
43473           true);
43474     }
43475     self->private_impl.f_call_sequence = 3;
43476 
43477     goto ok;
43478     ok:
43479     self->private_impl.p_decode_image_config[0] = 0;
43480     goto exit;
43481   }
43482 
43483   goto suspend;
43484   suspend:
43485   self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43486   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
43487   self->private_data.s_decode_image_config[0].v_i = v_i;
43488   self->private_data.s_decode_image_config[0].v_x32 = v_x32;
43489 
43490   goto exit;
43491   exit:
43492   if (a_src) {
43493     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43494   }
43495 
43496   if (wuffs_base__status__is_error(&status)) {
43497     self->private_impl.magic = WUFFS_BASE__DISABLED;
43498   }
43499   return status;
43500 }
43501 
43502 // -------- func wbmp.decoder.decode_frame_config
43503 
43504 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)43505 wuffs_wbmp__decoder__decode_frame_config(
43506     wuffs_wbmp__decoder* self,
43507     wuffs_base__frame_config* a_dst,
43508     wuffs_base__io_buffer* a_src) {
43509   if (!self) {
43510     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43511   }
43512   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43513     return wuffs_base__make_status(
43514         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43515         ? wuffs_base__error__disabled_by_previous_error
43516         : wuffs_base__error__initialize_not_called);
43517   }
43518   if (!a_src) {
43519     self->private_impl.magic = WUFFS_BASE__DISABLED;
43520     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43521   }
43522   if ((self->private_impl.active_coroutine != 0) &&
43523       (self->private_impl.active_coroutine != 2)) {
43524     self->private_impl.magic = WUFFS_BASE__DISABLED;
43525     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43526   }
43527   self->private_impl.active_coroutine = 0;
43528   wuffs_base__status status = wuffs_base__make_status(NULL);
43529 
43530   const uint8_t* iop_a_src = NULL;
43531   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43532   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43533   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43534   if (a_src) {
43535     io0_a_src = a_src->data.ptr;
43536     io1_a_src = io0_a_src + a_src->meta.ri;
43537     iop_a_src = io1_a_src;
43538     io2_a_src = io0_a_src + a_src->meta.wi;
43539   }
43540 
43541   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
43542   switch (coro_susp_point) {
43543     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43544 
43545     if (self->private_impl.f_call_sequence < 3) {
43546       if (a_src) {
43547         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43548       }
43549       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43550       status = wuffs_wbmp__decoder__decode_image_config(self, NULL, a_src);
43551       if (a_src) {
43552         iop_a_src = a_src->data.ptr + a_src->meta.ri;
43553       }
43554       if (status.repr) {
43555         goto suspend;
43556       }
43557     } else if (self->private_impl.f_call_sequence == 3) {
43558       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)))) {
43559         status = wuffs_base__make_status(wuffs_base__error__bad_restart);
43560         goto exit;
43561       }
43562     } else if (self->private_impl.f_call_sequence == 4) {
43563       self->private_impl.f_call_sequence = 255;
43564       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43565       goto ok;
43566     } else {
43567       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43568       goto ok;
43569     }
43570     if (a_dst != NULL) {
43571       wuffs_base__frame_config__set(
43572           a_dst,
43573           wuffs_base__utility__make_rect_ie_u32(
43574           0,
43575           0,
43576           self->private_impl.f_width,
43577           self->private_impl.f_height),
43578           ((wuffs_base__flicks)(0)),
43579           0,
43580           self->private_impl.f_frame_config_io_position,
43581           0,
43582           true,
43583           false,
43584           4278190080);
43585     }
43586     self->private_impl.f_call_sequence = 4;
43587 
43588     ok:
43589     self->private_impl.p_decode_frame_config[0] = 0;
43590     goto exit;
43591   }
43592 
43593   goto suspend;
43594   suspend:
43595   self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43596   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
43597 
43598   goto exit;
43599   exit:
43600   if (a_src) {
43601     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43602   }
43603 
43604   if (wuffs_base__status__is_error(&status)) {
43605     self->private_impl.magic = WUFFS_BASE__DISABLED;
43606   }
43607   return status;
43608 }
43609 
43610 // -------- func wbmp.decoder.decode_frame
43611 
43612 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)43613 wuffs_wbmp__decoder__decode_frame(
43614     wuffs_wbmp__decoder* self,
43615     wuffs_base__pixel_buffer* a_dst,
43616     wuffs_base__io_buffer* a_src,
43617     wuffs_base__pixel_blend a_blend,
43618     wuffs_base__slice_u8 a_workbuf,
43619     wuffs_base__decode_frame_options* a_opts) {
43620   if (!self) {
43621     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43622   }
43623   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43624     return wuffs_base__make_status(
43625         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43626         ? wuffs_base__error__disabled_by_previous_error
43627         : wuffs_base__error__initialize_not_called);
43628   }
43629   if (!a_dst || !a_src) {
43630     self->private_impl.magic = WUFFS_BASE__DISABLED;
43631     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43632   }
43633   if ((self->private_impl.active_coroutine != 0) &&
43634       (self->private_impl.active_coroutine != 3)) {
43635     self->private_impl.magic = WUFFS_BASE__DISABLED;
43636     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43637   }
43638   self->private_impl.active_coroutine = 0;
43639   wuffs_base__status status = wuffs_base__make_status(NULL);
43640 
43641   wuffs_base__status v_status = wuffs_base__make_status(NULL);
43642   wuffs_base__pixel_format v_dst_pixfmt = {0};
43643   uint32_t v_dst_bits_per_pixel = 0;
43644   uint64_t v_dst_bytes_per_pixel = 0;
43645   uint64_t v_dst_x_in_bytes = 0;
43646   uint32_t v_dst_x = 0;
43647   uint32_t v_dst_y = 0;
43648   wuffs_base__table_u8 v_tab = {0};
43649   wuffs_base__slice_u8 v_dst = {0};
43650   uint8_t v_src[1] = {0};
43651   uint8_t v_c = 0;
43652 
43653   const uint8_t* iop_a_src = NULL;
43654   const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43655   const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43656   const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43657   if (a_src) {
43658     io0_a_src = a_src->data.ptr;
43659     io1_a_src = io0_a_src + a_src->meta.ri;
43660     iop_a_src = io1_a_src;
43661     io2_a_src = io0_a_src + a_src->meta.wi;
43662   }
43663 
43664   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
43665   if (coro_susp_point) {
43666     v_dst_bytes_per_pixel = self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel;
43667     v_dst_x = self->private_data.s_decode_frame[0].v_dst_x;
43668     v_dst_y = self->private_data.s_decode_frame[0].v_dst_y;
43669     memcpy(v_src, self->private_data.s_decode_frame[0].v_src, sizeof(v_src));
43670     v_c = self->private_data.s_decode_frame[0].v_c;
43671   }
43672   switch (coro_susp_point) {
43673     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43674 
43675     if (self->private_impl.f_call_sequence < 4) {
43676       if (a_src) {
43677         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43678       }
43679       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43680       status = wuffs_wbmp__decoder__decode_frame_config(self, NULL, a_src);
43681       if (a_src) {
43682         iop_a_src = a_src->data.ptr + a_src->meta.ri;
43683       }
43684       if (status.repr) {
43685         goto suspend;
43686       }
43687     } else if (self->private_impl.f_call_sequence == 4) {
43688     } else {
43689       status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43690       goto ok;
43691     }
43692     v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
43693         wuffs_base__pixel_buffer__pixel_format(a_dst),
43694         wuffs_base__pixel_buffer__palette(a_dst),
43695         wuffs_base__utility__make_pixel_format(536870920),
43696         wuffs_base__utility__empty_slice_u8(),
43697         a_blend);
43698     if ( ! wuffs_base__status__is_ok(&v_status)) {
43699       status = v_status;
43700       if (wuffs_base__status__is_error(&status)) {
43701         goto exit;
43702       } else if (wuffs_base__status__is_suspension(&status)) {
43703         status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
43704         goto exit;
43705       }
43706       goto ok;
43707     }
43708     v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
43709     v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
43710     if ((v_dst_bits_per_pixel & 7) != 0) {
43711       status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
43712       goto exit;
43713     }
43714     v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
43715     if (self->private_impl.f_width > 0) {
43716       v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
43717       while (v_dst_y < self->private_impl.f_height) {
43718         v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
43719         v_dst_x = 0;
43720         while (v_dst_x < self->private_impl.f_width) {
43721           if ((v_dst_x & 7) == 0) {
43722             while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
43723               status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43724               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
43725               v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
43726               v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
43727               v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
43728               if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) {
43729                 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes);
43730               }
43731             }
43732             v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
43733             iop_a_src += 1;
43734           }
43735           if ((v_c & 128) == 0) {
43736             v_src[0] = 0;
43737           } else {
43738             v_src[0] = 255;
43739           }
43740           v_c = ((uint8_t)(((((uint32_t)(v_c)) << 1) & 255)));
43741           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));
43742           if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
43743             v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
43744           }
43745           v_dst_x += 1;
43746         }
43747         v_dst_y += 1;
43748       }
43749     }
43750     self->private_impl.f_call_sequence = 255;
43751 
43752     ok:
43753     self->private_impl.p_decode_frame[0] = 0;
43754     goto exit;
43755   }
43756 
43757   goto suspend;
43758   suspend:
43759   self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43760   self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
43761   self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
43762   self->private_data.s_decode_frame[0].v_dst_x = v_dst_x;
43763   self->private_data.s_decode_frame[0].v_dst_y = v_dst_y;
43764   memcpy(self->private_data.s_decode_frame[0].v_src, v_src, sizeof(v_src));
43765   self->private_data.s_decode_frame[0].v_c = v_c;
43766 
43767   goto exit;
43768   exit:
43769   if (a_src) {
43770     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43771   }
43772 
43773   if (wuffs_base__status__is_error(&status)) {
43774     self->private_impl.magic = WUFFS_BASE__DISABLED;
43775   }
43776   return status;
43777 }
43778 
43779 // -------- func wbmp.decoder.frame_dirty_rect
43780 
43781 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_wbmp__decoder__frame_dirty_rect(const wuffs_wbmp__decoder * self)43782 wuffs_wbmp__decoder__frame_dirty_rect(
43783     const wuffs_wbmp__decoder* self) {
43784   if (!self) {
43785     return wuffs_base__utility__empty_rect_ie_u32();
43786   }
43787   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43788       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43789     return wuffs_base__utility__empty_rect_ie_u32();
43790   }
43791 
43792   return wuffs_base__utility__make_rect_ie_u32(
43793       0,
43794       0,
43795       self->private_impl.f_width,
43796       self->private_impl.f_height);
43797 }
43798 
43799 // -------- func wbmp.decoder.num_animation_loops
43800 
43801 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_wbmp__decoder__num_animation_loops(const wuffs_wbmp__decoder * self)43802 wuffs_wbmp__decoder__num_animation_loops(
43803     const wuffs_wbmp__decoder* self) {
43804   if (!self) {
43805     return 0;
43806   }
43807   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43808       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43809     return 0;
43810   }
43811 
43812   return 0;
43813 }
43814 
43815 // -------- func wbmp.decoder.num_decoded_frame_configs
43816 
43817 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frame_configs(const wuffs_wbmp__decoder * self)43818 wuffs_wbmp__decoder__num_decoded_frame_configs(
43819     const wuffs_wbmp__decoder* self) {
43820   if (!self) {
43821     return 0;
43822   }
43823   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43824       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43825     return 0;
43826   }
43827 
43828   if (self->private_impl.f_call_sequence > 3) {
43829     return 1;
43830   }
43831   return 0;
43832 }
43833 
43834 // -------- func wbmp.decoder.num_decoded_frames
43835 
43836 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frames(const wuffs_wbmp__decoder * self)43837 wuffs_wbmp__decoder__num_decoded_frames(
43838     const wuffs_wbmp__decoder* self) {
43839   if (!self) {
43840     return 0;
43841   }
43842   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43843       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43844     return 0;
43845   }
43846 
43847   if (self->private_impl.f_call_sequence > 4) {
43848     return 1;
43849   }
43850   return 0;
43851 }
43852 
43853 // -------- func wbmp.decoder.restart_frame
43854 
43855 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)43856 wuffs_wbmp__decoder__restart_frame(
43857     wuffs_wbmp__decoder* self,
43858     uint64_t a_index,
43859     uint64_t a_io_position) {
43860   if (!self) {
43861     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43862   }
43863   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43864     return wuffs_base__make_status(
43865         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43866         ? wuffs_base__error__disabled_by_previous_error
43867         : wuffs_base__error__initialize_not_called);
43868   }
43869 
43870   if (self->private_impl.f_call_sequence < 3) {
43871     return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
43872   }
43873   if (a_index != 0) {
43874     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43875   }
43876   self->private_impl.f_call_sequence = 3;
43877   self->private_impl.f_frame_config_io_position = a_io_position;
43878   return wuffs_base__make_status(NULL);
43879 }
43880 
43881 // -------- func wbmp.decoder.set_report_metadata
43882 
43883 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)43884 wuffs_wbmp__decoder__set_report_metadata(
43885     wuffs_wbmp__decoder* self,
43886     uint32_t a_fourcc,
43887     bool a_report) {
43888   return wuffs_base__make_empty_struct();
43889 }
43890 
43891 // -------- func wbmp.decoder.tell_me_more
43892 
43893 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)43894 wuffs_wbmp__decoder__tell_me_more(
43895     wuffs_wbmp__decoder* self,
43896     wuffs_base__io_buffer* a_dst,
43897     wuffs_base__more_information* a_minfo,
43898     wuffs_base__io_buffer* a_src) {
43899   if (!self) {
43900     return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43901   }
43902   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43903     return wuffs_base__make_status(
43904         (self->private_impl.magic == WUFFS_BASE__DISABLED)
43905         ? wuffs_base__error__disabled_by_previous_error
43906         : wuffs_base__error__initialize_not_called);
43907   }
43908   if (!a_dst || !a_src) {
43909     self->private_impl.magic = WUFFS_BASE__DISABLED;
43910     return wuffs_base__make_status(wuffs_base__error__bad_argument);
43911   }
43912   if ((self->private_impl.active_coroutine != 0) &&
43913       (self->private_impl.active_coroutine != 4)) {
43914     self->private_impl.magic = WUFFS_BASE__DISABLED;
43915     return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43916   }
43917   self->private_impl.active_coroutine = 0;
43918   wuffs_base__status status = wuffs_base__make_status(NULL);
43919 
43920   status = wuffs_base__make_status(wuffs_base__error__no_more_information);
43921   goto exit;
43922 
43923   goto ok;
43924   ok:
43925   goto exit;
43926   exit:
43927   if (wuffs_base__status__is_error(&status)) {
43928     self->private_impl.magic = WUFFS_BASE__DISABLED;
43929   }
43930   return status;
43931 }
43932 
43933 // -------- func wbmp.decoder.workbuf_len
43934 
43935 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_wbmp__decoder__workbuf_len(const wuffs_wbmp__decoder * self)43936 wuffs_wbmp__decoder__workbuf_len(
43937     const wuffs_wbmp__decoder* self) {
43938   if (!self) {
43939     return wuffs_base__utility__empty_range_ii_u64();
43940   }
43941   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43942       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43943     return wuffs_base__utility__empty_range_ii_u64();
43944   }
43945 
43946   return wuffs_base__utility__make_range_ii_u64(0, 0);
43947 }
43948 
43949 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
43950 
43951 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
43952 
43953 // ---------------- Auxiliary - Base
43954 
43955 // Auxiliary code is discussed at
43956 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
43957 
43958 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__BASE)
43959 
43960 namespace wuffs_aux {
43961 
43962 namespace sync_io {
43963 
43964 // --------
43965 
DynIOBuffer(uint64_t max_incl)43966 DynIOBuffer::DynIOBuffer(uint64_t max_incl)
43967     : m_buf(wuffs_base__empty_io_buffer()), m_max_incl(max_incl) {}
43968 
~DynIOBuffer()43969 DynIOBuffer::~DynIOBuffer() {
43970   if (m_buf.data.ptr) {
43971     free(m_buf.data.ptr);
43972   }
43973 }
43974 
43975 void  //
drop()43976 DynIOBuffer::drop() {
43977   if (m_buf.data.ptr) {
43978     free(m_buf.data.ptr);
43979   }
43980   m_buf = wuffs_base__empty_io_buffer();
43981 }
43982 
43983 DynIOBuffer::GrowResult  //
grow(uint64_t min_incl)43984 DynIOBuffer::grow(uint64_t min_incl) {
43985   uint64_t n = round_up(min_incl, m_max_incl);
43986   if (n == 0) {
43987     return ((min_incl == 0) && (m_max_incl == 0))
43988                ? DynIOBuffer::GrowResult::OK
43989                : DynIOBuffer::GrowResult::FailedMaxInclExceeded;
43990   } else if (n > m_buf.data.len) {
43991     uint8_t* ptr = static_cast<uint8_t*>(realloc(m_buf.data.ptr, n));
43992     if (!ptr) {
43993       return DynIOBuffer::GrowResult::FailedOutOfMemory;
43994     }
43995     m_buf.data.ptr = ptr;
43996     m_buf.data.len = n;
43997   }
43998   return DynIOBuffer::GrowResult::OK;
43999 }
44000 
44001 // round_up rounds min_incl up, returning the smallest value x satisfying
44002 // (min_incl <= x) and (x <= max_incl) and some other constraints. It returns 0
44003 // if there is no such x.
44004 //
44005 // When max_incl <= 4096, the other constraints are:
44006 //  - (x == max_incl)
44007 //
44008 // When max_incl >  4096, the other constraints are:
44009 //  - (x == max_incl) or (x is a power of 2)
44010 //  - (x >= 4096)
44011 uint64_t  //
round_up(uint64_t min_incl,uint64_t max_incl)44012 DynIOBuffer::round_up(uint64_t min_incl, uint64_t max_incl) {
44013   if (min_incl > max_incl) {
44014     return 0;
44015   }
44016   uint64_t n = 4096;
44017   if (n >= max_incl) {
44018     return max_incl;
44019   }
44020   while (n < min_incl) {
44021     if (n >= (max_incl / 2)) {
44022       return max_incl;
44023     }
44024     n *= 2;
44025   }
44026   return n;
44027 }
44028 
44029 // --------
44030 
~Input()44031 Input::~Input() {}
44032 
44033 IOBuffer*  //
BringsItsOwnIOBuffer()44034 Input::BringsItsOwnIOBuffer() {
44035   return nullptr;
44036 }
44037 
44038 // --------
44039 
FileInput(FILE * f)44040 FileInput::FileInput(FILE* f) : m_f(f) {}
44041 
44042 std::string  //
CopyIn(IOBuffer * dst)44043 FileInput::CopyIn(IOBuffer* dst) {
44044   if (!m_f) {
44045     return "wuffs_aux::sync_io::FileInput: nullptr file";
44046   } else if (!dst) {
44047     return "wuffs_aux::sync_io::FileInput: nullptr IOBuffer";
44048   } else if (dst->meta.closed) {
44049     return "wuffs_aux::sync_io::FileInput: end of file";
44050   } else {
44051     dst->compact();
44052     size_t n = fread(dst->writer_pointer(), 1, dst->writer_length(), m_f);
44053     dst->meta.wi += n;
44054     dst->meta.closed = feof(m_f);
44055     if (ferror(m_f)) {
44056       return "wuffs_aux::sync_io::FileInput: error reading file";
44057     }
44058   }
44059   return "";
44060 }
44061 
44062 // --------
44063 
MemoryInput(const char * ptr,size_t len)44064 MemoryInput::MemoryInput(const char* ptr, size_t len)
44065     : m_io(wuffs_base__ptr_u8__reader(
44066           static_cast<uint8_t*>(static_cast<void*>(const_cast<char*>(ptr))),
44067           len,
44068           true)) {}
44069 
MemoryInput(const uint8_t * ptr,size_t len)44070 MemoryInput::MemoryInput(const uint8_t* ptr, size_t len)
44071     : m_io(wuffs_base__ptr_u8__reader(const_cast<uint8_t*>(ptr), len, true)) {}
44072 
44073 IOBuffer*  //
BringsItsOwnIOBuffer()44074 MemoryInput::BringsItsOwnIOBuffer() {
44075   return &m_io;
44076 }
44077 
44078 std::string  //
CopyIn(IOBuffer * dst)44079 MemoryInput::CopyIn(IOBuffer* dst) {
44080   if (!dst) {
44081     return "wuffs_aux::sync_io::MemoryInput: nullptr IOBuffer";
44082   } else if (dst->meta.closed) {
44083     return "wuffs_aux::sync_io::MemoryInput: end of file";
44084   } else if (wuffs_base__slice_u8__overlaps(dst->data, m_io.data)) {
44085     // Treat m_io's data as immutable, so don't compact dst or otherwise write
44086     // to it.
44087     return "wuffs_aux::sync_io::MemoryInput: overlapping buffers";
44088   } else {
44089     dst->compact();
44090     size_t nd = dst->writer_length();
44091     size_t ns = m_io.reader_length();
44092     size_t n = (nd < ns) ? nd : ns;
44093     memcpy(dst->writer_pointer(), m_io.reader_pointer(), n);
44094     m_io.meta.ri += n;
44095     dst->meta.wi += n;
44096     dst->meta.closed = m_io.reader_length() == 0;
44097   }
44098   return "";
44099 }
44100 
44101 // --------
44102 
44103 }  // namespace sync_io
44104 
44105 namespace private_impl {
44106 
44107 struct ErrorMessages {
44108   const char* max_incl_metadata_length_exceeded;
44109   const char* out_of_memory;
44110   const char* unexpected_end_of_file;
44111   const char* unsupported_metadata;
44112   const char* unsupported_negative_advance;
44113 
44114   // If adding new "const char*" typed fields to this struct, either add them
44115   // after existing fields or, if re-ordering fields, make sure that you update
44116   // all of the "const private_impl::ErrorMessages FooBarErrorMessages" values
44117   // in all of the sibling *.cc files.
44118 
resolveErrorMessages44119   static inline const char* resolve(const char* s) {
44120     return s ? s : "wuffs_aux::private_impl: unknown error";
44121   };
44122 };
44123 
44124 std::string  //
AdvanceIOBufferTo(const ErrorMessages & error_messages,sync_io::Input & input,IOBuffer & io_buf,uint64_t absolute_position)44125 AdvanceIOBufferTo(const ErrorMessages& error_messages,
44126                   sync_io::Input& input,
44127                   IOBuffer& io_buf,
44128                   uint64_t absolute_position) {
44129   if (absolute_position < io_buf.reader_position()) {
44130     return error_messages.resolve(error_messages.unsupported_negative_advance);
44131   }
44132   while (true) {
44133     uint64_t relative_position = absolute_position - io_buf.reader_position();
44134     if (relative_position <= io_buf.reader_length()) {
44135       io_buf.meta.ri += (size_t)relative_position;
44136       break;
44137     } else if (io_buf.meta.closed) {
44138       return error_messages.resolve(error_messages.unexpected_end_of_file);
44139     }
44140     io_buf.meta.ri = io_buf.meta.wi;
44141     if (!input.BringsItsOwnIOBuffer()) {
44142       io_buf.compact();
44143     }
44144     std::string error_message = input.CopyIn(&io_buf);
44145     if (!error_message.empty()) {
44146       return error_message;
44147     }
44148   }
44149   return "";
44150 }
44151 
44152 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)44153 HandleMetadata(
44154     const ErrorMessages& error_messages,
44155     sync_io::Input& input,
44156     wuffs_base__io_buffer& io_buf,
44157     sync_io::DynIOBuffer& raw,
44158     wuffs_base__status (*tell_me_more_func)(void*,
44159                                             wuffs_base__io_buffer*,
44160                                             wuffs_base__more_information*,
44161                                             wuffs_base__io_buffer*),
44162     void* tell_me_more_receiver,
44163     std::string (*handle_metadata_func)(void*,
44164                                         const wuffs_base__more_information*,
44165                                         wuffs_base__slice_u8),
44166     void* handle_metadata_receiver) {
44167   wuffs_base__more_information minfo = wuffs_base__empty_more_information();
44168   // Reset raw but keep its backing array (the raw.m_buf.data slice).
44169   raw.m_buf.meta = wuffs_base__empty_io_buffer_meta();
44170 
44171   while (true) {
44172     minfo = wuffs_base__empty_more_information();
44173     wuffs_base__status status = (*tell_me_more_func)(
44174         tell_me_more_receiver, &raw.m_buf, &minfo, &io_buf);
44175     switch (minfo.flavor) {
44176       case 0:
44177       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM:
44178       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED:
44179         break;
44180 
44181       case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH: {
44182         wuffs_base__range_ie_u64 r = minfo.metadata_raw_passthrough__range();
44183         if (r.is_empty()) {
44184           break;
44185         }
44186         uint64_t num_to_copy = r.length();
44187         if (num_to_copy > (raw.m_max_incl - raw.m_buf.meta.wi)) {
44188           return error_messages.resolve(
44189               error_messages.max_incl_metadata_length_exceeded);
44190         } else if (num_to_copy > (raw.m_buf.data.len - raw.m_buf.meta.wi)) {
44191           switch (raw.grow(num_to_copy + raw.m_buf.meta.wi)) {
44192             case sync_io::DynIOBuffer::GrowResult::OK:
44193               break;
44194             case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
44195               return error_messages.resolve(
44196                   error_messages.max_incl_metadata_length_exceeded);
44197             case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
44198               return error_messages.resolve(error_messages.out_of_memory);
44199           }
44200         }
44201 
44202         if (io_buf.reader_position() > r.min_incl) {
44203           return error_messages.resolve(error_messages.unsupported_metadata);
44204         } else {
44205           std::string error_message =
44206               AdvanceIOBufferTo(error_messages, input, io_buf, r.min_incl);
44207           if (!error_message.empty()) {
44208             return error_message;
44209           }
44210         }
44211 
44212         while (true) {
44213           uint64_t n =
44214               wuffs_base__u64__min(num_to_copy, io_buf.reader_length());
44215           memcpy(raw.m_buf.writer_pointer(), io_buf.reader_pointer(), n);
44216           raw.m_buf.meta.wi += n;
44217           io_buf.meta.ri += n;
44218           num_to_copy -= n;
44219           if (num_to_copy == 0) {
44220             break;
44221           } else if (io_buf.meta.closed) {
44222             return error_messages.resolve(
44223                 error_messages.unexpected_end_of_file);
44224           } else if (!input.BringsItsOwnIOBuffer()) {
44225             io_buf.compact();
44226           }
44227           std::string error_message = input.CopyIn(&io_buf);
44228           if (!error_message.empty()) {
44229             return error_message;
44230           }
44231         }
44232         break;
44233       }
44234 
44235       default:
44236         return error_messages.resolve(error_messages.unsupported_metadata);
44237     }
44238 
44239     if (status.repr == nullptr) {
44240       break;
44241     } else if (status.repr != wuffs_base__suspension__even_more_information) {
44242       if (status.repr != wuffs_base__suspension__short_write) {
44243         return status.message();
44244       }
44245       switch (raw.grow(wuffs_base__u64__sat_add(raw.m_buf.data.len, 1))) {
44246         case sync_io::DynIOBuffer::GrowResult::OK:
44247           break;
44248         case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
44249           return error_messages.resolve(
44250               error_messages.max_incl_metadata_length_exceeded);
44251         case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
44252           return error_messages.resolve(error_messages.out_of_memory);
44253       }
44254     }
44255   }
44256 
44257   return (*handle_metadata_func)(handle_metadata_receiver, &minfo,
44258                                  raw.m_buf.reader_slice());
44259 }
44260 
44261 }  // namespace private_impl
44262 
44263 }  // namespace wuffs_aux
44264 
44265 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
44266         // defined(WUFFS_CONFIG__MODULE__AUX__BASE)
44267 
44268 // ---------------- Auxiliary - CBOR
44269 
44270 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
44271 
44272 #include <utility>
44273 
44274 namespace wuffs_aux {
44275 
DecodeCborResult(std::string && error_message0,uint64_t cursor_position0)44276 DecodeCborResult::DecodeCborResult(std::string&& error_message0,
44277                                    uint64_t cursor_position0)
44278     : error_message(std::move(error_message0)),
44279       cursor_position(cursor_position0) {}
44280 
~DecodeCborCallbacks()44281 DecodeCborCallbacks::~DecodeCborCallbacks() {}
44282 
44283 void  //
Done(DecodeCborResult & result,sync_io::Input & input,IOBuffer & buffer)44284 DecodeCborCallbacks::Done(DecodeCborResult& result,
44285                           sync_io::Input& input,
44286                           IOBuffer& buffer) {}
44287 
DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)44288 DecodeCborArgQuirks::DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)
44289     : repr(repr0) {}
44290 
DecodeCborArgQuirks(uint32_t * ptr0,size_t len0)44291 DecodeCborArgQuirks::DecodeCborArgQuirks(uint32_t* ptr0, size_t len0)
44292     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
44293 
44294 DecodeCborArgQuirks  //
DefaultValue()44295 DecodeCborArgQuirks::DefaultValue() {
44296   return DecodeCborArgQuirks(wuffs_base__empty_slice_u32());
44297 }
44298 
44299 DecodeCborResult  //
DecodeCbor(DecodeCborCallbacks & callbacks,sync_io::Input & input,DecodeCborArgQuirks quirks)44300 DecodeCbor(DecodeCborCallbacks& callbacks,
44301            sync_io::Input& input,
44302            DecodeCborArgQuirks quirks) {
44303   // Prepare the wuffs_base__io_buffer and the resultant error_message.
44304   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
44305   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
44306   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
44307   if (!io_buf) {
44308     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
44309     fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
44310     io_buf = &fallback_io_buf;
44311   }
44312   // cursor_index is discussed at
44313   // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
44314   size_t cursor_index = 0;
44315   std::string ret_error_message;
44316   std::string io_error_message;
44317 
44318   do {
44319     // Prepare the low-level CBOR decoder.
44320     wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
44321     if (!dec) {
44322       ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
44323       goto done;
44324     }
44325     for (size_t i = 0; i < quirks.repr.len; i++) {
44326       dec->set_quirk_enabled(quirks.repr.ptr[i], true);
44327     }
44328 
44329     // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
44330     wuffs_base__token tok_array[256];
44331     wuffs_base__token_buffer tok_buf =
44332         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
44333             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
44334     wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
44335 
44336     // Prepare other state.
44337     int32_t depth = 0;
44338     std::string str;
44339     int64_t extension_category = 0;
44340     uint64_t extension_detail = 0;
44341 
44342     // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens
44343     // from outside of the base package, such as the CBOR package.
44344     constexpr int64_t EXT_CAT__CBOR_TAG = 16;
44345 
44346     // Loop, doing these two things:
44347     //  1. Get the next token.
44348     //  2. Process that token.
44349     while (true) {
44350       // 1. Get the next token.
44351 
44352       while (tok_buf.meta.ri >= tok_buf.meta.wi) {
44353         if (tok_status.repr == nullptr) {
44354           // No-op.
44355         } else if (tok_status.repr == wuffs_base__suspension__short_write) {
44356           tok_buf.compact();
44357         } else if (tok_status.repr == wuffs_base__suspension__short_read) {
44358           // Read from input to io_buf.
44359           if (!io_error_message.empty()) {
44360             ret_error_message = std::move(io_error_message);
44361             goto done;
44362           } else if (cursor_index != io_buf->meta.ri) {
44363             ret_error_message =
44364                 "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
44365             goto done;
44366           } else if (io_buf->meta.closed) {
44367             ret_error_message =
44368                 "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
44369             goto done;
44370           }
44371           io_buf->compact();
44372           if (io_buf->meta.wi >= io_buf->data.len) {
44373             ret_error_message =
44374                 "wuffs_aux::DecodeCbor: internal error: io_buf is full";
44375             goto done;
44376           }
44377           cursor_index = io_buf->meta.ri;
44378           io_error_message = input.CopyIn(io_buf);
44379         } else {
44380           ret_error_message = tok_status.message();
44381           goto done;
44382         }
44383 
44384         if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
44385           ret_error_message =
44386               "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
44387           goto done;
44388         }
44389         wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
44390         tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
44391         if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
44392             (tok_buf.meta.wi > tok_buf.data.len) ||
44393             (io_buf->meta.ri > io_buf->meta.wi) ||
44394             (io_buf->meta.wi > io_buf->data.len)) {
44395           ret_error_message =
44396               "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
44397           goto done;
44398         }
44399       }
44400 
44401       wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
44402       uint64_t token_len = token.length();
44403       if ((io_buf->meta.ri < cursor_index) ||
44404           ((io_buf->meta.ri - cursor_index) < token_len)) {
44405         ret_error_message =
44406             "wuffs_aux::DecodeCbor: internal error: bad token indexes";
44407         goto done;
44408       }
44409       uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
44410       cursor_index += static_cast<size_t>(token_len);
44411 
44412       // 2. Process that token.
44413 
44414       uint64_t vbd = token.value_base_detail();
44415 
44416       if (extension_category != 0) {
44417         int64_t ext = token.value_extension();
44418         if ((ext >= 0) && !token.continued()) {
44419           extension_detail = (extension_detail
44420                               << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |
44421                              static_cast<uint64_t>(ext);
44422           switch (extension_category) {
44423             case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED:
44424               extension_category = 0;
44425               ret_error_message =
44426                   callbacks.AppendI64(static_cast<int64_t>(extension_detail));
44427               goto parsed_a_value;
44428             case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:
44429               extension_category = 0;
44430               ret_error_message = callbacks.AppendU64(extension_detail);
44431               goto parsed_a_value;
44432             case EXT_CAT__CBOR_TAG:
44433               extension_category = 0;
44434               ret_error_message = callbacks.AppendCborTag(extension_detail);
44435               if (!ret_error_message.empty()) {
44436                 goto done;
44437               }
44438               continue;
44439           }
44440         }
44441         ret_error_message =
44442             "wuffs_aux::DecodeCbor: internal error: bad extended token";
44443         goto done;
44444       }
44445 
44446       switch (token.value_base_category()) {
44447         case WUFFS_BASE__TOKEN__VBC__FILLER:
44448           continue;
44449 
44450         case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
44451           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
44452             ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
44453             if (!ret_error_message.empty()) {
44454               goto done;
44455             }
44456             depth++;
44457             if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
44458               ret_error_message =
44459                   "wuffs_aux::DecodeCbor: internal error: bad depth";
44460               goto done;
44461             }
44462             continue;
44463           }
44464           ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
44465           depth--;
44466           if (depth < 0) {
44467             ret_error_message =
44468                 "wuffs_aux::DecodeCbor: internal error: bad depth";
44469             goto done;
44470           }
44471           goto parsed_a_value;
44472         }
44473 
44474         case WUFFS_BASE__TOKEN__VBC__STRING: {
44475           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
44476             // No-op.
44477           } else if (vbd &
44478                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
44479             const char* ptr =  // Convert from (uint8_t*).
44480                 static_cast<const char*>(static_cast<void*>(token_ptr));
44481             str.append(ptr, static_cast<size_t>(token_len));
44482           } else {
44483             goto fail;
44484           }
44485           if (token.continued()) {
44486             continue;
44487           }
44488           ret_error_message =
44489               (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)
44490                   ? callbacks.AppendTextString(std::move(str))
44491                   : callbacks.AppendByteString(std::move(str));
44492           str.clear();
44493           goto parsed_a_value;
44494         }
44495 
44496         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
44497           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
44498           size_t n = wuffs_base__utf_8__encode(
44499               wuffs_base__make_slice_u8(
44500                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
44501               static_cast<uint32_t>(vbd));
44502           const char* ptr =  // Convert from (uint8_t*).
44503               static_cast<const char*>(static_cast<void*>(&u[0]));
44504           str.append(ptr, n);
44505           if (token.continued()) {
44506             continue;
44507           }
44508           goto fail;
44509         }
44510 
44511         case WUFFS_BASE__TOKEN__VBC__LITERAL: {
44512           if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {
44513             ret_error_message = callbacks.AppendNull();
44514           } else if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED) {
44515             ret_error_message = callbacks.AppendUndefined();
44516           } else {
44517             ret_error_message = callbacks.AppendBool(
44518                 vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
44519           }
44520           goto parsed_a_value;
44521         }
44522 
44523         case WUFFS_BASE__TOKEN__VBC__NUMBER: {
44524           const uint64_t cfp_fbbe_fifb =
44525               WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |
44526               WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |
44527               WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;
44528           if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {
44529             double f;
44530             switch (token_len) {
44531               case 3:
44532                 f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(
44533                     wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));
44534                 break;
44535               case 5:
44536                 f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(
44537                     wuffs_base__peek_u32be__no_bounds_check(token_ptr + 1));
44538                 break;
44539               case 9:
44540                 f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
44541                     wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
44542                 break;
44543               default:
44544                 goto fail;
44545             }
44546             ret_error_message = callbacks.AppendF64(f);
44547             goto parsed_a_value;
44548           }
44549           goto fail;
44550         }
44551 
44552         case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {
44553           if (token.continued()) {
44554             extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;
44555             extension_detail =
44556                 static_cast<uint64_t>(token.value_base_detail__sign_extended());
44557             continue;
44558           }
44559           ret_error_message =
44560               callbacks.AppendI64(token.value_base_detail__sign_extended());
44561           goto parsed_a_value;
44562         }
44563 
44564         case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {
44565           if (token.continued()) {
44566             extension_category =
44567                 WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;
44568             extension_detail = vbd;
44569             continue;
44570           }
44571           ret_error_message = callbacks.AppendU64(vbd);
44572           goto parsed_a_value;
44573         }
44574       }
44575 
44576       if (token.value_major() == WUFFS_CBOR__TOKEN_VALUE_MAJOR) {
44577         uint64_t value_minor = token.value_minor();
44578         if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {
44579           if (token_len == 9) {
44580             ret_error_message = callbacks.AppendMinus1MinusX(
44581                 wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
44582             goto parsed_a_value;
44583           }
44584         } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {
44585           ret_error_message =
44586               callbacks.AppendCborSimpleValue(static_cast<uint8_t>(
44587                   value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));
44588           goto parsed_a_value;
44589         } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG) {
44590           if (token.continued()) {
44591             extension_category = EXT_CAT__CBOR_TAG;
44592             extension_detail =
44593                 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;
44594             continue;
44595           }
44596           ret_error_message = callbacks.AppendCborTag(
44597               value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);
44598           if (!ret_error_message.empty()) {
44599             goto done;
44600           }
44601           continue;
44602         }
44603       }
44604 
44605     fail:
44606       ret_error_message =
44607           "wuffs_aux::DecodeCbor: internal error: unexpected token";
44608       goto done;
44609 
44610     parsed_a_value:
44611       if (!ret_error_message.empty() || (depth == 0)) {
44612         goto done;
44613       }
44614     }
44615   } while (false);
44616 
44617 done:
44618   DecodeCborResult result(
44619       std::move(ret_error_message),
44620       wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
44621   callbacks.Done(result, input, *io_buf);
44622   return result;
44623 }
44624 
44625 }  // namespace wuffs_aux
44626 
44627 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
44628         // defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
44629 
44630 // ---------------- Auxiliary - Image
44631 
44632 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
44633 
44634 #include <utility>
44635 
44636 namespace wuffs_aux {
44637 
DecodeImageResult(MemOwner && pixbuf_mem_owner0,wuffs_base__pixel_buffer pixbuf0,std::string && error_message0)44638 DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
44639                                      wuffs_base__pixel_buffer pixbuf0,
44640                                      std::string&& error_message0)
44641     : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
44642       pixbuf(pixbuf0),
44643       error_message(std::move(error_message0)) {}
44644 
DecodeImageResult(std::string && error_message0)44645 DecodeImageResult::DecodeImageResult(std::string&& error_message0)
44646     : pixbuf_mem_owner(nullptr, &free),
44647       pixbuf(wuffs_base__null_pixel_buffer()),
44648       error_message(std::move(error_message0)) {}
44649 
~DecodeImageCallbacks()44650 DecodeImageCallbacks::~DecodeImageCallbacks() {}
44651 
AllocPixbufResult(MemOwner && mem_owner0,wuffs_base__pixel_buffer pixbuf0)44652 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
44653     MemOwner&& mem_owner0,
44654     wuffs_base__pixel_buffer pixbuf0)
44655     : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
44656 
AllocPixbufResult(std::string && error_message0)44657 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
44658     std::string&& error_message0)
44659     : mem_owner(nullptr, &free),
44660       pixbuf(wuffs_base__null_pixel_buffer()),
44661       error_message(std::move(error_message0)) {}
44662 
AllocWorkbufResult(MemOwner && mem_owner0,wuffs_base__slice_u8 workbuf0)44663 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
44664     MemOwner&& mem_owner0,
44665     wuffs_base__slice_u8 workbuf0)
44666     : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
44667 
AllocWorkbufResult(std::string && error_message0)44668 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
44669     std::string&& error_message0)
44670     : mem_owner(nullptr, &free),
44671       workbuf(wuffs_base__empty_slice_u8()),
44672       error_message(std::move(error_message0)) {}
44673 
44674 wuffs_base__image_decoder::unique_ptr  //
SelectDecoder(uint32_t fourcc,wuffs_base__slice_u8 prefix_data,bool prefix_closed)44675 DecodeImageCallbacks::SelectDecoder(uint32_t fourcc,
44676                                     wuffs_base__slice_u8 prefix_data,
44677                                     bool prefix_closed) {
44678   switch (fourcc) {
44679 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
44680     case WUFFS_BASE__FOURCC__BMP:
44681       return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
44682 #endif
44683 
44684 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
44685     case WUFFS_BASE__FOURCC__GIF:
44686       return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
44687 #endif
44688 
44689 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
44690     case WUFFS_BASE__FOURCC__NIE:
44691       return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
44692 #endif
44693 
44694 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
44695     case WUFFS_BASE__FOURCC__PNG: {
44696       auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
44697       // Favor faster decodes over rejecting invalid checksums.
44698       dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
44699       return dec;
44700     }
44701 #endif
44702 
44703 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
44704     case WUFFS_BASE__FOURCC__TGA:
44705       return wuffs_tga__decoder::alloc_as__wuffs_base__image_decoder();
44706 #endif
44707 
44708 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
44709     case WUFFS_BASE__FOURCC__WBMP:
44710       return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
44711 #endif
44712   }
44713 
44714   return wuffs_base__image_decoder::unique_ptr(nullptr, &free);
44715 }
44716 
44717 std::string  //
HandleMetadata(const wuffs_base__more_information & minfo,wuffs_base__slice_u8 raw)44718 DecodeImageCallbacks::HandleMetadata(const wuffs_base__more_information& minfo,
44719                                      wuffs_base__slice_u8 raw) {
44720   return "";
44721 }
44722 
44723 wuffs_base__pixel_format  //
SelectPixfmt(const wuffs_base__image_config & image_config)44724 DecodeImageCallbacks::SelectPixfmt(
44725     const wuffs_base__image_config& image_config) {
44726   return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
44727 }
44728 
44729 DecodeImageCallbacks::AllocPixbufResult  //
AllocPixbuf(const wuffs_base__image_config & image_config,bool allow_uninitialized_memory)44730 DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
44731                                   bool allow_uninitialized_memory) {
44732   uint32_t w = image_config.pixcfg.width();
44733   uint32_t h = image_config.pixcfg.height();
44734   if ((w == 0) || (h == 0)) {
44735     return AllocPixbufResult("");
44736   }
44737   uint64_t len = image_config.pixcfg.pixbuf_len();
44738   if ((len == 0) || (SIZE_MAX < len)) {
44739     return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
44740   }
44741   void* ptr =
44742       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
44743   if (!ptr) {
44744     return AllocPixbufResult(DecodeImage_OutOfMemory);
44745   }
44746   wuffs_base__pixel_buffer pixbuf;
44747   wuffs_base__status status = pixbuf.set_from_slice(
44748       &image_config.pixcfg,
44749       wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
44750   if (!status.is_ok()) {
44751     free(ptr);
44752     return AllocPixbufResult(status.message());
44753   }
44754   return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
44755 }
44756 
44757 DecodeImageCallbacks::AllocWorkbufResult  //
AllocWorkbuf(wuffs_base__range_ii_u64 len_range,bool allow_uninitialized_memory)44758 DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
44759                                    bool allow_uninitialized_memory) {
44760   uint64_t len = len_range.max_incl;
44761   if (len == 0) {
44762     return AllocWorkbufResult("");
44763   } else if (SIZE_MAX < len) {
44764     return AllocWorkbufResult(DecodeImage_OutOfMemory);
44765   }
44766   void* ptr =
44767       allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
44768   if (!ptr) {
44769     return AllocWorkbufResult(DecodeImage_OutOfMemory);
44770   }
44771   return AllocWorkbufResult(
44772       MemOwner(ptr, &free),
44773       wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
44774 }
44775 
44776 void  //
Done(DecodeImageResult & result,sync_io::Input & input,IOBuffer & buffer,wuffs_base__image_decoder::unique_ptr image_decoder)44777 DecodeImageCallbacks::Done(
44778     DecodeImageResult& result,
44779     sync_io::Input& input,
44780     IOBuffer& buffer,
44781     wuffs_base__image_decoder::unique_ptr image_decoder) {}
44782 
44783 const char DecodeImage_BufferIsTooShort[] =  //
44784     "wuffs_aux::DecodeImage: buffer is too short";
44785 const char DecodeImage_MaxInclDimensionExceeded[] =  //
44786     "wuffs_aux::DecodeImage: max_incl_dimension exceeded";
44787 const char DecodeImage_MaxInclMetadataLengthExceeded[] =  //
44788     "wuffs_aux::DecodeImage: max_incl_metadata_length exceeded";
44789 const char DecodeImage_OutOfMemory[] =  //
44790     "wuffs_aux::DecodeImage: out of memory";
44791 const char DecodeImage_UnexpectedEndOfFile[] =  //
44792     "wuffs_aux::DecodeImage: unexpected end of file";
44793 const char DecodeImage_UnsupportedImageFormat[] =  //
44794     "wuffs_aux::DecodeImage: unsupported image format";
44795 const char DecodeImage_UnsupportedMetadata[] =  //
44796     "wuffs_aux::DecodeImage: unsupported metadata";
44797 const char DecodeImage_UnsupportedPixelBlend[] =  //
44798     "wuffs_aux::DecodeImage: unsupported pixel blend";
44799 const char DecodeImage_UnsupportedPixelConfiguration[] =  //
44800     "wuffs_aux::DecodeImage: unsupported pixel configuration";
44801 const char DecodeImage_UnsupportedPixelFormat[] =  //
44802     "wuffs_aux::DecodeImage: unsupported pixel format";
44803 
DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)44804 DecodeImageArgQuirks::DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)
44805     : repr(repr0) {}
44806 
DecodeImageArgQuirks(uint32_t * ptr0,size_t len0)44807 DecodeImageArgQuirks::DecodeImageArgQuirks(uint32_t* ptr0, size_t len0)
44808     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
44809 
44810 DecodeImageArgQuirks  //
DefaultValue()44811 DecodeImageArgQuirks::DefaultValue() {
44812   return DecodeImageArgQuirks(wuffs_base__empty_slice_u32());
44813 }
44814 
DecodeImageArgFlags(uint64_t repr0)44815 DecodeImageArgFlags::DecodeImageArgFlags(uint64_t repr0) : repr(repr0) {}
44816 
44817 DecodeImageArgFlags  //
DefaultValue()44818 DecodeImageArgFlags::DefaultValue() {
44819   return DecodeImageArgFlags(0);
44820 }
44821 
DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0)44822 DecodeImageArgPixelBlend::DecodeImageArgPixelBlend(
44823     wuffs_base__pixel_blend repr0)
44824     : repr(repr0) {}
44825 
44826 DecodeImageArgPixelBlend  //
DefaultValue()44827 DecodeImageArgPixelBlend::DefaultValue() {
44828   return DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC);
44829 }
44830 
DecodeImageArgBackgroundColor(wuffs_base__color_u32_argb_premul repr0)44831 DecodeImageArgBackgroundColor::DecodeImageArgBackgroundColor(
44832     wuffs_base__color_u32_argb_premul repr0)
44833     : repr(repr0) {}
44834 
44835 DecodeImageArgBackgroundColor  //
DefaultValue()44836 DecodeImageArgBackgroundColor::DefaultValue() {
44837   return DecodeImageArgBackgroundColor(1);
44838 }
44839 
DecodeImageArgMaxInclDimension(uint32_t repr0)44840 DecodeImageArgMaxInclDimension::DecodeImageArgMaxInclDimension(uint32_t repr0)
44841     : repr(repr0) {}
44842 
44843 DecodeImageArgMaxInclDimension  //
DefaultValue()44844 DecodeImageArgMaxInclDimension::DefaultValue() {
44845   return DecodeImageArgMaxInclDimension(1048575);
44846 }
44847 
DecodeImageArgMaxInclMetadataLength(uint64_t repr0)44848 DecodeImageArgMaxInclMetadataLength::DecodeImageArgMaxInclMetadataLength(
44849     uint64_t repr0)
44850     : repr(repr0) {}
44851 
44852 DecodeImageArgMaxInclMetadataLength  //
DefaultValue()44853 DecodeImageArgMaxInclMetadataLength::DefaultValue() {
44854   return DecodeImageArgMaxInclMetadataLength(16777215);
44855 }
44856 
44857 // --------
44858 
44859 namespace {
44860 
44861 const private_impl::ErrorMessages DecodeImageErrorMessages = {
44862     DecodeImage_MaxInclMetadataLengthExceeded,  //
44863     DecodeImage_OutOfMemory,                    //
44864     DecodeImage_UnexpectedEndOfFile,            //
44865     DecodeImage_UnsupportedMetadata,            //
44866     DecodeImage_UnsupportedImageFormat,         //
44867 };
44868 
44869 std::string  //
DecodeImageAdvanceIOBufferTo(sync_io::Input & input,wuffs_base__io_buffer & io_buf,uint64_t absolute_position)44870 DecodeImageAdvanceIOBufferTo(sync_io::Input& input,
44871                              wuffs_base__io_buffer& io_buf,
44872                              uint64_t absolute_position) {
44873   return private_impl::AdvanceIOBufferTo(DecodeImageErrorMessages, input,
44874                                          io_buf, absolute_position);
44875 }
44876 
44877 wuffs_base__status  //
DIHM0(void * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)44878 DIHM0(void* self,
44879       wuffs_base__io_buffer* a_dst,
44880       wuffs_base__more_information* a_minfo,
44881       wuffs_base__io_buffer* a_src) {
44882   return wuffs_base__image_decoder__tell_me_more(
44883       static_cast<wuffs_base__image_decoder*>(self), a_dst, a_minfo, a_src);
44884 }
44885 
44886 std::string  //
DIHM1(void * self,const wuffs_base__more_information * minfo,wuffs_base__slice_u8 raw)44887 DIHM1(void* self,
44888       const wuffs_base__more_information* minfo,
44889       wuffs_base__slice_u8 raw) {
44890   return static_cast<DecodeImageCallbacks*>(self)->HandleMetadata(*minfo, raw);
44891 }
44892 
44893 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)44894 DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr& image_decoder,
44895                           DecodeImageCallbacks& callbacks,
44896                           sync_io::Input& input,
44897                           wuffs_base__io_buffer& io_buf,
44898                           sync_io::DynIOBuffer& raw_metadata_buf) {
44899   return private_impl::HandleMetadata(DecodeImageErrorMessages, input, io_buf,
44900                                       raw_metadata_buf, DIHM0,
44901                                       static_cast<void*>(image_decoder.get()),
44902                                       DIHM1, static_cast<void*>(&callbacks));
44903 }
44904 
44905 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)44906 DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,
44907              DecodeImageCallbacks& callbacks,
44908              sync_io::Input& input,
44909              wuffs_base__io_buffer& io_buf,
44910              wuffs_base__slice_u32 quirks,
44911              uint64_t flags,
44912              wuffs_base__pixel_blend pixel_blend,
44913              wuffs_base__color_u32_argb_premul background_color,
44914              uint32_t max_incl_dimension,
44915              uint64_t max_incl_metadata_length) {
44916   // Check args.
44917   switch (pixel_blend) {
44918     case WUFFS_BASE__PIXEL_BLEND__SRC:
44919     case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
44920       break;
44921     default:
44922       return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);
44923   }
44924 
44925   wuffs_base__image_config image_config = wuffs_base__null_image_config();
44926   sync_io::DynIOBuffer raw_metadata_buf(max_incl_metadata_length);
44927   uint64_t start_pos = io_buf.reader_position();
44928   bool redirected = false;
44929   int32_t fourcc = 0;
44930 redirect:
44931   do {
44932     // Determine the image format.
44933     if (!redirected) {
44934       while (true) {
44935         fourcc = wuffs_base__magic_number_guess_fourcc(io_buf.reader_slice(),
44936                                                        io_buf.meta.closed);
44937         if (fourcc > 0) {
44938           break;
44939         } else if ((fourcc == 0) && (io_buf.reader_length() >= 64)) {
44940           // Having (fourcc == 0) means that Wuffs' built in MIME sniffer
44941           // didn't recognize the image format. Nonetheless, custom callbacks
44942           // may still be able to do their own MIME sniffing, for exotic image
44943           // types. We try to give them at least 64 bytes of prefix data when
44944           // one-shot-calling callbacks.SelectDecoder. There is no mechanism
44945           // for the callbacks to request a longer prefix.
44946           break;
44947         } else if (io_buf.meta.closed || (io_buf.writer_length() == 0)) {
44948           fourcc = 0;
44949           break;
44950         }
44951         std::string error_message = input.CopyIn(&io_buf);
44952         if (!error_message.empty()) {
44953           return DecodeImageResult(std::move(error_message));
44954         }
44955       }
44956     } else {
44957       wuffs_base__io_buffer empty = wuffs_base__empty_io_buffer();
44958       wuffs_base__more_information minfo = wuffs_base__empty_more_information();
44959       wuffs_base__status tmm_status =
44960           image_decoder->tell_me_more(&empty, &minfo, &io_buf);
44961       if (tmm_status.repr != nullptr) {
44962         return DecodeImageResult(tmm_status.message());
44963       }
44964       if (minfo.flavor != WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {
44965         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44966       }
44967       uint64_t pos = minfo.io_redirect__range().min_incl;
44968       if (pos <= start_pos) {
44969         // Redirects must go forward.
44970         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44971       }
44972       std::string error_message =
44973           DecodeImageAdvanceIOBufferTo(input, io_buf, pos);
44974       if (!error_message.empty()) {
44975         return DecodeImageResult(std::move(error_message));
44976       }
44977       fourcc = (int32_t)(minfo.io_redirect__fourcc());
44978       if (fourcc == 0) {
44979         return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44980       }
44981       image_decoder.reset();
44982     }
44983 
44984     // Select the image decoder.
44985     image_decoder = callbacks.SelectDecoder(
44986         (uint32_t)fourcc, io_buf.reader_slice(), io_buf.meta.closed);
44987     if (!image_decoder) {
44988       return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44989     }
44990 
44991     // Apply quirks.
44992     for (size_t i = 0; i < quirks.len; i++) {
44993       image_decoder->set_quirk_enabled(quirks.ptr[i], true);
44994     }
44995 
44996     // Apply flags.
44997     if (flags != 0) {
44998       if (flags & DecodeImageArgFlags::REPORT_METADATA_CHRM) {
44999         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__CHRM, true);
45000       }
45001       if (flags & DecodeImageArgFlags::REPORT_METADATA_EXIF) {
45002         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__EXIF, true);
45003       }
45004       if (flags & DecodeImageArgFlags::REPORT_METADATA_GAMA) {
45005         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__GAMA, true);
45006       }
45007       if (flags & DecodeImageArgFlags::REPORT_METADATA_ICCP) {
45008         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__ICCP, true);
45009       }
45010       if (flags & DecodeImageArgFlags::REPORT_METADATA_KVP) {
45011         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__KVP, true);
45012       }
45013       if (flags & DecodeImageArgFlags::REPORT_METADATA_SRGB) {
45014         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__SRGB, true);
45015       }
45016       if (flags & DecodeImageArgFlags::REPORT_METADATA_XMP) {
45017         image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__XMP, true);
45018       }
45019     }
45020 
45021     // Decode the image config.
45022     while (true) {
45023       wuffs_base__status id_dic_status =
45024           image_decoder->decode_image_config(&image_config, &io_buf);
45025       if (id_dic_status.repr == nullptr) {
45026         break;
45027       } else if (id_dic_status.repr == wuffs_base__note__i_o_redirect) {
45028         if (redirected) {
45029           return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
45030         }
45031         redirected = true;
45032         goto redirect;
45033       } else if (id_dic_status.repr == wuffs_base__note__metadata_reported) {
45034         std::string error_message = DecodeImageHandleMetadata(
45035             image_decoder, callbacks, input, io_buf, raw_metadata_buf);
45036         if (!error_message.empty()) {
45037           return DecodeImageResult(std::move(error_message));
45038         }
45039       } else if (id_dic_status.repr != wuffs_base__suspension__short_read) {
45040         return DecodeImageResult(id_dic_status.message());
45041       } else if (io_buf.meta.closed) {
45042         return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
45043       } else {
45044         std::string error_message = input.CopyIn(&io_buf);
45045         if (!error_message.empty()) {
45046           return DecodeImageResult(std::move(error_message));
45047         }
45048       }
45049     }
45050   } while (false);
45051   raw_metadata_buf.drop();
45052 
45053   // Select the pixel format.
45054   uint32_t w = image_config.pixcfg.width();
45055   uint32_t h = image_config.pixcfg.height();
45056   if ((w > max_incl_dimension) || (h > max_incl_dimension)) {
45057     return DecodeImageResult(DecodeImage_MaxInclDimensionExceeded);
45058   }
45059   wuffs_base__pixel_format pixel_format = callbacks.SelectPixfmt(image_config);
45060   if (pixel_format.repr != image_config.pixcfg.pixel_format().repr) {
45061     switch (pixel_format.repr) {
45062       case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
45063       case WUFFS_BASE__PIXEL_FORMAT__BGR:
45064       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
45065       case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
45066       case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
45067       case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
45068       case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
45069         break;
45070       default:
45071         return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
45072     }
45073     image_config.pixcfg.set(pixel_format.repr,
45074                             WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);
45075   }
45076 
45077   // Allocate the pixel buffer.
45078   bool valid_background_color =
45079       wuffs_base__color_u32_argb_premul__is_valid(background_color);
45080   DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
45081       callbacks.AllocPixbuf(image_config, valid_background_color);
45082   if (!alloc_pixbuf_result.error_message.empty()) {
45083     return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
45084   }
45085   wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
45086   if (valid_background_color) {
45087     wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
45088         pixel_buffer.pixcfg.bounds(), background_color);
45089     if (pb_scufr_status.repr != nullptr) {
45090       return DecodeImageResult(pb_scufr_status.message());
45091     }
45092   }
45093 
45094   // Allocate the work buffer. Wuffs' decoders conventionally assume that this
45095   // can be uninitialized memory.
45096   wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
45097   DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
45098       callbacks.AllocWorkbuf(workbuf_len, true);
45099   if (!alloc_workbuf_result.error_message.empty()) {
45100     return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
45101   } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
45102     return DecodeImageResult(DecodeImage_BufferIsTooShort);
45103   }
45104 
45105   // Decode the frame config.
45106   wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();
45107   while (true) {
45108     wuffs_base__status id_dfc_status =
45109         image_decoder->decode_frame_config(&frame_config, &io_buf);
45110     if (id_dfc_status.repr == nullptr) {
45111       break;
45112     } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
45113       return DecodeImageResult(id_dfc_status.message());
45114     } else if (io_buf.meta.closed) {
45115       return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
45116     } else {
45117       std::string error_message = input.CopyIn(&io_buf);
45118       if (!error_message.empty()) {
45119         return DecodeImageResult(std::move(error_message));
45120       }
45121     }
45122   }
45123 
45124   // Decode the frame (the pixels).
45125   //
45126   // From here on, always returns the pixel_buffer. If we get this far, we can
45127   // still display a partial image, even if we encounter an error.
45128   std::string message("");
45129   if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&
45130       frame_config.overwrite_instead_of_blend()) {
45131     pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;
45132   }
45133   while (true) {
45134     wuffs_base__status id_df_status =
45135         image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
45136                                     alloc_workbuf_result.workbuf, nullptr);
45137     if (id_df_status.repr == nullptr) {
45138       break;
45139     } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
45140       message = id_df_status.message();
45141       break;
45142     } else if (io_buf.meta.closed) {
45143       message = DecodeImage_UnexpectedEndOfFile;
45144       break;
45145     } else {
45146       std::string error_message = input.CopyIn(&io_buf);
45147       if (!error_message.empty()) {
45148         message = std::move(error_message);
45149         break;
45150       }
45151     }
45152   }
45153   return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
45154                            pixel_buffer, std::move(message));
45155 }
45156 
45157 }  // namespace
45158 
45159 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)45160 DecodeImage(DecodeImageCallbacks& callbacks,
45161             sync_io::Input& input,
45162             DecodeImageArgQuirks quirks,
45163             DecodeImageArgFlags flags,
45164             DecodeImageArgPixelBlend pixel_blend,
45165             DecodeImageArgBackgroundColor background_color,
45166             DecodeImageArgMaxInclDimension max_incl_dimension,
45167             DecodeImageArgMaxInclMetadataLength max_incl_metadata_length) {
45168   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
45169   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
45170   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
45171   if (!io_buf) {
45172     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);
45173     fallback_io_buf =
45174         wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);
45175     io_buf = &fallback_io_buf;
45176   }
45177 
45178   wuffs_base__image_decoder::unique_ptr image_decoder(nullptr, &free);
45179   DecodeImageResult result =
45180       DecodeImage0(image_decoder, callbacks, input, *io_buf, quirks.repr,
45181                    flags.repr, pixel_blend.repr, background_color.repr,
45182                    max_incl_dimension.repr, max_incl_metadata_length.repr);
45183   callbacks.Done(result, input, *io_buf, std::move(image_decoder));
45184   return result;
45185 }
45186 
45187 }  // namespace wuffs_aux
45188 
45189 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
45190         // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
45191 
45192 // ---------------- Auxiliary - JSON
45193 
45194 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)
45195 
45196 #include <utility>
45197 
45198 namespace wuffs_aux {
45199 
DecodeJsonResult(std::string && error_message0,uint64_t cursor_position0)45200 DecodeJsonResult::DecodeJsonResult(std::string&& error_message0,
45201                                    uint64_t cursor_position0)
45202     : error_message(std::move(error_message0)),
45203       cursor_position(cursor_position0) {}
45204 
~DecodeJsonCallbacks()45205 DecodeJsonCallbacks::~DecodeJsonCallbacks() {}
45206 
45207 void  //
Done(DecodeJsonResult & result,sync_io::Input & input,IOBuffer & buffer)45208 DecodeJsonCallbacks::Done(DecodeJsonResult& result,
45209                           sync_io::Input& input,
45210                           IOBuffer& buffer) {}
45211 
45212 const char DecodeJson_BadJsonPointer[] =  //
45213     "wuffs_aux::DecodeJson: bad JSON Pointer";
45214 const char DecodeJson_NoMatch[] =  //
45215     "wuffs_aux::DecodeJson: no match";
45216 
DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)45217 DecodeJsonArgQuirks::DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)
45218     : repr(repr0) {}
45219 
DecodeJsonArgQuirks(uint32_t * ptr0,size_t len0)45220 DecodeJsonArgQuirks::DecodeJsonArgQuirks(uint32_t* ptr0, size_t len0)
45221     : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
45222 
45223 DecodeJsonArgQuirks  //
DefaultValue()45224 DecodeJsonArgQuirks::DefaultValue() {
45225   return DecodeJsonArgQuirks(wuffs_base__empty_slice_u32());
45226 }
45227 
DecodeJsonArgJsonPointer(std::string repr0)45228 DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0)
45229     : repr(repr0) {}
45230 
45231 DecodeJsonArgJsonPointer  //
DefaultValue()45232 DecodeJsonArgJsonPointer::DefaultValue() {
45233   return DecodeJsonArgJsonPointer(std::string());
45234 }
45235 
45236 // --------
45237 
45238 #define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN                          \
45239   while (tok_buf.meta.ri >= tok_buf.meta.wi) {                              \
45240     if (tok_status.repr == nullptr) {                                       \
45241       goto done;                                                            \
45242     } else if (tok_status.repr == wuffs_base__suspension__short_write) {    \
45243       tok_buf.compact();                                                    \
45244     } else if (tok_status.repr == wuffs_base__suspension__short_read) {     \
45245       if (!io_error_message.empty()) {                                      \
45246         ret_error_message = std::move(io_error_message);                    \
45247         goto done;                                                          \
45248       } else if (cursor_index != io_buf->meta.ri) {                         \
45249         ret_error_message =                                                 \
45250             "wuffs_aux::DecodeJson: internal error: bad cursor_index";      \
45251         goto done;                                                          \
45252       } else if (io_buf->meta.closed) {                                     \
45253         ret_error_message =                                                 \
45254             "wuffs_aux::DecodeJson: internal error: io_buf is closed";      \
45255         goto done;                                                          \
45256       }                                                                     \
45257       io_buf->compact();                                                    \
45258       if (io_buf->meta.wi >= io_buf->data.len) {                            \
45259         ret_error_message =                                                 \
45260             "wuffs_aux::DecodeJson: internal error: io_buf is full";        \
45261         goto done;                                                          \
45262       }                                                                     \
45263       cursor_index = io_buf->meta.ri;                                       \
45264       io_error_message = input.CopyIn(io_buf);                              \
45265     } else {                                                                \
45266       ret_error_message = tok_status.message();                             \
45267       goto done;                                                            \
45268     }                                                                       \
45269     tok_status =                                                            \
45270         dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
45271     if ((tok_buf.meta.ri > tok_buf.meta.wi) ||                              \
45272         (tok_buf.meta.wi > tok_buf.data.len) ||                             \
45273         (io_buf->meta.ri > io_buf->meta.wi) ||                              \
45274         (io_buf->meta.wi > io_buf->data.len)) {                             \
45275       ret_error_message =                                                   \
45276           "wuffs_aux::DecodeJson: internal error: bad buffer indexes";      \
45277       goto done;                                                            \
45278     }                                                                       \
45279   }                                                                         \
45280   wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];            \
45281   uint64_t token_len = token.length();                                      \
45282   if ((io_buf->meta.ri < cursor_index) ||                                   \
45283       ((io_buf->meta.ri - cursor_index) < token_len)) {                     \
45284     ret_error_message =                                                     \
45285         "wuffs_aux::DecodeJson: internal error: bad token indexes";         \
45286     goto done;                                                              \
45287   }                                                                         \
45288   uint8_t* token_ptr = io_buf->data.ptr + cursor_index;                     \
45289   (void)(token_ptr);                                                        \
45290   cursor_index += static_cast<size_t>(token_len)
45291 
45292 // --------
45293 
45294 namespace {
45295 
45296 // DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
45297 // etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
45298 // out of bounds.
45299 //
45300 // The string returned is unescaped. If calling it again, this time with i=8,
45301 // the "b~1z" substring would be returned as "b/z".
45302 std::pair<std::string, size_t>  //
DecodeJson_SplitJsonPointer(std::string & s,size_t i,bool allow_tilde_n_tilde_r_tilde_t)45303 DecodeJson_SplitJsonPointer(std::string& s,
45304                             size_t i,
45305                             bool allow_tilde_n_tilde_r_tilde_t) {
45306   std::string fragment;
45307   if (i > s.size()) {
45308     return std::make_pair(std::string(), 0);
45309   }
45310   while (i < s.size()) {
45311     char c = s[i];
45312     if (c == '/') {
45313       break;
45314     } else if (c != '~') {
45315       fragment.push_back(c);
45316       i++;
45317       continue;
45318     }
45319     i++;
45320     if (i >= s.size()) {
45321       return std::make_pair(std::string(), 0);
45322     }
45323     c = s[i];
45324     if (c == '0') {
45325       fragment.push_back('~');
45326       i++;
45327       continue;
45328     } else if (c == '1') {
45329       fragment.push_back('/');
45330       i++;
45331       continue;
45332     } else if (allow_tilde_n_tilde_r_tilde_t) {
45333       if (c == 'n') {
45334         fragment.push_back('\n');
45335         i++;
45336         continue;
45337       } else if (c == 'r') {
45338         fragment.push_back('\r');
45339         i++;
45340         continue;
45341       } else if (c == 't') {
45342         fragment.push_back('\t');
45343         i++;
45344         continue;
45345       }
45346     }
45347     return std::make_pair(std::string(), 0);
45348   }
45349   return std::make_pair(std::move(fragment), i);
45350 }
45351 
45352 // --------
45353 
45354 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)45355 DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,
45356                                    wuffs_base__status& tok_status,
45357                                    wuffs_json__decoder::unique_ptr& dec,
45358                                    wuffs_base__io_buffer* io_buf,
45359                                    std::string& io_error_message,
45360                                    size_t& cursor_index,
45361                                    sync_io::Input& input,
45362                                    std::string& json_pointer_fragment) {
45363   std::string ret_error_message;
45364   while (true) {
45365     WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45366 
45367     int64_t vbc = token.value_base_category();
45368     uint64_t vbd = token.value_base_detail();
45369     if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
45370       continue;
45371     } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||
45372                !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {
45373       return DecodeJson_NoMatch;
45374     } else if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST) {
45375       goto do_list;
45376     }
45377     goto do_dict;
45378   }
45379 
45380 do_dict:
45381   // Alternate between these two things:
45382   //  1. Decode the next dict key (a string). If it matches the fragment, we're
45383   //    done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)
45384   //    so that there was no next dict key, we're done (failure).
45385   //  2. Otherwise, skip the next dict value.
45386   while (true) {
45387     for (std::string str; true;) {
45388       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45389 
45390       int64_t vbc = token.value_base_category();
45391       uint64_t vbd = token.value_base_detail();
45392       switch (vbc) {
45393         case WUFFS_BASE__TOKEN__VBC__FILLER:
45394           continue;
45395 
45396         case WUFFS_BASE__TOKEN__VBC__STRUCTURE:
45397           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45398             goto fail;
45399           }
45400           return DecodeJson_NoMatch;
45401 
45402         case WUFFS_BASE__TOKEN__VBC__STRING: {
45403           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
45404             // No-op.
45405           } else if (vbd &
45406                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
45407             const char* ptr =  // Convert from (uint8_t*).
45408                 static_cast<const char*>(static_cast<void*>(token_ptr));
45409             str.append(ptr, static_cast<size_t>(token_len));
45410           } else {
45411             goto fail;
45412           }
45413           break;
45414         }
45415 
45416         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
45417           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
45418           size_t n = wuffs_base__utf_8__encode(
45419               wuffs_base__make_slice_u8(
45420                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
45421               static_cast<uint32_t>(vbd));
45422           const char* ptr =  // Convert from (uint8_t*).
45423               static_cast<const char*>(static_cast<void*>(&u[0]));
45424           str.append(ptr, n);
45425           break;
45426         }
45427 
45428         default:
45429           goto fail;
45430       }
45431 
45432       if (token.continued()) {
45433         continue;
45434       }
45435       if (str == json_pointer_fragment) {
45436         return "";
45437       }
45438       goto skip_the_next_dict_value;
45439     }
45440 
45441   skip_the_next_dict_value:
45442     for (uint32_t skip_depth = 0; true;) {
45443       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45444 
45445       int64_t vbc = token.value_base_category();
45446       uint64_t vbd = token.value_base_detail();
45447       if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
45448         continue;
45449       } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
45450         if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45451           skip_depth++;
45452           continue;
45453         }
45454         skip_depth--;
45455       }
45456 
45457       if (skip_depth == 0) {
45458         break;
45459       }
45460     }  // skip_the_next_dict_value
45461   }    // do_dict
45462 
45463 do_list:
45464   do {
45465     wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(
45466         wuffs_base__make_slice_u8(
45467             static_cast<uint8_t*>(static_cast<void*>(
45468                 const_cast<char*>(json_pointer_fragment.data()))),
45469             json_pointer_fragment.size()),
45470         WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
45471     if (!result_u64.status.is_ok()) {
45472       return DecodeJson_NoMatch;
45473     }
45474     uint64_t remaining = result_u64.value;
45475     if (remaining == 0) {
45476       goto check_that_a_value_follows;
45477     }
45478     for (uint32_t skip_depth = 0; true;) {
45479       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45480 
45481       int64_t vbc = token.value_base_category();
45482       uint64_t vbd = token.value_base_detail();
45483       if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
45484         continue;
45485       } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
45486         if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45487           skip_depth++;
45488           continue;
45489         }
45490         if (skip_depth == 0) {
45491           return DecodeJson_NoMatch;
45492         }
45493         skip_depth--;
45494       }
45495 
45496       if (skip_depth > 0) {
45497         continue;
45498       }
45499       remaining--;
45500       if (remaining == 0) {
45501         goto check_that_a_value_follows;
45502       }
45503     }
45504   } while (false);  // do_list
45505 
45506 check_that_a_value_follows:
45507   while (true) {
45508     WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45509 
45510     int64_t vbc = token.value_base_category();
45511     uint64_t vbd = token.value_base_detail();
45512     if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
45513       continue;
45514     }
45515 
45516     // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
45517     // that we're only peeking at the next token.
45518     tok_buf.meta.ri--;
45519     cursor_index -= static_cast<size_t>(token_len);
45520 
45521     if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&
45522         (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {
45523       return DecodeJson_NoMatch;
45524     }
45525     return "";
45526   }  // check_that_a_value_follows
45527 
45528 fail:
45529   return "wuffs_aux::DecodeJson: internal error: unexpected token";
45530 done:
45531   return ret_error_message;
45532 }
45533 
45534 }  // namespace
45535 
45536 // --------
45537 
45538 DecodeJsonResult  //
DecodeJson(DecodeJsonCallbacks & callbacks,sync_io::Input & input,DecodeJsonArgQuirks quirks,DecodeJsonArgJsonPointer json_pointer)45539 DecodeJson(DecodeJsonCallbacks& callbacks,
45540            sync_io::Input& input,
45541            DecodeJsonArgQuirks quirks,
45542            DecodeJsonArgJsonPointer json_pointer) {
45543   // Prepare the wuffs_base__io_buffer and the resultant error_message.
45544   wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
45545   wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
45546   std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
45547   if (!io_buf) {
45548     fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
45549     fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
45550     io_buf = &fallback_io_buf;
45551   }
45552   // cursor_index is discussed at
45553   // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
45554   size_t cursor_index = 0;
45555   std::string ret_error_message;
45556   std::string io_error_message;
45557 
45558   do {
45559     // Prepare the low-level JSON decoder.
45560     wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();
45561     if (!dec) {
45562       ret_error_message = "wuffs_aux::DecodeJson: out of memory";
45563       goto done;
45564     } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
45565       ret_error_message =
45566           "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
45567       goto done;
45568     }
45569     bool allow_tilde_n_tilde_r_tilde_t = false;
45570     for (size_t i = 0; i < quirks.repr.len; i++) {
45571       dec->set_quirk_enabled(quirks.repr.ptr[i], true);
45572       if (quirks.repr.ptr[i] ==
45573           WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {
45574         allow_tilde_n_tilde_r_tilde_t = true;
45575       }
45576     }
45577 
45578     // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
45579     wuffs_base__token tok_array[256];
45580     wuffs_base__token_buffer tok_buf =
45581         wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
45582             &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
45583     wuffs_base__status tok_status =
45584         dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
45585 
45586     // Prepare other state.
45587     int32_t depth = 0;
45588     std::string str;
45589 
45590     // Walk the (optional) JSON Pointer.
45591     for (size_t i = 0; i < json_pointer.repr.size();) {
45592       if (json_pointer.repr[i] != '/') {
45593         ret_error_message = DecodeJson_BadJsonPointer;
45594         goto done;
45595       }
45596       std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
45597           json_pointer.repr, i + 1, allow_tilde_n_tilde_r_tilde_t);
45598       i = split.second;
45599       if (i == 0) {
45600         ret_error_message = DecodeJson_BadJsonPointer;
45601         goto done;
45602       }
45603       ret_error_message = DecodeJson_WalkJsonPointerFragment(
45604           tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,
45605           input, split.first);
45606       if (!ret_error_message.empty()) {
45607         goto done;
45608       }
45609     }
45610 
45611     // Loop, doing these two things:
45612     //  1. Get the next token.
45613     //  2. Process that token.
45614     while (true) {
45615       WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45616 
45617       int64_t vbc = token.value_base_category();
45618       uint64_t vbd = token.value_base_detail();
45619       switch (vbc) {
45620         case WUFFS_BASE__TOKEN__VBC__FILLER:
45621           continue;
45622 
45623         case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
45624           if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45625             ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
45626             if (!ret_error_message.empty()) {
45627               goto done;
45628             }
45629             depth++;
45630             if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
45631               ret_error_message =
45632                   "wuffs_aux::DecodeJson: internal error: bad depth";
45633               goto done;
45634             }
45635             continue;
45636           }
45637           ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
45638           depth--;
45639           if (depth < 0) {
45640             ret_error_message =
45641                 "wuffs_aux::DecodeJson: internal error: bad depth";
45642             goto done;
45643           }
45644           goto parsed_a_value;
45645         }
45646 
45647         case WUFFS_BASE__TOKEN__VBC__STRING: {
45648           if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
45649             // No-op.
45650           } else if (vbd &
45651                      WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
45652             const char* ptr =  // Convert from (uint8_t*).
45653                 static_cast<const char*>(static_cast<void*>(token_ptr));
45654             str.append(ptr, static_cast<size_t>(token_len));
45655           } else {
45656             goto fail;
45657           }
45658           if (token.continued()) {
45659             continue;
45660           }
45661           ret_error_message = callbacks.AppendTextString(std::move(str));
45662           str.clear();
45663           goto parsed_a_value;
45664         }
45665 
45666         case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
45667           uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
45668           size_t n = wuffs_base__utf_8__encode(
45669               wuffs_base__make_slice_u8(
45670                   &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
45671               static_cast<uint32_t>(vbd));
45672           const char* ptr =  // Convert from (uint8_t*).
45673               static_cast<const char*>(static_cast<void*>(&u[0]));
45674           str.append(ptr, n);
45675           if (token.continued()) {
45676             continue;
45677           }
45678           goto fail;
45679         }
45680 
45681         case WUFFS_BASE__TOKEN__VBC__LITERAL: {
45682           ret_error_message =
45683               (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)
45684                   ? callbacks.AppendNull()
45685                   : callbacks.AppendBool(vbd &
45686                                          WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
45687           goto parsed_a_value;
45688         }
45689 
45690         case WUFFS_BASE__TOKEN__VBC__NUMBER: {
45691           if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {
45692             if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {
45693               wuffs_base__result_i64 r = wuffs_base__parse_number_i64(
45694                   wuffs_base__make_slice_u8(token_ptr,
45695                                             static_cast<size_t>(token_len)),
45696                   WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
45697               if (r.status.is_ok()) {
45698                 ret_error_message = callbacks.AppendI64(r.value);
45699                 goto parsed_a_value;
45700               }
45701             }
45702             if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {
45703               wuffs_base__result_f64 r = wuffs_base__parse_number_f64(
45704                   wuffs_base__make_slice_u8(token_ptr,
45705                                             static_cast<size_t>(token_len)),
45706                   WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
45707               if (r.status.is_ok()) {
45708                 ret_error_message = callbacks.AppendF64(r.value);
45709                 goto parsed_a_value;
45710               }
45711             }
45712           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {
45713             ret_error_message = callbacks.AppendF64(
45714                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45715                     0xFFF0000000000000ul));
45716             goto parsed_a_value;
45717           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {
45718             ret_error_message = callbacks.AppendF64(
45719                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45720                     0x7FF0000000000000ul));
45721             goto parsed_a_value;
45722           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {
45723             ret_error_message = callbacks.AppendF64(
45724                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45725                     0xFFFFFFFFFFFFFFFFul));
45726             goto parsed_a_value;
45727           } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {
45728             ret_error_message = callbacks.AppendF64(
45729                 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45730                     0x7FFFFFFFFFFFFFFFul));
45731             goto parsed_a_value;
45732           }
45733           goto fail;
45734         }
45735       }
45736 
45737     fail:
45738       ret_error_message =
45739           "wuffs_aux::DecodeJson: internal error: unexpected token";
45740       goto done;
45741 
45742     parsed_a_value:
45743       // If an error was encountered, we are done. Otherwise, (depth == 0)
45744       // after parsing a value is equivalent to having decoded the entire JSON
45745       // value (for an empty json_pointer query) or having decoded the
45746       // pointed-to JSON value (for a non-empty json_pointer query). In the
45747       // latter case, we are also done.
45748       //
45749       // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
45750       // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
45751       // the entire JSON value should also consume any trailing filler, in case
45752       // the DecodeJson caller wants to subsequently check that the input is
45753       // completely exhausted (and otherwise raise "valid JSON followed by
45754       // further (unexpected) data"). We aren't done yet. Instead, keep the
45755       // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
45756       // decode_tokens returns an ok status.
45757       if (!ret_error_message.empty() ||
45758           ((depth == 0) && !json_pointer.repr.empty())) {
45759         goto done;
45760       }
45761     }
45762   } while (false);
45763 
45764 done:
45765   DecodeJsonResult result(
45766       std::move(ret_error_message),
45767       wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
45768   callbacks.Done(result, input, *io_buf);
45769   return result;
45770 }
45771 
45772 #undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN
45773 
45774 }  // namespace wuffs_aux
45775 
45776 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
45777         // defined(WUFFS_CONFIG__MODULE__AUX__JSON)
45778 
45779 #endif  // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
45780 
45781 #endif  // WUFFS_IMPLEMENTATION
45782 
45783 #if defined(__GNUC__)
45784 #pragma GCC diagnostic pop
45785 #elif defined(__clang__)
45786 #pragma clang diagnostic pop
45787 #endif
45788 
45789 #endif  // WUFFS_INCLUDE_GUARD
45790