• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Copyright 2017 The Wuffs Authors.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 //    https://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #include <stdbool.h>
26 #include <stdint.h>
27 #include <string.h>
28 
29 // GCC does not warn for unused *static inline* functions, but clang does.
30 #ifdef __clang__
31 #pragma clang diagnostic push
32 #pragma clang diagnostic ignored "-Wunused-function"
33 #endif
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 // Wuffs assumes that:
40 //  - converting a uint32_t to a size_t will never overflow.
41 //  - converting a size_t to a uint64_t will never overflow.
42 #ifdef __WORDSIZE
43 #if (__WORDSIZE != 32) && (__WORDSIZE != 64)
44 #error "Wuffs requires a word size of either 32 or 64 bits"
45 #endif
46 #endif
47 
48 // WUFFS_VERSION is the major.minor.patch version, as per https://semver.org/,
49 // as a uint64_t. The major number is the high 32 bits. The minor number is the
50 // middle 16 bits. The patch number is the low 16 bits. The pre-release label
51 // and build metadata are part of the string representation (such as
52 // "1.2.3-beta+456.20181231") but not the uint64_t representation.
53 //
54 // WUFFS_VERSION_PRE_RELEASE_LABEL (such as "", "beta" or "rc.1") being
55 // non-empty denotes a developer preview, not a release version, and has no
56 // backwards or forwards compatibility guarantees.
57 //
58 // WUFFS_VERSION_BUILD_METADATA_XXX, if non-zero, are the number of commits and
59 // the last commit date in the repository used to build this library. Within
60 // each major.minor branch, the commit count should increase monotonically.
61 //
62 // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision
63 // 3037f1e389b54f9721161cc92c9b00372254cafc committed on 2019-07-07.
64 #define WUFFS_VERSION ((uint64_t)0x0000000000020000)
65 #define WUFFS_VERSION_MAJOR ((uint64_t)0x00000000)
66 #define WUFFS_VERSION_MINOR ((uint64_t)0x0002)
67 #define WUFFS_VERSION_PATCH ((uint64_t)0x0000)
68 #define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.44"
69 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 1776
70 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20190707
71 #define WUFFS_VERSION_STRING "0.2.0-alpha.44+1776.20190707"
72 
73 // Define WUFFS_CONFIG__STATIC_FUNCTIONS to make all of Wuffs' functions have
74 // static storage. The motivation is discussed in the "ALLOW STATIC
75 // IMPLEMENTATION" section of
76 // https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
77 #ifdef WUFFS_CONFIG__STATIC_FUNCTIONS
78 #define WUFFS_BASE__MAYBE_STATIC static
79 #else
80 #define WUFFS_BASE__MAYBE_STATIC
81 #endif
82 
83 #if defined(__clang__)
84 #define WUFFS_BASE__POTENTIALLY_UNUSED_FIELD __attribute__((unused))
85 #else
86 #define WUFFS_BASE__POTENTIALLY_UNUSED_FIELD
87 #endif
88 
89 // Clang also defines "__GNUC__".
90 #if defined(__GNUC__)
91 #define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused))
92 #define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result))
93 #else
94 #define WUFFS_BASE__POTENTIALLY_UNUSED
95 #define WUFFS_BASE__WARN_UNUSED_RESULT
96 #endif
97 
98 // Flags for wuffs_foo__bar__initialize functions.
99 
100 #define WUFFS_INITIALIZE__DEFAULT_OPTIONS ((uint32_t)0x00000000)
101 
102 // WUFFS_INITIALIZE__ALREADY_ZEROED means that the "self" receiver struct value
103 // has already been set to all zeroes.
104 #define WUFFS_INITIALIZE__ALREADY_ZEROED ((uint32_t)0x00000001)
105 
106 // WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED means that, absent
107 // WUFFS_INITIALIZE__ALREADY_ZEROED, only some of the "self" receiver struct
108 // value will be set to all zeroes. Internal buffers, which tend to be a large
109 // proportion of the struct's size, will be left uninitialized. Internal means
110 // that the buffer is contained by the receiver struct, as opposed to being
111 // passed as a separately allocated "work buffer".
112 //
113 // With or without this bit set, the Wuffs compiler still enforces that no
114 // reads or writes will overflow internal buffers' bounds. Even with this bit
115 // set, the Wuffs standard library also considers reading from an uninitialized
116 // buffer to be a bug, and strives to never do so, but unlike buffer overflows,
117 // it is not a bug class that the Wuffs compiler eliminates.
118 //
119 // For those paranoid about security, leave this bit unset, so that
120 // wuffs_foo__bar__initialize will initialize the entire struct value to zeroes
121 // (unless WUFFS_INITIALIZE__ALREADY_ZEROED is set).
122 //
123 // Setting this bit gives a small absolute improvement on micro-benchmarks, but
124 // this can be a large relative effect, up to 2x faster, when the actual work
125 // to be done is also small, such as decompressing small input. See git commit
126 // 438fc105 "Move some struct fields to private_data" for some numbers and a
127 // discussion, noting that its commit message was written before this
128 // WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED option was defined.
129 #define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \
130   ((uint32_t)0x00000002)
131 
132 // --------
133 
134 // wuffs_base__empty_struct is used when a Wuffs function returns an empty
135 // struct. In C, if a function f returns void, you can't say "x = f()", but in
136 // Wuffs, if a function g returns empty, you can say "y = g()".
137 typedef struct {
138   // private_impl is a placeholder field. It isn't explicitly used, except that
139   // without it, the sizeof a struct with no fields can differ across C/C++
140   // compilers, and it is undefined behavior in C99. For example, gcc says that
141   // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
142   // ABI incompatibility if a Wuffs .c file is processed by one compiler and
143   // its .h file with another compiler.
144   //
145   // Instead, we explicitly insert an otherwise unused field, so that the
146   // sizeof this struct is always 1.
147   uint8_t private_impl;
148 } wuffs_base__empty_struct;
149 
150 static inline wuffs_base__empty_struct  //
wuffs_base__make_empty_struct()151 wuffs_base__make_empty_struct() {
152   wuffs_base__empty_struct ret;
153   ret.private_impl = 0;
154   return ret;
155 }
156 
157 // wuffs_base__utility is a placeholder receiver type. It enables what Java
158 // calls static methods, as opposed to regular methods.
159 typedef struct {
160   // private_impl is a placeholder field. It isn't explicitly used, except that
161   // without it, the sizeof a struct with no fields can differ across C/C++
162   // compilers, and it is undefined behavior in C99. For example, gcc says that
163   // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
164   // ABI incompatibility if a Wuffs .c file is processed by one compiler and
165   // its .h file with another compiler.
166   //
167   // Instead, we explicitly insert an otherwise unused field, so that the
168   // sizeof this struct is always 1.
169   uint8_t private_impl;
170 } wuffs_base__utility;
171 
172 // --------
173 
174 // A status is either NULL (meaning OK) or a string message. That message is
175 // human-readable, for programmers, but it is not for end users. It is not
176 // localized, and does not contain additional contextual information such as a
177 // source filename.
178 //
179 // Status strings are statically allocated and should never be free'd. They can
180 // be compared by the == operator and not just by strcmp.
181 //
182 // Statuses come in four categories:
183 //  - OK:          the request was completed, successfully.
184 //  - Warnings:    the request was completed, unsuccessfully.
185 //  - Suspensions: the request was not completed, but can be re-tried.
186 //  - Errors:      the request was not completed, permanently.
187 //
188 // When a function returns an incomplete status, a suspension means that that
189 // function should be called again within a new context, such as after flushing
190 // or re-filling an I/O buffer. An error means that an irrecoverable failure
191 // state was reached.
192 typedef const char* wuffs_base__status;
193 
194 extern const char* wuffs_base__warning__end_of_data;
195 extern const char* wuffs_base__warning__metadata_reported;
196 extern const char* wuffs_base__suspension__short_read;
197 extern const char* wuffs_base__suspension__short_write;
198 extern const char* wuffs_base__error__bad_i_o_position;
199 extern const char* wuffs_base__error__bad_argument_length_too_short;
200 extern const char* wuffs_base__error__bad_argument;
201 extern const char* wuffs_base__error__bad_call_sequence;
202 extern const char* wuffs_base__error__bad_receiver;
203 extern const char* wuffs_base__error__bad_restart;
204 extern const char* wuffs_base__error__bad_sizeof_receiver;
205 extern const char* wuffs_base__error__bad_workbuf_length;
206 extern const char* wuffs_base__error__bad_wuffs_version;
207 extern const char* wuffs_base__error__cannot_return_a_suspension;
208 extern const char* wuffs_base__error__disabled_by_previous_error;
209 extern const char* wuffs_base__error__initialize_falsely_claimed_already_zeroed;
210 extern const char* wuffs_base__error__initialize_not_called;
211 extern const char* wuffs_base__error__interleaved_coroutine_calls;
212 extern const char* wuffs_base__error__not_enough_data;
213 extern const char* wuffs_base__error__unsupported_option;
214 extern const char* wuffs_base__error__too_much_data;
215 
216 static inline bool  //
wuffs_base__status__is_complete(wuffs_base__status z)217 wuffs_base__status__is_complete(wuffs_base__status z) {
218   return (z == NULL) || ((*z != '$') && (*z != '#'));
219 }
220 
221 static inline bool  //
wuffs_base__status__is_error(wuffs_base__status z)222 wuffs_base__status__is_error(wuffs_base__status z) {
223   return z && (*z == '#');
224 }
225 
226 static inline bool  //
wuffs_base__status__is_ok(wuffs_base__status z)227 wuffs_base__status__is_ok(wuffs_base__status z) {
228   return z == NULL;
229 }
230 
231 static inline bool  //
wuffs_base__status__is_suspension(wuffs_base__status z)232 wuffs_base__status__is_suspension(wuffs_base__status z) {
233   return z && (*z == '$');
234 }
235 
236 static inline bool  //
wuffs_base__status__is_warning(wuffs_base__status z)237 wuffs_base__status__is_warning(wuffs_base__status z) {
238   return z && (*z != '$') && (*z != '#');
239 }
240 
241 // --------
242 
243 // FourCC constants.
244 
245 // International Color Consortium Profile.
246 #define WUFFS_BASE__FOURCC__ICCP 0x49434350
247 
248 // Extensible Metadata Platform.
249 #define WUFFS_BASE__FOURCC__XMP 0x584D5020
250 
251 // --------
252 
253 // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a
254 // second. See https://github.com/OculusVR/Flicks
255 typedef int64_t wuffs_base__flicks;
256 
257 #define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000)
258 #define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600)
259 
260 // ---------------- Numeric Types
261 
262 static inline uint8_t  //
wuffs_base__u8__min(uint8_t x,uint8_t y)263 wuffs_base__u8__min(uint8_t x, uint8_t y) {
264   return x < y ? x : y;
265 }
266 
267 static inline uint8_t  //
wuffs_base__u8__max(uint8_t x,uint8_t y)268 wuffs_base__u8__max(uint8_t x, uint8_t y) {
269   return x > y ? x : y;
270 }
271 
272 static inline uint16_t  //
wuffs_base__u16__min(uint16_t x,uint16_t y)273 wuffs_base__u16__min(uint16_t x, uint16_t y) {
274   return x < y ? x : y;
275 }
276 
277 static inline uint16_t  //
wuffs_base__u16__max(uint16_t x,uint16_t y)278 wuffs_base__u16__max(uint16_t x, uint16_t y) {
279   return x > y ? x : y;
280 }
281 
282 static inline uint32_t  //
wuffs_base__u32__min(uint32_t x,uint32_t y)283 wuffs_base__u32__min(uint32_t x, uint32_t y) {
284   return x < y ? x : y;
285 }
286 
287 static inline uint32_t  //
wuffs_base__u32__max(uint32_t x,uint32_t y)288 wuffs_base__u32__max(uint32_t x, uint32_t y) {
289   return x > y ? x : y;
290 }
291 
292 static inline uint64_t  //
wuffs_base__u64__min(uint64_t x,uint64_t y)293 wuffs_base__u64__min(uint64_t x, uint64_t y) {
294   return x < y ? x : y;
295 }
296 
297 static inline uint64_t  //
wuffs_base__u64__max(uint64_t x,uint64_t y)298 wuffs_base__u64__max(uint64_t x, uint64_t y) {
299   return x > y ? x : y;
300 }
301 
302 // --------
303 
304 // Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms
305 // are per https://locklessinc.com/articles/sat_arithmetic/
306 //
307 // It is important that the underlying types are unsigned integers, as signed
308 // integer arithmetic overflow is undefined behavior in C.
309 
310 static inline uint8_t  //
wuffs_base__u8__sat_add(uint8_t x,uint8_t y)311 wuffs_base__u8__sat_add(uint8_t x, uint8_t y) {
312   uint8_t res = (uint8_t)(x + y);
313   res |= (uint8_t)(-(res < x));
314   return res;
315 }
316 
317 static inline uint8_t  //
wuffs_base__u8__sat_sub(uint8_t x,uint8_t y)318 wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) {
319   uint8_t res = (uint8_t)(x - y);
320   res &= (uint8_t)(-(res <= x));
321   return res;
322 }
323 
324 static inline uint16_t  //
wuffs_base__u16__sat_add(uint16_t x,uint16_t y)325 wuffs_base__u16__sat_add(uint16_t x, uint16_t y) {
326   uint16_t res = (uint16_t)(x + y);
327   res |= (uint16_t)(-(res < x));
328   return res;
329 }
330 
331 static inline uint16_t  //
wuffs_base__u16__sat_sub(uint16_t x,uint16_t y)332 wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) {
333   uint16_t res = (uint16_t)(x - y);
334   res &= (uint16_t)(-(res <= x));
335   return res;
336 }
337 
338 static inline uint32_t  //
wuffs_base__u32__sat_add(uint32_t x,uint32_t y)339 wuffs_base__u32__sat_add(uint32_t x, uint32_t y) {
340   uint32_t res = (uint32_t)(x + y);
341   res |= (uint32_t)(-(res < x));
342   return res;
343 }
344 
345 static inline uint32_t  //
wuffs_base__u32__sat_sub(uint32_t x,uint32_t y)346 wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) {
347   uint32_t res = (uint32_t)(x - y);
348   res &= (uint32_t)(-(res <= x));
349   return res;
350 }
351 
352 static inline uint64_t  //
wuffs_base__u64__sat_add(uint64_t x,uint64_t y)353 wuffs_base__u64__sat_add(uint64_t x, uint64_t y) {
354   uint64_t res = (uint64_t)(x + y);
355   res |= (uint64_t)(-(res < x));
356   return res;
357 }
358 
359 static inline uint64_t  //
wuffs_base__u64__sat_sub(uint64_t x,uint64_t y)360 wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) {
361   uint64_t res = (uint64_t)(x - y);
362   res &= (uint64_t)(-(res <= x));
363   return res;
364 }
365 
366 // ---------------- Slices and Tables
367 
368 // WUFFS_BASE__SLICE is a 1-dimensional buffer.
369 //
370 // len measures a number of elements, not necessarily a size in bytes.
371 //
372 // A value with all fields NULL or zero is a valid, empty slice.
373 #define WUFFS_BASE__SLICE(T) \
374   struct {                   \
375     T* ptr;                  \
376     size_t len;              \
377   }
378 
379 // WUFFS_BASE__TABLE is a 2-dimensional buffer.
380 //
381 // width height, and stride measure a number of elements, not necessarily a
382 // size in bytes.
383 //
384 // A value with all fields NULL or zero is a valid, empty table.
385 #define WUFFS_BASE__TABLE(T) \
386   struct {                   \
387     T* ptr;                  \
388     size_t width;            \
389     size_t height;           \
390     size_t stride;           \
391   }
392 
393 typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;
394 typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;
395 typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;
396 typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;
397 
398 typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8;
399 typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;
400 typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;
401 typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;
402 
403 static inline wuffs_base__slice_u8  //
wuffs_base__make_slice_u8(uint8_t * ptr,size_t len)404 wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {
405   wuffs_base__slice_u8 ret;
406   ret.ptr = ptr;
407   ret.len = len;
408   return ret;
409 }
410 
411 static inline wuffs_base__slice_u16  //
wuffs_base__make_slice_u16(uint16_t * ptr,size_t len)412 wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {
413   wuffs_base__slice_u16 ret;
414   ret.ptr = ptr;
415   ret.len = len;
416   return ret;
417 }
418 
419 static inline wuffs_base__slice_u32  //
wuffs_base__make_slice_u32(uint32_t * ptr,size_t len)420 wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {
421   wuffs_base__slice_u32 ret;
422   ret.ptr = ptr;
423   ret.len = len;
424   return ret;
425 }
426 
427 static inline wuffs_base__slice_u64  //
wuffs_base__make_slice_u64(uint64_t * ptr,size_t len)428 wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {
429   wuffs_base__slice_u64 ret;
430   ret.ptr = ptr;
431   ret.len = len;
432   return ret;
433 }
434 
435 static inline wuffs_base__slice_u8  //
wuffs_base__null_slice_u8()436 wuffs_base__null_slice_u8() {
437   wuffs_base__slice_u8 ret;
438   ret.ptr = NULL;
439   ret.len = 0;
440   return ret;
441 }
442 
443 static inline wuffs_base__table_u8  //
wuffs_base__null_table_u8()444 wuffs_base__null_table_u8() {
445   wuffs_base__table_u8 ret;
446   ret.ptr = NULL;
447   ret.width = 0;
448   ret.height = 0;
449   ret.stride = 0;
450   return ret;
451 }
452 
453 // wuffs_base__slice_u8__subslice_i returns s[i:].
454 //
455 // It returns an empty slice if i is out of bounds.
456 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s,uint64_t i)457 wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {
458   if ((i <= SIZE_MAX) && (i <= s.len)) {
459     return wuffs_base__make_slice_u8(s.ptr + i, s.len - i);
460   }
461   return wuffs_base__make_slice_u8(NULL, 0);
462 }
463 
464 // wuffs_base__slice_u8__subslice_j returns s[:j].
465 //
466 // It returns an empty slice if j is out of bounds.
467 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s,uint64_t j)468 wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {
469   if ((j <= SIZE_MAX) && (j <= s.len)) {
470     return wuffs_base__make_slice_u8(s.ptr, j);
471   }
472   return wuffs_base__make_slice_u8(NULL, 0);
473 }
474 
475 // wuffs_base__slice_u8__subslice_ij returns s[i:j].
476 //
477 // It returns an empty slice if i or j is out of bounds.
478 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,uint64_t i,uint64_t j)479 wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,
480                                   uint64_t i,
481                                   uint64_t j) {
482   if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {
483     return wuffs_base__make_slice_u8(s.ptr + i, j - i);
484   }
485   return wuffs_base__make_slice_u8(NULL, 0);
486 }
487 
488 // ---------------- Ranges and Rects
489 
490 // Ranges are either inclusive ("range_ii") or exclusive ("range_ie") on the
491 // high end. Both the "ii" and "ie" flavors are useful in practice.
492 //
493 // The "ei" and "ee" flavors also exist in theory, but aren't widely used. In
494 // Wuffs, the low end is always inclusive.
495 //
496 // The "ii" (closed interval) flavor is useful when refining e.g. "the set of
497 // all uint32_t values" to a contiguous subset: "uint32_t values in the closed
498 // interval [M, N]", for uint32_t values M and N. An unrefined type (in other
499 // words, the set of all uint32_t values) is not representable in the "ie"
500 // flavor because if N equals ((1<<32) - 1) then (N + 1) will overflow.
501 //
502 // On the other hand, the "ie" (half-open interval) flavor is recommended by
503 // Dijkstra's "Why numbering should start at zero" at
504 // http://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF and a further
505 // discussion of motivating rationale is at
506 // https://www.quora.com/Why-are-Python-ranges-half-open-exclusive-instead-of-closed-inclusive
507 //
508 // For example, with "ie", the number of elements in "uint32_t values in the
509 // half-open interval [M, N)" is equal to max(0, N-M). Furthermore, that number
510 // of elements (in one dimension, a length, in two dimensions, a width or
511 // height) is itself representable as a uint32_t without overflow, again for
512 // uint32_t values M and N. In the contrasting "ii" flavor, the length of the
513 // closed interval [0, (1<<32) - 1] is 1<<32, which cannot be represented as a
514 // uint32_t. In Wuffs, because of this potential overflow, the "ie" flavor has
515 // length / width / height methods, but the "ii" flavor does not.
516 //
517 // It is valid for min > max (for range_ii) or for min >= max (for range_ie),
518 // in which case the range is empty. There are multiple representations of an
519 // empty range.
520 
521 typedef struct wuffs_base__range_ii_u32__struct {
522   uint32_t min_incl;
523   uint32_t max_incl;
524 
525 #ifdef __cplusplus
526   inline bool is_empty() const;
527   inline bool equals(wuffs_base__range_ii_u32__struct s) const;
528   inline wuffs_base__range_ii_u32__struct intersect(
529       wuffs_base__range_ii_u32__struct s) const;
530   inline wuffs_base__range_ii_u32__struct unite(
531       wuffs_base__range_ii_u32__struct s) const;
532   inline bool contains(uint32_t x) const;
533   inline bool contains_range(wuffs_base__range_ii_u32__struct s) const;
534 #endif  // __cplusplus
535 
536 } wuffs_base__range_ii_u32;
537 
538 static inline wuffs_base__range_ii_u32  //
wuffs_base__make_range_ii_u32(uint32_t min_incl,uint32_t max_incl)539 wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) {
540   wuffs_base__range_ii_u32 ret;
541   ret.min_incl = min_incl;
542   ret.max_incl = max_incl;
543   return ret;
544 }
545 
546 static inline bool  //
wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32 * r)547 wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) {
548   return r->min_incl > r->max_incl;
549 }
550 
551 static inline bool  //
wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)552 wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r,
553                                  wuffs_base__range_ii_u32 s) {
554   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
555          (wuffs_base__range_ii_u32__is_empty(r) &&
556           wuffs_base__range_ii_u32__is_empty(&s));
557 }
558 
559 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)560 wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r,
561                                     wuffs_base__range_ii_u32 s) {
562   wuffs_base__range_ii_u32 t;
563   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
564   t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl);
565   return t;
566 }
567 
568 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)569 wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r,
570                                 wuffs_base__range_ii_u32 s) {
571   if (wuffs_base__range_ii_u32__is_empty(r)) {
572     return s;
573   }
574   if (wuffs_base__range_ii_u32__is_empty(&s)) {
575     return *r;
576   }
577   wuffs_base__range_ii_u32 t;
578   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
579   t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl);
580   return t;
581 }
582 
583 static inline bool  //
wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32 * r,uint32_t x)584 wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r,
585                                    uint32_t x) {
586   return (r->min_incl <= x) && (x <= r->max_incl);
587 }
588 
589 static inline bool  //
wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)590 wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r,
591                                          wuffs_base__range_ii_u32 s) {
592   return wuffs_base__range_ii_u32__equals(
593       &s, wuffs_base__range_ii_u32__intersect(r, s));
594 }
595 
596 #ifdef __cplusplus
597 
598 inline bool  //
is_empty()599 wuffs_base__range_ii_u32::is_empty() const {
600   return wuffs_base__range_ii_u32__is_empty(this);
601 }
602 
603 inline bool  //
equals(wuffs_base__range_ii_u32 s)604 wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const {
605   return wuffs_base__range_ii_u32__equals(this, s);
606 }
607 
608 inline wuffs_base__range_ii_u32  //
intersect(wuffs_base__range_ii_u32 s)609 wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const {
610   return wuffs_base__range_ii_u32__intersect(this, s);
611 }
612 
613 inline wuffs_base__range_ii_u32  //
unite(wuffs_base__range_ii_u32 s)614 wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const {
615   return wuffs_base__range_ii_u32__unite(this, s);
616 }
617 
618 inline bool  //
contains(uint32_t x)619 wuffs_base__range_ii_u32::contains(uint32_t x) const {
620   return wuffs_base__range_ii_u32__contains(this, x);
621 }
622 
623 inline bool  //
contains_range(wuffs_base__range_ii_u32 s)624 wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const {
625   return wuffs_base__range_ii_u32__contains_range(this, s);
626 }
627 
628 #endif  // __cplusplus
629 
630 // --------
631 
632 typedef struct wuffs_base__range_ie_u32__struct {
633   uint32_t min_incl;
634   uint32_t max_excl;
635 
636 #ifdef __cplusplus
637   inline bool is_empty() const;
638   inline bool equals(wuffs_base__range_ie_u32__struct s) const;
639   inline wuffs_base__range_ie_u32__struct intersect(
640       wuffs_base__range_ie_u32__struct s) const;
641   inline wuffs_base__range_ie_u32__struct unite(
642       wuffs_base__range_ie_u32__struct s) const;
643   inline bool contains(uint32_t x) const;
644   inline bool contains_range(wuffs_base__range_ie_u32__struct s) const;
645   inline uint32_t length() const;
646 #endif  // __cplusplus
647 
648 } wuffs_base__range_ie_u32;
649 
650 static inline wuffs_base__range_ie_u32  //
wuffs_base__make_range_ie_u32(uint32_t min_incl,uint32_t max_excl)651 wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) {
652   wuffs_base__range_ie_u32 ret;
653   ret.min_incl = min_incl;
654   ret.max_excl = max_excl;
655   return ret;
656 }
657 
658 static inline bool  //
wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32 * r)659 wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) {
660   return r->min_incl >= r->max_excl;
661 }
662 
663 static inline bool  //
wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)664 wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r,
665                                  wuffs_base__range_ie_u32 s) {
666   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
667          (wuffs_base__range_ie_u32__is_empty(r) &&
668           wuffs_base__range_ie_u32__is_empty(&s));
669 }
670 
671 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)672 wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r,
673                                     wuffs_base__range_ie_u32 s) {
674   wuffs_base__range_ie_u32 t;
675   t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
676   t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl);
677   return t;
678 }
679 
680 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)681 wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r,
682                                 wuffs_base__range_ie_u32 s) {
683   if (wuffs_base__range_ie_u32__is_empty(r)) {
684     return s;
685   }
686   if (wuffs_base__range_ie_u32__is_empty(&s)) {
687     return *r;
688   }
689   wuffs_base__range_ie_u32 t;
690   t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
691   t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl);
692   return t;
693 }
694 
695 static inline bool  //
wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32 * r,uint32_t x)696 wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r,
697                                    uint32_t x) {
698   return (r->min_incl <= x) && (x < r->max_excl);
699 }
700 
701 static inline bool  //
wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)702 wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r,
703                                          wuffs_base__range_ie_u32 s) {
704   return wuffs_base__range_ie_u32__equals(
705       &s, wuffs_base__range_ie_u32__intersect(r, s));
706 }
707 
708 static inline uint32_t  //
wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32 * r)709 wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) {
710   return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl);
711 }
712 
713 #ifdef __cplusplus
714 
715 inline bool  //
is_empty()716 wuffs_base__range_ie_u32::is_empty() const {
717   return wuffs_base__range_ie_u32__is_empty(this);
718 }
719 
720 inline bool  //
equals(wuffs_base__range_ie_u32 s)721 wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const {
722   return wuffs_base__range_ie_u32__equals(this, s);
723 }
724 
725 inline wuffs_base__range_ie_u32  //
intersect(wuffs_base__range_ie_u32 s)726 wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const {
727   return wuffs_base__range_ie_u32__intersect(this, s);
728 }
729 
730 inline wuffs_base__range_ie_u32  //
unite(wuffs_base__range_ie_u32 s)731 wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const {
732   return wuffs_base__range_ie_u32__unite(this, s);
733 }
734 
735 inline bool  //
contains(uint32_t x)736 wuffs_base__range_ie_u32::contains(uint32_t x) const {
737   return wuffs_base__range_ie_u32__contains(this, x);
738 }
739 
740 inline bool  //
contains_range(wuffs_base__range_ie_u32 s)741 wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const {
742   return wuffs_base__range_ie_u32__contains_range(this, s);
743 }
744 
745 inline uint32_t  //
length()746 wuffs_base__range_ie_u32::length() const {
747   return wuffs_base__range_ie_u32__length(this);
748 }
749 
750 #endif  // __cplusplus
751 
752 // --------
753 
754 typedef struct wuffs_base__range_ii_u64__struct {
755   uint64_t min_incl;
756   uint64_t max_incl;
757 
758 #ifdef __cplusplus
759   inline bool is_empty() const;
760   inline bool equals(wuffs_base__range_ii_u64__struct s) const;
761   inline wuffs_base__range_ii_u64__struct intersect(
762       wuffs_base__range_ii_u64__struct s) const;
763   inline wuffs_base__range_ii_u64__struct unite(
764       wuffs_base__range_ii_u64__struct s) const;
765   inline bool contains(uint64_t x) const;
766   inline bool contains_range(wuffs_base__range_ii_u64__struct s) const;
767 #endif  // __cplusplus
768 
769 } wuffs_base__range_ii_u64;
770 
771 static inline wuffs_base__range_ii_u64  //
wuffs_base__make_range_ii_u64(uint64_t min_incl,uint64_t max_incl)772 wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) {
773   wuffs_base__range_ii_u64 ret;
774   ret.min_incl = min_incl;
775   ret.max_incl = max_incl;
776   return ret;
777 }
778 
779 static inline bool  //
wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64 * r)780 wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) {
781   return r->min_incl > r->max_incl;
782 }
783 
784 static inline bool  //
wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)785 wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r,
786                                  wuffs_base__range_ii_u64 s) {
787   return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
788          (wuffs_base__range_ii_u64__is_empty(r) &&
789           wuffs_base__range_ii_u64__is_empty(&s));
790 }
791 
792 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)793 wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r,
794                                     wuffs_base__range_ii_u64 s) {
795   wuffs_base__range_ii_u64 t;
796   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
797   t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl);
798   return t;
799 }
800 
801 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)802 wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r,
803                                 wuffs_base__range_ii_u64 s) {
804   if (wuffs_base__range_ii_u64__is_empty(r)) {
805     return s;
806   }
807   if (wuffs_base__range_ii_u64__is_empty(&s)) {
808     return *r;
809   }
810   wuffs_base__range_ii_u64 t;
811   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
812   t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl);
813   return t;
814 }
815 
816 static inline bool  //
wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64 * r,uint64_t x)817 wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r,
818                                    uint64_t x) {
819   return (r->min_incl <= x) && (x <= r->max_incl);
820 }
821 
822 static inline bool  //
wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)823 wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r,
824                                          wuffs_base__range_ii_u64 s) {
825   return wuffs_base__range_ii_u64__equals(
826       &s, wuffs_base__range_ii_u64__intersect(r, s));
827 }
828 
829 #ifdef __cplusplus
830 
831 inline bool  //
is_empty()832 wuffs_base__range_ii_u64::is_empty() const {
833   return wuffs_base__range_ii_u64__is_empty(this);
834 }
835 
836 inline bool  //
equals(wuffs_base__range_ii_u64 s)837 wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const {
838   return wuffs_base__range_ii_u64__equals(this, s);
839 }
840 
841 inline wuffs_base__range_ii_u64  //
intersect(wuffs_base__range_ii_u64 s)842 wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const {
843   return wuffs_base__range_ii_u64__intersect(this, s);
844 }
845 
846 inline wuffs_base__range_ii_u64  //
unite(wuffs_base__range_ii_u64 s)847 wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const {
848   return wuffs_base__range_ii_u64__unite(this, s);
849 }
850 
851 inline bool  //
contains(uint64_t x)852 wuffs_base__range_ii_u64::contains(uint64_t x) const {
853   return wuffs_base__range_ii_u64__contains(this, x);
854 }
855 
856 inline bool  //
contains_range(wuffs_base__range_ii_u64 s)857 wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const {
858   return wuffs_base__range_ii_u64__contains_range(this, s);
859 }
860 
861 #endif  // __cplusplus
862 
863 // --------
864 
865 typedef struct wuffs_base__range_ie_u64__struct {
866   uint64_t min_incl;
867   uint64_t max_excl;
868 
869 #ifdef __cplusplus
870   inline bool is_empty() const;
871   inline bool equals(wuffs_base__range_ie_u64__struct s) const;
872   inline wuffs_base__range_ie_u64__struct intersect(
873       wuffs_base__range_ie_u64__struct s) const;
874   inline wuffs_base__range_ie_u64__struct unite(
875       wuffs_base__range_ie_u64__struct s) const;
876   inline bool contains(uint64_t x) const;
877   inline bool contains_range(wuffs_base__range_ie_u64__struct s) const;
878   inline uint64_t length() const;
879 #endif  // __cplusplus
880 
881 } wuffs_base__range_ie_u64;
882 
883 static inline wuffs_base__range_ie_u64  //
wuffs_base__make_range_ie_u64(uint64_t min_incl,uint64_t max_excl)884 wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) {
885   wuffs_base__range_ie_u64 ret;
886   ret.min_incl = min_incl;
887   ret.max_excl = max_excl;
888   return ret;
889 }
890 
891 static inline bool  //
wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64 * r)892 wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) {
893   return r->min_incl >= r->max_excl;
894 }
895 
896 static inline bool  //
wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)897 wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r,
898                                  wuffs_base__range_ie_u64 s) {
899   return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
900          (wuffs_base__range_ie_u64__is_empty(r) &&
901           wuffs_base__range_ie_u64__is_empty(&s));
902 }
903 
904 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)905 wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r,
906                                     wuffs_base__range_ie_u64 s) {
907   wuffs_base__range_ie_u64 t;
908   t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
909   t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl);
910   return t;
911 }
912 
913 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)914 wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r,
915                                 wuffs_base__range_ie_u64 s) {
916   if (wuffs_base__range_ie_u64__is_empty(r)) {
917     return s;
918   }
919   if (wuffs_base__range_ie_u64__is_empty(&s)) {
920     return *r;
921   }
922   wuffs_base__range_ie_u64 t;
923   t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
924   t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl);
925   return t;
926 }
927 
928 static inline bool  //
wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64 * r,uint64_t x)929 wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r,
930                                    uint64_t x) {
931   return (r->min_incl <= x) && (x < r->max_excl);
932 }
933 
934 static inline bool  //
wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)935 wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r,
936                                          wuffs_base__range_ie_u64 s) {
937   return wuffs_base__range_ie_u64__equals(
938       &s, wuffs_base__range_ie_u64__intersect(r, s));
939 }
940 
941 static inline uint64_t  //
wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64 * r)942 wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) {
943   return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl);
944 }
945 
946 #ifdef __cplusplus
947 
948 inline bool  //
is_empty()949 wuffs_base__range_ie_u64::is_empty() const {
950   return wuffs_base__range_ie_u64__is_empty(this);
951 }
952 
953 inline bool  //
equals(wuffs_base__range_ie_u64 s)954 wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const {
955   return wuffs_base__range_ie_u64__equals(this, s);
956 }
957 
958 inline wuffs_base__range_ie_u64  //
intersect(wuffs_base__range_ie_u64 s)959 wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const {
960   return wuffs_base__range_ie_u64__intersect(this, s);
961 }
962 
963 inline wuffs_base__range_ie_u64  //
unite(wuffs_base__range_ie_u64 s)964 wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const {
965   return wuffs_base__range_ie_u64__unite(this, s);
966 }
967 
968 inline bool  //
contains(uint64_t x)969 wuffs_base__range_ie_u64::contains(uint64_t x) const {
970   return wuffs_base__range_ie_u64__contains(this, x);
971 }
972 
973 inline bool  //
contains_range(wuffs_base__range_ie_u64 s)974 wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const {
975   return wuffs_base__range_ie_u64__contains_range(this, s);
976 }
977 
978 inline uint64_t  //
length()979 wuffs_base__range_ie_u64::length() const {
980   return wuffs_base__range_ie_u64__length(this);
981 }
982 
983 #endif  // __cplusplus
984 
985 // --------
986 
987 // wuffs_base__rect_ii_u32 is a rectangle (a 2-dimensional range) on the
988 // integer grid. The "ii" means that the bounds are inclusive on the low end
989 // and inclusive on the high end. It contains all points (x, y) such that
990 // ((min_incl_x <= x) && (x <= max_incl_x)) and likewise for y.
991 //
992 // It is valid for min > max, in which case the rectangle is empty. There are
993 // multiple representations of an empty rectangle.
994 //
995 // The X and Y axes increase right and down.
996 typedef struct wuffs_base__rect_ii_u32__struct {
997   uint32_t min_incl_x;
998   uint32_t min_incl_y;
999   uint32_t max_incl_x;
1000   uint32_t max_incl_y;
1001 
1002 #ifdef __cplusplus
1003   inline bool is_empty() const;
1004   inline bool equals(wuffs_base__rect_ii_u32__struct s) const;
1005   inline wuffs_base__rect_ii_u32__struct intersect(
1006       wuffs_base__rect_ii_u32__struct s) const;
1007   inline wuffs_base__rect_ii_u32__struct unite(
1008       wuffs_base__rect_ii_u32__struct s) const;
1009   inline bool contains(uint32_t x, uint32_t y) const;
1010   inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const;
1011 #endif  // __cplusplus
1012 
1013 } wuffs_base__rect_ii_u32;
1014 
1015 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)1016 wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,
1017                              uint32_t min_incl_y,
1018                              uint32_t max_incl_x,
1019                              uint32_t max_incl_y) {
1020   wuffs_base__rect_ii_u32 ret;
1021   ret.min_incl_x = min_incl_x;
1022   ret.min_incl_y = min_incl_y;
1023   ret.max_incl_x = max_incl_x;
1024   ret.max_incl_y = max_incl_y;
1025   return ret;
1026 }
1027 
1028 static inline bool  //
wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32 * r)1029 wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) {
1030   return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y);
1031 }
1032 
1033 static inline bool  //
wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)1034 wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r,
1035                                 wuffs_base__rect_ii_u32 s) {
1036   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
1037           r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) ||
1038          (wuffs_base__rect_ii_u32__is_empty(r) &&
1039           wuffs_base__rect_ii_u32__is_empty(&s));
1040 }
1041 
1042 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)1043 wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r,
1044                                    wuffs_base__rect_ii_u32 s) {
1045   wuffs_base__rect_ii_u32 t;
1046   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
1047   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
1048   t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x);
1049   t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y);
1050   return t;
1051 }
1052 
1053 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)1054 wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r,
1055                                wuffs_base__rect_ii_u32 s) {
1056   if (wuffs_base__rect_ii_u32__is_empty(r)) {
1057     return s;
1058   }
1059   if (wuffs_base__rect_ii_u32__is_empty(&s)) {
1060     return *r;
1061   }
1062   wuffs_base__rect_ii_u32 t;
1063   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
1064   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
1065   t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x);
1066   t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y);
1067   return t;
1068 }
1069 
1070 static inline bool  //
wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32 * r,uint32_t x,uint32_t y)1071 wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r,
1072                                   uint32_t x,
1073                                   uint32_t y) {
1074   return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) &&
1075          (y <= r->max_incl_y);
1076 }
1077 
1078 static inline bool  //
wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)1079 wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r,
1080                                        wuffs_base__rect_ii_u32 s) {
1081   return wuffs_base__rect_ii_u32__equals(
1082       &s, wuffs_base__rect_ii_u32__intersect(r, s));
1083 }
1084 
1085 #ifdef __cplusplus
1086 
1087 inline bool  //
is_empty()1088 wuffs_base__rect_ii_u32::is_empty() const {
1089   return wuffs_base__rect_ii_u32__is_empty(this);
1090 }
1091 
1092 inline bool  //
equals(wuffs_base__rect_ii_u32 s)1093 wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const {
1094   return wuffs_base__rect_ii_u32__equals(this, s);
1095 }
1096 
1097 inline wuffs_base__rect_ii_u32  //
intersect(wuffs_base__rect_ii_u32 s)1098 wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const {
1099   return wuffs_base__rect_ii_u32__intersect(this, s);
1100 }
1101 
1102 inline wuffs_base__rect_ii_u32  //
unite(wuffs_base__rect_ii_u32 s)1103 wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const {
1104   return wuffs_base__rect_ii_u32__unite(this, s);
1105 }
1106 
1107 inline bool  //
contains(uint32_t x,uint32_t y)1108 wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const {
1109   return wuffs_base__rect_ii_u32__contains(this, x, y);
1110 }
1111 
1112 inline bool  //
contains_rect(wuffs_base__rect_ii_u32 s)1113 wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const {
1114   return wuffs_base__rect_ii_u32__contains_rect(this, s);
1115 }
1116 
1117 #endif  // __cplusplus
1118 
1119 // --------
1120 
1121 // wuffs_base__rect_ie_u32 is a rectangle (a 2-dimensional range) on the
1122 // integer grid. The "ie" means that the bounds are inclusive on the low end
1123 // and exclusive on the high end. It contains all points (x, y) such that
1124 // ((min_incl_x <= x) && (x < max_excl_x)) and likewise for y.
1125 //
1126 // It is valid for min >= max, in which case the rectangle is empty. There are
1127 // multiple representations of an empty rectangle, including a value with all
1128 // fields zero.
1129 //
1130 // The X and Y axes increase right and down.
1131 typedef struct wuffs_base__rect_ie_u32__struct {
1132   uint32_t min_incl_x;
1133   uint32_t min_incl_y;
1134   uint32_t max_excl_x;
1135   uint32_t max_excl_y;
1136 
1137 #ifdef __cplusplus
1138   inline bool is_empty() const;
1139   inline bool equals(wuffs_base__rect_ie_u32__struct s) const;
1140   inline wuffs_base__rect_ie_u32__struct intersect(
1141       wuffs_base__rect_ie_u32__struct s) const;
1142   inline wuffs_base__rect_ie_u32__struct unite(
1143       wuffs_base__rect_ie_u32__struct s) const;
1144   inline bool contains(uint32_t x, uint32_t y) const;
1145   inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const;
1146   inline uint32_t width() const;
1147   inline uint32_t height() const;
1148 #endif  // __cplusplus
1149 
1150 } wuffs_base__rect_ie_u32;
1151 
1152 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)1153 wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,
1154                              uint32_t min_incl_y,
1155                              uint32_t max_excl_x,
1156                              uint32_t max_excl_y) {
1157   wuffs_base__rect_ie_u32 ret;
1158   ret.min_incl_x = min_incl_x;
1159   ret.min_incl_y = min_incl_y;
1160   ret.max_excl_x = max_excl_x;
1161   ret.max_excl_y = max_excl_y;
1162   return ret;
1163 }
1164 
1165 static inline bool  //
wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32 * r)1166 wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) {
1167   return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y);
1168 }
1169 
1170 static inline bool  //
wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)1171 wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r,
1172                                 wuffs_base__rect_ie_u32 s) {
1173   return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
1174           r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) ||
1175          (wuffs_base__rect_ie_u32__is_empty(r) &&
1176           wuffs_base__rect_ie_u32__is_empty(&s));
1177 }
1178 
1179 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)1180 wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r,
1181                                    wuffs_base__rect_ie_u32 s) {
1182   wuffs_base__rect_ie_u32 t;
1183   t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
1184   t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
1185   t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x);
1186   t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y);
1187   return t;
1188 }
1189 
1190 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)1191 wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r,
1192                                wuffs_base__rect_ie_u32 s) {
1193   if (wuffs_base__rect_ie_u32__is_empty(r)) {
1194     return s;
1195   }
1196   if (wuffs_base__rect_ie_u32__is_empty(&s)) {
1197     return *r;
1198   }
1199   wuffs_base__rect_ie_u32 t;
1200   t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
1201   t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
1202   t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x);
1203   t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y);
1204   return t;
1205 }
1206 
1207 static inline bool  //
wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32 * r,uint32_t x,uint32_t y)1208 wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r,
1209                                   uint32_t x,
1210                                   uint32_t y) {
1211   return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) &&
1212          (y < r->max_excl_y);
1213 }
1214 
1215 static inline bool  //
wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)1216 wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r,
1217                                        wuffs_base__rect_ie_u32 s) {
1218   return wuffs_base__rect_ie_u32__equals(
1219       &s, wuffs_base__rect_ie_u32__intersect(r, s));
1220 }
1221 
1222 static inline uint32_t  //
wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32 * r)1223 wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) {
1224   return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x);
1225 }
1226 
1227 static inline uint32_t  //
wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32 * r)1228 wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) {
1229   return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y);
1230 }
1231 
1232 #ifdef __cplusplus
1233 
1234 inline bool  //
is_empty()1235 wuffs_base__rect_ie_u32::is_empty() const {
1236   return wuffs_base__rect_ie_u32__is_empty(this);
1237 }
1238 
1239 inline bool  //
equals(wuffs_base__rect_ie_u32 s)1240 wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const {
1241   return wuffs_base__rect_ie_u32__equals(this, s);
1242 }
1243 
1244 inline wuffs_base__rect_ie_u32  //
intersect(wuffs_base__rect_ie_u32 s)1245 wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const {
1246   return wuffs_base__rect_ie_u32__intersect(this, s);
1247 }
1248 
1249 inline wuffs_base__rect_ie_u32  //
unite(wuffs_base__rect_ie_u32 s)1250 wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const {
1251   return wuffs_base__rect_ie_u32__unite(this, s);
1252 }
1253 
1254 inline bool  //
contains(uint32_t x,uint32_t y)1255 wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const {
1256   return wuffs_base__rect_ie_u32__contains(this, x, y);
1257 }
1258 
1259 inline bool  //
contains_rect(wuffs_base__rect_ie_u32 s)1260 wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const {
1261   return wuffs_base__rect_ie_u32__contains_rect(this, s);
1262 }
1263 
1264 inline uint32_t  //
width()1265 wuffs_base__rect_ie_u32::width() const {
1266   return wuffs_base__rect_ie_u32__width(this);
1267 }
1268 
1269 inline uint32_t  //
height()1270 wuffs_base__rect_ie_u32::height() const {
1271   return wuffs_base__rect_ie_u32__height(this);
1272 }
1273 
1274 #endif  // __cplusplus
1275 
1276 // ---------------- I/O
1277 //
1278 // See (/doc/note/io-input-output.md).
1279 
1280 // wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's
1281 // data.
1282 typedef struct {
1283   size_t wi;     // Write index. Invariant: wi <= len.
1284   size_t ri;     // Read  index. Invariant: ri <= wi.
1285   uint64_t pos;  // Position of the buffer start relative to the stream start.
1286   bool closed;   // No further writes are expected.
1287 } wuffs_base__io_buffer_meta;
1288 
1289 // wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus
1290 // additional metadata.
1291 //
1292 // A value with all fields zero is a valid, empty buffer.
1293 typedef struct wuffs_base__io_buffer__struct {
1294   wuffs_base__slice_u8 data;
1295   wuffs_base__io_buffer_meta meta;
1296 
1297 #ifdef __cplusplus
1298   inline void compact();
1299   inline wuffs_base__io_buffer__struct* reader();  // Deprecated.
1300   inline wuffs_base__io_buffer__struct* writer();  // Deprecated.
1301   inline uint64_t reader_available() const;
1302   inline uint64_t reader_io_position() const;
1303   inline uint64_t writer_available() const;
1304   inline uint64_t writer_io_position() const;
1305 #endif  // __cplusplus
1306 
1307 } wuffs_base__io_buffer;
1308 
1309 static inline wuffs_base__io_buffer  //
wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,wuffs_base__io_buffer_meta meta)1310 wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,
1311                            wuffs_base__io_buffer_meta meta) {
1312   wuffs_base__io_buffer ret;
1313   ret.data = data;
1314   ret.meta = meta;
1315   return ret;
1316 }
1317 
1318 static inline wuffs_base__io_buffer_meta  //
wuffs_base__make_io_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)1319 wuffs_base__make_io_buffer_meta(size_t wi,
1320                                 size_t ri,
1321                                 uint64_t pos,
1322                                 bool closed) {
1323   wuffs_base__io_buffer_meta ret;
1324   ret.wi = wi;
1325   ret.ri = ri;
1326   ret.pos = pos;
1327   ret.closed = closed;
1328   return ret;
1329 }
1330 
1331 static inline wuffs_base__io_buffer  //
wuffs_base__null_io_buffer()1332 wuffs_base__null_io_buffer() {
1333   wuffs_base__io_buffer ret;
1334   ret.data.ptr = NULL;
1335   ret.data.len = 0;
1336   ret.meta.wi = 0;
1337   ret.meta.ri = 0;
1338   ret.meta.pos = 0;
1339   ret.meta.closed = false;
1340   return ret;
1341 }
1342 
1343 static inline wuffs_base__io_buffer_meta  //
wuffs_base__null_io_buffer_meta()1344 wuffs_base__null_io_buffer_meta() {
1345   wuffs_base__io_buffer_meta ret;
1346   ret.wi = 0;
1347   ret.ri = 0;
1348   ret.pos = 0;
1349   ret.closed = false;
1350   return ret;
1351 }
1352 
1353 // wuffs_base__io_buffer__compact moves any written but unread bytes to the
1354 // start of the buffer.
1355 static inline void  //
wuffs_base__io_buffer__compact(wuffs_base__io_buffer * buf)1356 wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) {
1357   if (!buf || (buf->meta.ri == 0)) {
1358     return;
1359   }
1360   buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
1361   size_t n = buf->meta.wi - buf->meta.ri;
1362   if (n != 0) {
1363     memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, n);
1364   }
1365   buf->meta.wi = n;
1366   buf->meta.ri = 0;
1367 }
1368 
1369 static inline uint64_t  //
wuffs_base__io_buffer__reader_available(const wuffs_base__io_buffer * buf)1370 wuffs_base__io_buffer__reader_available(const wuffs_base__io_buffer* buf) {
1371   return buf ? buf->meta.wi - buf->meta.ri : 0;
1372 }
1373 
1374 static inline uint64_t  //
wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer * buf)1375 wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer* buf) {
1376   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
1377 }
1378 
1379 static inline uint64_t  //
wuffs_base__io_buffer__writer_available(const wuffs_base__io_buffer * buf)1380 wuffs_base__io_buffer__writer_available(const wuffs_base__io_buffer* buf) {
1381   return buf ? buf->data.len - buf->meta.wi : 0;
1382 }
1383 
1384 static inline uint64_t  //
wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer * buf)1385 wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer* buf) {
1386   return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
1387 }
1388 
1389 #ifdef __cplusplus
1390 
1391 inline void  //
compact()1392 wuffs_base__io_buffer__struct::compact() {
1393   wuffs_base__io_buffer__compact(this);
1394 }
1395 
1396 inline wuffs_base__io_buffer*  //
reader()1397 wuffs_base__io_buffer__struct::reader() {
1398   return this;
1399 }
1400 
1401 inline wuffs_base__io_buffer*  //
writer()1402 wuffs_base__io_buffer__struct::writer() {
1403   return this;
1404 }
1405 
1406 inline uint64_t  //
reader_available()1407 wuffs_base__io_buffer__struct::reader_available() const {
1408   return wuffs_base__io_buffer__reader_available(this);
1409 }
1410 
1411 inline uint64_t  //
reader_io_position()1412 wuffs_base__io_buffer__struct::reader_io_position() const {
1413   return wuffs_base__io_buffer__reader_io_position(this);
1414 }
1415 
1416 inline uint64_t  //
writer_available()1417 wuffs_base__io_buffer__struct::writer_available() const {
1418   return wuffs_base__io_buffer__writer_available(this);
1419 }
1420 
1421 inline uint64_t  //
writer_io_position()1422 wuffs_base__io_buffer__struct::writer_io_position() const {
1423   return wuffs_base__io_buffer__writer_io_position(this);
1424 }
1425 
1426 #endif  // __cplusplus
1427 
1428 // ---------------- Memory Allocation
1429 
1430 // The memory allocation related functions in this section aren't used by Wuffs
1431 // per se, but they may be helpful to the code that uses Wuffs.
1432 
1433 // wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except
1434 // that it takes a uint64_t number of elements instead of a size_t size in
1435 // bytes, and it returns a slice (a pointer and a length) instead of just a
1436 // pointer.
1437 //
1438 // You can pass the C stdlib's malloc as the malloc_func.
1439 //
1440 // It returns an empty slice (containing a NULL ptr field) if (num_uxx *
1441 // sizeof(uintxx_t)) would overflow SIZE_MAX.
1442 
1443 static inline wuffs_base__slice_u8  //
wuffs_base__malloc_slice_u8(void * (* malloc_func)(size_t),uint64_t num_u8)1444 wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) {
1445   if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) {
1446     void* p = (*malloc_func)(num_u8 * sizeof(uint8_t));
1447     if (p) {
1448       return wuffs_base__make_slice_u8((uint8_t*)(p), num_u8);
1449     }
1450   }
1451   return wuffs_base__make_slice_u8(NULL, 0);
1452 }
1453 
1454 static inline wuffs_base__slice_u16  //
wuffs_base__malloc_slice_u16(void * (* malloc_func)(size_t),uint64_t num_u16)1455 wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) {
1456   if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) {
1457     void* p = (*malloc_func)(num_u16 * sizeof(uint16_t));
1458     if (p) {
1459       return wuffs_base__make_slice_u16((uint16_t*)(p), num_u16);
1460     }
1461   }
1462   return wuffs_base__make_slice_u16(NULL, 0);
1463 }
1464 
1465 static inline wuffs_base__slice_u32  //
wuffs_base__malloc_slice_u32(void * (* malloc_func)(size_t),uint64_t num_u32)1466 wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) {
1467   if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) {
1468     void* p = (*malloc_func)(num_u32 * sizeof(uint32_t));
1469     if (p) {
1470       return wuffs_base__make_slice_u32((uint32_t*)(p), num_u32);
1471     }
1472   }
1473   return wuffs_base__make_slice_u32(NULL, 0);
1474 }
1475 
1476 static inline wuffs_base__slice_u64  //
wuffs_base__malloc_slice_u64(void * (* malloc_func)(size_t),uint64_t num_u64)1477 wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) {
1478   if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) {
1479     void* p = (*malloc_func)(num_u64 * sizeof(uint64_t));
1480     if (p) {
1481       return wuffs_base__make_slice_u64((uint64_t*)(p), num_u64);
1482     }
1483   }
1484   return wuffs_base__make_slice_u64(NULL, 0);
1485 }
1486 
1487 // ---------------- Images
1488 
1489 // wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
1490 // Alpha, Red, Green, Blue color, as a uint32_t value. It is in word order, not
1491 // byte order: its value is always 0xAARRGGBB, regardless of endianness.
1492 typedef uint32_t wuffs_base__color_u32_argb_premul;
1493 
1494 // --------
1495 
1496 // wuffs_base__pixel_format encodes the format of the bytes that constitute an
1497 // image frame's pixel data. Its bits:
1498 //  - bit        31  is reserved.
1499 //  - bits 30 .. 28 encodes color (and channel order, in terms of memory).
1500 //  - bit        27  is reserved.
1501 //  - bits 26 .. 24 encodes transparency.
1502 //  - bits 23 .. 21 are reserved.
1503 //  - bit        20 indicates big-endian/MSB-first (as opposed to little/LSB).
1504 //  - bit        19 indicates floating point (as opposed to integer).
1505 //  - bit        18 indicates palette-indexed. The number-of-planes (the next
1506 //                  field) will be 0, as the format is considered interleaved,
1507 //                  but the 8-bit N-BGRA color data is stored in plane 3.
1508 //  - bits 17 .. 16 are the number of planes, minus 1. Zero means interleaved.
1509 //  - bits 15 .. 12 encodes the number of bits (depth) in the 3rd channel.
1510 //  - bits 11 ..  8 encodes the number of bits (depth) in the 2nd channel.
1511 //  - bits  7 ..  4 encodes the number of bits (depth) in the 1st channel.
1512 //  - bits  3 ..  0 encodes the number of bits (depth) in the 0th channel.
1513 //
1514 // The bit fields of a wuffs_base__pixel_format are not independent. For
1515 // example, the number of planes should not be greater than the number of
1516 // channels. Similarly, bits 15..4 are unused (and should be zero) if bits
1517 // 31..24 (color and transparency) together imply only 1 channel (gray, no
1518 // alpha) and floating point samples should mean a bit depth of 16, 32 or 64.
1519 //
1520 // Formats hold between 1 and 4 channels. For example: Y (1 channel: gray), YA
1521 // (2 channels: gray and alpha), BGR (3 channels: blue, green, red) or CMYK (4
1522 // channels: cyan, magenta, yellow, black).
1523 //
1524 // For direct formats with N > 1 channels, those channels can be laid out in
1525 // either 1 (interleaved) or N (planar) planes. For example, RGBA data is
1526 // usually interleaved, but YCbCr data is usually planar, due to chroma
1527 // subsampling (for details, see the wuffs_base__pixel_subsampling type).
1528 //
1529 // For indexed formats, the palette (always 256 × 4 bytes) holds 8 bits per
1530 // channel non-alpha-premultiplied BGRA color data. There is only 1 plane (for
1531 // the index), as the format is considered interleaved. Plane 0 holds the
1532 // per-pixel indices. Plane 3 is re-purposed to hold the per-index colors.
1533 //
1534 // The color field is encoded in 3 bits:
1535 //  - 0 means                   A (Alpha).
1536 //  - 1 means Y         or     YA (Gray, Alpha).
1537 //  - 2 means YCbCr     or YCbCrA (Luma, Chroma-blue, Chroma-red, Alpha).
1538 //  - 3 means YCoCg     or YCoCgA (Luma, Chroma-orange, Chroma-green, Alpha).
1539 //  - 4 means BGR, BGRX or   BGRA (Blue, Green, Red, X-padding or Alpha).
1540 //  - 5 means RGB, RGBX or   RGBA (Red, Green, Blue, X-padding or Alpha).
1541 //  - 6 means CMY       or   CMYK (Cyan, Magenta, Yellow, Black).
1542 //  - all other values are reserved.
1543 //
1544 // In Wuffs, channels are given in memory order (also known as byte order),
1545 // regardless of endianness, since the C type for the pixel data is an array of
1546 // bytes, not an array of uint32_t. For example, interleaved BGRA with 8 bits
1547 // per channel means that the bytes in memory are always Blue, Green, Red then
1548 // Alpha. On big-endian systems, that is the uint32_t 0xBBGGRRAA. On
1549 // little-endian, 0xAARRGGBB.
1550 //
1551 // When the color field (3 bits) encodes multiple options, the transparency
1552 // field (3 bits) distinguishes them:
1553 //  - 0 means fully opaque, no extra channels
1554 //  - 1 means fully opaque, one extra channel (X or K, padding or black).
1555 //  - 5 means one extra alpha channel, other channels are non-premultiplied.
1556 //  - 6 means one extra alpha channel, other channels are     premultiplied.
1557 //  - 7 means one extra alpha channel, binary alpha.
1558 //  - all other values are reserved.
1559 //
1560 // Binary alpha means that if a color is not completely opaque, it is
1561 // completely transparent black. As a source pixel format, it can therefore be
1562 // treated as either non-premultiplied or premultiplied.
1563 //
1564 // The zero wuffs_base__pixel_format value is an invalid pixel format, as it is
1565 // invalid to combine the zero color (alpha only) with the zero transparency.
1566 //
1567 // Bit depth is encoded in 4 bits:
1568 //  -  0 means the channel or index is unused.
1569 //  -  x means a bit depth of  x, for x in the range 1..8.
1570 //  -  9 means a bit depth of 10.
1571 //  - 10 means a bit depth of 12.
1572 //  - 11 means a bit depth of 16.
1573 //  - 12 means a bit depth of 24.
1574 //  - 13 means a bit depth of 32.
1575 //  - 14 means a bit depth of 48.
1576 //  - 15 means a bit depth of 64.
1577 //
1578 // For example, wuffs_base__pixel_format 0x5510BBBB is a natural format for
1579 // decoding a PNG image - network byte order (also known as big-endian),
1580 // interleaved, non-premultiplied alpha - that happens to be 16-bit-depth
1581 // truecolor with alpha (RGBA). In memory order:
1582 //
1583 //  ptr+0  ptr+1  ptr+2  ptr+3  ptr+4  ptr+5  ptr+6  ptr+7
1584 //  Rhi    Rlo    Ghi    Glo    Bhi    Blo    Ahi    Alo
1585 //
1586 // For example, the value wuffs_base__pixel_format 0x40000565 means BGR with no
1587 // alpha or padding, 5/6/5 bits for blue/green/red, interleaved 2 bytes per
1588 // pixel, laid out LSB-first in memory order:
1589 //
1590 //  ptr+0...........  ptr+1...........
1591 //  MSB          LSB  MSB          LSB
1592 //  G₂G₁G₀B₄B₃B₂B₁B₀  R₄R₃R₂R₁R₀G₅G₄G₃
1593 //
1594 // On little-endian systems (but not big-endian), this Wuffs pixel format value
1595 // (0x40000565) corresponds to the Cairo library's CAIRO_FORMAT_RGB16_565, the
1596 // SDL2 (Simple DirectMedia Layer 2) library's SDL_PIXELFORMAT_RGB565 and the
1597 // Skia library's kRGB_565_SkColorType. Note BGR in Wuffs versus RGB in the
1598 // other libraries.
1599 //
1600 // Regardless of endianness, this Wuffs pixel format value (0x40000565)
1601 // corresponds to the V4L2 (Video For Linux 2) library's V4L2_PIX_FMT_RGB565
1602 // and the Wayland-DRM library's WL_DRM_FORMAT_RGB565.
1603 //
1604 // Different software libraries name their pixel formats (and especially their
1605 // channel order) either according to memory layout or as bits of a native
1606 // integer type like uint32_t. The two conventions differ because of a system's
1607 // endianness. As mentioned earlier, Wuffs pixel formats are always in memory
1608 // order. More detail of other software libraries' naming conventions is in the
1609 // Pixel Format Guide at https://afrantzis.github.io/pixel-format-guide/
1610 //
1611 // Do not manipulate these bits directly; they are private implementation
1612 // details. Use methods such as wuffs_base__pixel_format__num_planes instead.
1613 typedef uint32_t wuffs_base__pixel_format;
1614 
1615 // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid
1616 // wuffs_base__pixel_format values are present.
1617 
1618 #define WUFFS_BASE__PIXEL_FORMAT__INVALID ((wuffs_base__pixel_format)0x00000000)
1619 
1620 #define WUFFS_BASE__PIXEL_FORMAT__A ((wuffs_base__pixel_format)0x02000008)
1621 
1622 #define WUFFS_BASE__PIXEL_FORMAT__Y ((wuffs_base__pixel_format)0x10000008)
1623 #define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL \
1624   ((wuffs_base__pixel_format)0x15000008)
1625 #define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL \
1626   ((wuffs_base__pixel_format)0x16000008)
1627 
1628 #define WUFFS_BASE__PIXEL_FORMAT__YCBCR ((wuffs_base__pixel_format)0x20020888)
1629 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRK ((wuffs_base__pixel_format)0x21038888)
1630 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL \
1631   ((wuffs_base__pixel_format)0x25038888)
1632 
1633 #define WUFFS_BASE__PIXEL_FORMAT__YCOCG ((wuffs_base__pixel_format)0x30020888)
1634 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGK ((wuffs_base__pixel_format)0x31038888)
1635 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL \
1636   ((wuffs_base__pixel_format)0x35038888)
1637 
1638 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL \
1639   ((wuffs_base__pixel_format)0x45040008)
1640 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL \
1641   ((wuffs_base__pixel_format)0x46040008)
1642 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY \
1643   ((wuffs_base__pixel_format)0x47040008)
1644 
1645 #define WUFFS_BASE__PIXEL_FORMAT__BGR ((wuffs_base__pixel_format)0x40000888)
1646 #define WUFFS_BASE__PIXEL_FORMAT__BGRX ((wuffs_base__pixel_format)0x41008888)
1647 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL \
1648   ((wuffs_base__pixel_format)0x45008888)
1649 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL \
1650   ((wuffs_base__pixel_format)0x46008888)
1651 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY \
1652   ((wuffs_base__pixel_format)0x47008888)
1653 
1654 #define WUFFS_BASE__PIXEL_FORMAT__RGB ((wuffs_base__pixel_format)0x50000888)
1655 #define WUFFS_BASE__PIXEL_FORMAT__RGBX ((wuffs_base__pixel_format)0x51008888)
1656 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL \
1657   ((wuffs_base__pixel_format)0x55008888)
1658 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL \
1659   ((wuffs_base__pixel_format)0x56008888)
1660 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY \
1661   ((wuffs_base__pixel_format)0x57008888)
1662 
1663 #define WUFFS_BASE__PIXEL_FORMAT__CMY ((wuffs_base__pixel_format)0x60020888)
1664 #define WUFFS_BASE__PIXEL_FORMAT__CMYK ((wuffs_base__pixel_format)0x61038888)
1665 
1666 extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];
1667 
1668 static inline bool  //
wuffs_base__pixel_format__is_valid(wuffs_base__pixel_format f)1669 wuffs_base__pixel_format__is_valid(wuffs_base__pixel_format f) {
1670   return f != 0;
1671 }
1672 
1673 // wuffs_base__pixel_format__bits_per_pixel returns the number of bits per
1674 // pixel for interleaved pixel formats, and returns 0 for planar pixel formats.
1675 static inline uint32_t  //
wuffs_base__pixel_format__bits_per_pixel(wuffs_base__pixel_format f)1676 wuffs_base__pixel_format__bits_per_pixel(wuffs_base__pixel_format f) {
1677   if (((f >> 16) & 0x03) != 0) {
1678     return 0;
1679   }
1680   return wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 0)] +
1681          wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 4)] +
1682          wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 8)] +
1683          wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 12)];
1684 }
1685 
1686 static inline bool  //
wuffs_base__pixel_format__is_indexed(wuffs_base__pixel_format f)1687 wuffs_base__pixel_format__is_indexed(wuffs_base__pixel_format f) {
1688   return (f >> 18) & 0x01;
1689 }
1690 
1691 static inline bool  //
wuffs_base__pixel_format__is_interleaved(wuffs_base__pixel_format f)1692 wuffs_base__pixel_format__is_interleaved(wuffs_base__pixel_format f) {
1693   return ((f >> 16) & 0x03) == 0;
1694 }
1695 
1696 static inline bool  //
wuffs_base__pixel_format__is_planar(wuffs_base__pixel_format f)1697 wuffs_base__pixel_format__is_planar(wuffs_base__pixel_format f) {
1698   return ((f >> 16) & 0x03) != 0;
1699 }
1700 
1701 static inline uint32_t  //
wuffs_base__pixel_format__num_planes(wuffs_base__pixel_format f)1702 wuffs_base__pixel_format__num_planes(wuffs_base__pixel_format f) {
1703   return ((f >> 16) & 0x03) + 1;
1704 }
1705 
1706 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
1707 
1708 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
1709 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
1710 
1711 // --------
1712 
1713 // wuffs_base__pixel_subsampling encodes the mapping of pixel space coordinates
1714 // (x, y) to pixel buffer indices (i, j). That mapping can differ for each
1715 // plane p. For a depth of 8 bits (1 byte), the p'th plane's sample starts at
1716 // (planes[p].ptr + (j * planes[p].stride) + i).
1717 //
1718 // For interleaved pixel formats, the mapping is trivial: i = x and j = y. For
1719 // planar pixel formats, the mapping can differ due to chroma subsampling. For
1720 // example, consider a three plane YCbCr pixel format with 4:2:2 subsampling.
1721 // For the luma (Y) channel, there is one sample for every pixel, but for the
1722 // chroma (Cb, Cr) channels, there is one sample for every two pixels: pairs of
1723 // horizontally adjacent pixels form one macropixel, i = x / 2 and j == y. In
1724 // general, for a given p:
1725 //  - i = (x + bias_x) >> shift_x.
1726 //  - j = (y + bias_y) >> shift_y.
1727 // where biases and shifts are in the range 0..3 and 0..2 respectively.
1728 //
1729 // In general, the biases will be zero after decoding an image. However, making
1730 // a sub-image may change the bias, since the (x, y) coordinates are relative
1731 // to the sub-image's top-left origin, but the backing pixel buffers were
1732 // created relative to the original image's origin.
1733 //
1734 // For each plane p, each of those four numbers (biases and shifts) are encoded
1735 // in two bits, which combine to form an 8 bit unsigned integer:
1736 //
1737 //  e_p = (bias_x << 6) | (shift_x << 4) | (bias_y << 2) | (shift_y << 0)
1738 //
1739 // Those e_p values (e_0 for the first plane, e_1 for the second plane, etc)
1740 // combine to form a wuffs_base__pixel_subsampling value:
1741 //
1742 //  pixsub = (e_3 << 24) | (e_2 << 16) | (e_1 << 8) | (e_0 << 0)
1743 //
1744 // Do not manipulate these bits directly; they are private implementation
1745 // details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead.
1746 typedef uint32_t wuffs_base__pixel_subsampling;
1747 
1748 #define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE ((wuffs_base__pixel_subsampling)0)
1749 
1750 #define WUFFS_BASE__PIXEL_SUBSAMPLING__444 \
1751   ((wuffs_base__pixel_subsampling)0x000000)
1752 #define WUFFS_BASE__PIXEL_SUBSAMPLING__440 \
1753   ((wuffs_base__pixel_subsampling)0x010100)
1754 #define WUFFS_BASE__PIXEL_SUBSAMPLING__422 \
1755   ((wuffs_base__pixel_subsampling)0x101000)
1756 #define WUFFS_BASE__PIXEL_SUBSAMPLING__420 \
1757   ((wuffs_base__pixel_subsampling)0x111100)
1758 #define WUFFS_BASE__PIXEL_SUBSAMPLING__411 \
1759   ((wuffs_base__pixel_subsampling)0x202000)
1760 #define WUFFS_BASE__PIXEL_SUBSAMPLING__410 \
1761   ((wuffs_base__pixel_subsampling)0x212100)
1762 
1763 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_x(wuffs_base__pixel_subsampling s,uint32_t plane)1764 wuffs_base__pixel_subsampling__bias_x(wuffs_base__pixel_subsampling s,
1765                                       uint32_t plane) {
1766   uint32_t shift = ((plane & 0x03) * 8) + 6;
1767   return (s >> shift) & 0x03;
1768 }
1769 
1770 static inline uint32_t  //
wuffs_base__pixel_subsampling__shift_x(wuffs_base__pixel_subsampling s,uint32_t plane)1771 wuffs_base__pixel_subsampling__shift_x(wuffs_base__pixel_subsampling s,
1772                                        uint32_t plane) {
1773   uint32_t shift = ((plane & 0x03) * 8) + 4;
1774   return (s >> shift) & 0x03;
1775 }
1776 
1777 static inline uint32_t  //
wuffs_base__pixel_subsampling__bias_y(wuffs_base__pixel_subsampling s,uint32_t plane)1778 wuffs_base__pixel_subsampling__bias_y(wuffs_base__pixel_subsampling s,
1779                                       uint32_t plane) {
1780   uint32_t shift = ((plane & 0x03) * 8) + 2;
1781   return (s >> shift) & 0x03;
1782 }
1783 
1784 static inline uint32_t  //
wuffs_base__pixel_subsampling__shift_y(wuffs_base__pixel_subsampling s,uint32_t plane)1785 wuffs_base__pixel_subsampling__shift_y(wuffs_base__pixel_subsampling s,
1786                                        uint32_t plane) {
1787   uint32_t shift = ((plane & 0x03) * 8) + 0;
1788   return (s >> shift) & 0x03;
1789 }
1790 
1791 // --------
1792 
1793 typedef struct {
1794   // Do not access the private_impl's fields directly. There is no API/ABI
1795   // compatibility or safety guarantee if you do so.
1796   struct {
1797     wuffs_base__pixel_format pixfmt;
1798     wuffs_base__pixel_subsampling pixsub;
1799     uint32_t width;
1800     uint32_t height;
1801   } private_impl;
1802 
1803 #ifdef __cplusplus
1804   inline void set(wuffs_base__pixel_format pixfmt,
1805                   wuffs_base__pixel_subsampling pixsub,
1806                   uint32_t width,
1807                   uint32_t height);
1808   inline void invalidate();
1809   inline bool is_valid() const;
1810   inline wuffs_base__pixel_format pixel_format() const;
1811   inline wuffs_base__pixel_subsampling pixel_subsampling() const;
1812   inline wuffs_base__rect_ie_u32 bounds() const;
1813   inline uint32_t width() const;
1814   inline uint32_t height() const;
1815   inline uint64_t pixbuf_len() const;
1816 #endif  // __cplusplus
1817 
1818 } wuffs_base__pixel_config;
1819 
1820 static inline wuffs_base__pixel_config  //
wuffs_base__null_pixel_config()1821 wuffs_base__null_pixel_config() {
1822   wuffs_base__pixel_config ret;
1823   ret.private_impl.pixfmt = 0;
1824   ret.private_impl.pixsub = 0;
1825   ret.private_impl.width = 0;
1826   ret.private_impl.height = 0;
1827   return ret;
1828 }
1829 
1830 // TODO: Should this function return bool? An error type?
1831 static inline void  //
wuffs_base__pixel_config__set(wuffs_base__pixel_config * c,wuffs_base__pixel_format pixfmt,wuffs_base__pixel_subsampling pixsub,uint32_t width,uint32_t height)1832 wuffs_base__pixel_config__set(wuffs_base__pixel_config* c,
1833                               wuffs_base__pixel_format pixfmt,
1834                               wuffs_base__pixel_subsampling pixsub,
1835                               uint32_t width,
1836                               uint32_t height) {
1837   if (!c) {
1838     return;
1839   }
1840   if (pixfmt) {
1841     uint64_t wh = ((uint64_t)width) * ((uint64_t)height);
1842     // TODO: handle things other than 1 byte per pixel.
1843     if (wh <= ((uint64_t)SIZE_MAX)) {
1844       c->private_impl.pixfmt = pixfmt;
1845       c->private_impl.pixsub = pixsub;
1846       c->private_impl.width = width;
1847       c->private_impl.height = height;
1848       return;
1849     }
1850   }
1851 
1852   c->private_impl.pixfmt = 0;
1853   c->private_impl.pixsub = 0;
1854   c->private_impl.width = 0;
1855   c->private_impl.height = 0;
1856 }
1857 
1858 static inline void  //
wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config * c)1859 wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) {
1860   if (c) {
1861     c->private_impl.pixfmt = 0;
1862     c->private_impl.pixsub = 0;
1863     c->private_impl.width = 0;
1864     c->private_impl.height = 0;
1865   }
1866 }
1867 
1868 static inline bool  //
wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config * c)1869 wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) {
1870   return c && c->private_impl.pixfmt;
1871 }
1872 
1873 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config * c)1874 wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
1875   return c ? c->private_impl.pixfmt : 0;
1876 }
1877 
1878 static inline wuffs_base__pixel_subsampling  //
wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config * c)1879 wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) {
1880   return c ? c->private_impl.pixsub : 0;
1881 }
1882 
1883 static inline wuffs_base__rect_ie_u32  //
wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config * c)1884 wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) {
1885   if (c) {
1886     wuffs_base__rect_ie_u32 ret;
1887     ret.min_incl_x = 0;
1888     ret.min_incl_y = 0;
1889     ret.max_excl_x = c->private_impl.width;
1890     ret.max_excl_y = c->private_impl.height;
1891     return ret;
1892   }
1893 
1894   wuffs_base__rect_ie_u32 ret;
1895   ret.min_incl_x = 0;
1896   ret.min_incl_y = 0;
1897   ret.max_excl_x = 0;
1898   ret.max_excl_y = 0;
1899   return ret;
1900 }
1901 
1902 static inline uint32_t  //
wuffs_base__pixel_config__width(const wuffs_base__pixel_config * c)1903 wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) {
1904   return c ? c->private_impl.width : 0;
1905 }
1906 
1907 static inline uint32_t  //
wuffs_base__pixel_config__height(const wuffs_base__pixel_config * c)1908 wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) {
1909   return c ? c->private_impl.height : 0;
1910 }
1911 
1912 // TODO: this is the right API for planar (not interleaved) pixbufs? Should it
1913 // allow decoding into a color model different from the format's intrinsic one?
1914 // For example, decoding a JPEG image straight to RGBA instead of to YCbCr?
1915 static inline uint64_t  //
wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config * c)1916 wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) {
1917   if (!c) {
1918     return 0;
1919   }
1920   if (wuffs_base__pixel_format__is_planar(c->private_impl.pixfmt)) {
1921     // TODO: support planar pixel formats, concious of pixel subsampling.
1922     return 0;
1923   }
1924   uint32_t bits_per_pixel =
1925       wuffs_base__pixel_format__bits_per_pixel(c->private_impl.pixfmt);
1926   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
1927     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
1928     return 0;
1929   }
1930   uint64_t bytes_per_pixel = bits_per_pixel / 8;
1931 
1932   uint64_t n =
1933       ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height);
1934   if (n > (UINT64_MAX / bytes_per_pixel)) {
1935     return 0;
1936   }
1937   n *= bytes_per_pixel;
1938 
1939   if (wuffs_base__pixel_format__is_indexed(c->private_impl.pixfmt)) {
1940     if (n > (UINT64_MAX - 1024)) {
1941       return 0;
1942     }
1943     n += 1024;
1944   }
1945 
1946   return n;
1947 }
1948 
1949 #ifdef __cplusplus
1950 
1951 inline void  //
set(wuffs_base__pixel_format pixfmt,wuffs_base__pixel_subsampling pixsub,uint32_t width,uint32_t height)1952 wuffs_base__pixel_config::set(wuffs_base__pixel_format pixfmt,
1953                               wuffs_base__pixel_subsampling pixsub,
1954                               uint32_t width,
1955                               uint32_t height) {
1956   wuffs_base__pixel_config__set(this, pixfmt, pixsub, width, height);
1957 }
1958 
1959 inline void  //
invalidate()1960 wuffs_base__pixel_config::invalidate() {
1961   wuffs_base__pixel_config__invalidate(this);
1962 }
1963 
1964 inline bool  //
is_valid()1965 wuffs_base__pixel_config::is_valid() const {
1966   return wuffs_base__pixel_config__is_valid(this);
1967 }
1968 
1969 inline wuffs_base__pixel_format  //
pixel_format()1970 wuffs_base__pixel_config::pixel_format() const {
1971   return wuffs_base__pixel_config__pixel_format(this);
1972 }
1973 
1974 inline wuffs_base__pixel_subsampling  //
pixel_subsampling()1975 wuffs_base__pixel_config::pixel_subsampling() const {
1976   return wuffs_base__pixel_config__pixel_subsampling(this);
1977 }
1978 
1979 inline wuffs_base__rect_ie_u32  //
bounds()1980 wuffs_base__pixel_config::bounds() const {
1981   return wuffs_base__pixel_config__bounds(this);
1982 }
1983 
1984 inline uint32_t  //
width()1985 wuffs_base__pixel_config::width() const {
1986   return wuffs_base__pixel_config__width(this);
1987 }
1988 
1989 inline uint32_t  //
height()1990 wuffs_base__pixel_config::height() const {
1991   return wuffs_base__pixel_config__height(this);
1992 }
1993 
1994 inline uint64_t  //
pixbuf_len()1995 wuffs_base__pixel_config::pixbuf_len() const {
1996   return wuffs_base__pixel_config__pixbuf_len(this);
1997 }
1998 
1999 #endif  // __cplusplus
2000 
2001 // --------
2002 
2003 typedef struct {
2004   wuffs_base__pixel_config pixcfg;
2005 
2006   // Do not access the private_impl's fields directly. There is no API/ABI
2007   // compatibility or safety guarantee if you do so.
2008   struct {
2009     uint64_t first_frame_io_position;
2010     bool first_frame_is_opaque;
2011   } private_impl;
2012 
2013 #ifdef __cplusplus
2014   inline void set(wuffs_base__pixel_format pixfmt,
2015                   wuffs_base__pixel_subsampling pixsub,
2016                   uint32_t width,
2017                   uint32_t height,
2018                   uint64_t first_frame_io_position,
2019                   bool first_frame_is_opaque);
2020   inline void invalidate();
2021   inline bool is_valid() const;
2022   inline uint64_t first_frame_io_position() const;
2023   inline bool first_frame_is_opaque() const;
2024 #endif  // __cplusplus
2025 
2026 } wuffs_base__image_config;
2027 
2028 static inline wuffs_base__image_config  //
wuffs_base__null_image_config()2029 wuffs_base__null_image_config() {
2030   wuffs_base__image_config ret;
2031   ret.pixcfg = wuffs_base__null_pixel_config();
2032   ret.private_impl.first_frame_io_position = 0;
2033   ret.private_impl.first_frame_is_opaque = false;
2034   return ret;
2035 }
2036 
2037 // TODO: Should this function return bool? An error type?
2038 static inline void  //
wuffs_base__image_config__set(wuffs_base__image_config * c,wuffs_base__pixel_format pixfmt,wuffs_base__pixel_subsampling pixsub,uint32_t width,uint32_t height,uint64_t first_frame_io_position,bool first_frame_is_opaque)2039 wuffs_base__image_config__set(wuffs_base__image_config* c,
2040                               wuffs_base__pixel_format pixfmt,
2041                               wuffs_base__pixel_subsampling pixsub,
2042                               uint32_t width,
2043                               uint32_t height,
2044                               uint64_t first_frame_io_position,
2045                               bool first_frame_is_opaque) {
2046   if (!c) {
2047     return;
2048   }
2049   if (wuffs_base__pixel_format__is_valid(pixfmt)) {
2050     c->pixcfg.private_impl.pixfmt = pixfmt;
2051     c->pixcfg.private_impl.pixsub = pixsub;
2052     c->pixcfg.private_impl.width = width;
2053     c->pixcfg.private_impl.height = height;
2054     c->private_impl.first_frame_io_position = first_frame_io_position;
2055     c->private_impl.first_frame_is_opaque = first_frame_is_opaque;
2056     return;
2057   }
2058 
2059   c->pixcfg.private_impl.pixfmt = 0;
2060   c->pixcfg.private_impl.pixsub = 0;
2061   c->pixcfg.private_impl.width = 0;
2062   c->pixcfg.private_impl.height = 0;
2063   c->private_impl.first_frame_io_position = 0;
2064   c->private_impl.first_frame_is_opaque = 0;
2065 }
2066 
2067 static inline void  //
wuffs_base__image_config__invalidate(wuffs_base__image_config * c)2068 wuffs_base__image_config__invalidate(wuffs_base__image_config* c) {
2069   if (c) {
2070     c->pixcfg.private_impl.pixfmt = 0;
2071     c->pixcfg.private_impl.pixsub = 0;
2072     c->pixcfg.private_impl.width = 0;
2073     c->pixcfg.private_impl.height = 0;
2074     c->private_impl.first_frame_io_position = 0;
2075     c->private_impl.first_frame_is_opaque = 0;
2076   }
2077 }
2078 
2079 static inline bool  //
wuffs_base__image_config__is_valid(const wuffs_base__image_config * c)2080 wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {
2081   return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));
2082 }
2083 
2084 static inline uint64_t  //
wuffs_base__image_config__first_frame_io_position(const wuffs_base__image_config * c)2085 wuffs_base__image_config__first_frame_io_position(
2086     const wuffs_base__image_config* c) {
2087   return c ? c->private_impl.first_frame_io_position : 0;
2088 }
2089 
2090 static inline bool  //
wuffs_base__image_config__first_frame_is_opaque(const wuffs_base__image_config * c)2091 wuffs_base__image_config__first_frame_is_opaque(
2092     const wuffs_base__image_config* c) {
2093   return c ? c->private_impl.first_frame_is_opaque : false;
2094 }
2095 
2096 #ifdef __cplusplus
2097 
2098 inline void  //
set(wuffs_base__pixel_format pixfmt,wuffs_base__pixel_subsampling pixsub,uint32_t width,uint32_t height,uint64_t first_frame_io_position,bool first_frame_is_opaque)2099 wuffs_base__image_config::set(wuffs_base__pixel_format pixfmt,
2100                               wuffs_base__pixel_subsampling pixsub,
2101                               uint32_t width,
2102                               uint32_t height,
2103                               uint64_t first_frame_io_position,
2104                               bool first_frame_is_opaque) {
2105   wuffs_base__image_config__set(this, pixfmt, pixsub, width, height,
2106                                 first_frame_io_position, first_frame_is_opaque);
2107 }
2108 
2109 inline void  //
invalidate()2110 wuffs_base__image_config::invalidate() {
2111   wuffs_base__image_config__invalidate(this);
2112 }
2113 
2114 inline bool  //
is_valid()2115 wuffs_base__image_config::is_valid() const {
2116   return wuffs_base__image_config__is_valid(this);
2117 }
2118 
2119 inline uint64_t  //
first_frame_io_position()2120 wuffs_base__image_config::first_frame_io_position() const {
2121   return wuffs_base__image_config__first_frame_io_position(this);
2122 }
2123 
2124 inline bool  //
first_frame_is_opaque()2125 wuffs_base__image_config::first_frame_is_opaque() const {
2126   return wuffs_base__image_config__first_frame_is_opaque(this);
2127 }
2128 
2129 #endif  // __cplusplus
2130 
2131 // --------
2132 
2133 // wuffs_base__animation_blend encodes, for an animated image, how to blend the
2134 // transparent pixels of this frame with the existing canvas. In Porter-Duff
2135 // compositing operator terminology:
2136 //  - 0 means the frame may be transparent, and should be blended "src over
2137 //    dst", also known as just "over".
2138 //  - 1 means the frame may be transparent, and should be blended "src".
2139 //  - 2 means the frame is completely opaque, so that "src over dst" and "src"
2140 //    are equivalent.
2141 //
2142 // These semantics are conservative. It is valid for a completely opaque frame
2143 // to have a blend value other than 2.
2144 typedef uint8_t wuffs_base__animation_blend;
2145 
2146 #define WUFFS_BASE__ANIMATION_BLEND__SRC_OVER_DST \
2147   ((wuffs_base__animation_blend)0)
2148 #define WUFFS_BASE__ANIMATION_BLEND__SRC ((wuffs_base__animation_blend)1)
2149 #define WUFFS_BASE__ANIMATION_BLEND__OPAQUE ((wuffs_base__animation_blend)2)
2150 
2151 // --------
2152 
2153 // wuffs_base__animation_disposal encodes, for an animated image, how to
2154 // dispose of a frame after displaying it:
2155 //  - None means to draw the next frame on top of this one.
2156 //  - Restore Background means to clear the frame's dirty rectangle to "the
2157 //    background color" (in practice, this means transparent black) before
2158 //    drawing the next frame.
2159 //  - Restore Previous means to undo the current frame, so that the next frame
2160 //    is drawn on top of the previous one.
2161 typedef uint8_t wuffs_base__animation_disposal;
2162 
2163 #define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)
2164 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \
2165   ((wuffs_base__animation_disposal)1)
2166 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \
2167   ((wuffs_base__animation_disposal)2)
2168 
2169 // --------
2170 
2171 typedef struct {
2172   // Do not access the private_impl's fields directly. There is no API/ABI
2173   // compatibility or safety guarantee if you do so.
2174   struct {
2175     wuffs_base__rect_ie_u32 bounds;
2176     wuffs_base__flicks duration;
2177     uint64_t index;
2178     uint64_t io_position;
2179     wuffs_base__animation_blend blend;
2180     wuffs_base__animation_disposal disposal;
2181     wuffs_base__color_u32_argb_premul background_color;
2182   } private_impl;
2183 
2184 #ifdef __cplusplus
2185   inline void update(wuffs_base__rect_ie_u32 bounds,
2186                      wuffs_base__flicks duration,
2187                      uint64_t index,
2188                      uint64_t io_position,
2189                      wuffs_base__animation_blend blend,
2190                      wuffs_base__animation_disposal disposal,
2191                      wuffs_base__color_u32_argb_premul background_color);
2192   inline wuffs_base__rect_ie_u32 bounds() const;
2193   inline uint32_t width() const;
2194   inline uint32_t height() const;
2195   inline wuffs_base__flicks duration() const;
2196   inline uint64_t index() const;
2197   inline uint64_t io_position() const;
2198   inline wuffs_base__animation_blend blend() const;
2199   inline wuffs_base__animation_disposal disposal() const;
2200   inline wuffs_base__color_u32_argb_premul background_color() const;
2201 #endif  // __cplusplus
2202 
2203 } wuffs_base__frame_config;
2204 
2205 static inline wuffs_base__frame_config  //
wuffs_base__null_frame_config()2206 wuffs_base__null_frame_config() {
2207   wuffs_base__frame_config ret;
2208   ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);
2209   ret.private_impl.duration = 0;
2210   ret.private_impl.index = 0;
2211   ret.private_impl.io_position = 0;
2212   ret.private_impl.blend = 0;
2213   ret.private_impl.disposal = 0;
2214   return ret;
2215 }
2216 
2217 static inline void  //
wuffs_base__frame_config__update(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_blend blend,wuffs_base__animation_disposal disposal,wuffs_base__color_u32_argb_premul background_color)2218 wuffs_base__frame_config__update(
2219     wuffs_base__frame_config* c,
2220     wuffs_base__rect_ie_u32 bounds,
2221     wuffs_base__flicks duration,
2222     uint64_t index,
2223     uint64_t io_position,
2224     wuffs_base__animation_blend blend,
2225     wuffs_base__animation_disposal disposal,
2226     wuffs_base__color_u32_argb_premul background_color) {
2227   if (!c) {
2228     return;
2229   }
2230 
2231   c->private_impl.bounds = bounds;
2232   c->private_impl.duration = duration;
2233   c->private_impl.index = index;
2234   c->private_impl.io_position = io_position;
2235   c->private_impl.blend = blend;
2236   c->private_impl.disposal = disposal;
2237   c->private_impl.background_color = background_color;
2238 }
2239 
2240 static inline wuffs_base__rect_ie_u32  //
wuffs_base__frame_config__bounds(const wuffs_base__frame_config * c)2241 wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {
2242   if (c) {
2243     return c->private_impl.bounds;
2244   }
2245 
2246   wuffs_base__rect_ie_u32 ret;
2247   ret.min_incl_x = 0;
2248   ret.min_incl_y = 0;
2249   ret.max_excl_x = 0;
2250   ret.max_excl_y = 0;
2251   return ret;
2252 }
2253 
2254 static inline uint32_t  //
wuffs_base__frame_config__width(const wuffs_base__frame_config * c)2255 wuffs_base__frame_config__width(const wuffs_base__frame_config* c) {
2256   return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;
2257 }
2258 
2259 static inline uint32_t  //
wuffs_base__frame_config__height(const wuffs_base__frame_config * c)2260 wuffs_base__frame_config__height(const wuffs_base__frame_config* c) {
2261   return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;
2262 }
2263 
2264 // wuffs_base__frame_config__duration returns the amount of time to display
2265 // this frame. Zero means to display forever - a still (non-animated) image.
2266 static inline wuffs_base__flicks  //
wuffs_base__frame_config__duration(const wuffs_base__frame_config * c)2267 wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {
2268   return c ? c->private_impl.duration : 0;
2269 }
2270 
2271 // wuffs_base__frame_config__index returns the index of this frame. The first
2272 // frame in an image has index 0, the second frame has index 1, and so on.
2273 static inline uint64_t  //
wuffs_base__frame_config__index(const wuffs_base__frame_config * c)2274 wuffs_base__frame_config__index(const wuffs_base__frame_config* c) {
2275   return c ? c->private_impl.index : 0;
2276 }
2277 
2278 // wuffs_base__frame_config__io_position returns the I/O stream position before
2279 // the frame config.
2280 static inline uint64_t  //
wuffs_base__frame_config__io_position(const wuffs_base__frame_config * c)2281 wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {
2282   return c ? c->private_impl.io_position : 0;
2283 }
2284 
2285 // wuffs_base__frame_config__blend returns, for an animated image, how to blend
2286 // the transparent pixels of this frame with the existing canvas.
2287 static inline wuffs_base__animation_blend  //
wuffs_base__frame_config__blend(const wuffs_base__frame_config * c)2288 wuffs_base__frame_config__blend(const wuffs_base__frame_config* c) {
2289   return c ? c->private_impl.blend : 0;
2290 }
2291 
2292 // wuffs_base__frame_config__disposal returns, for an animated image, how to
2293 // dispose of this frame after displaying it.
2294 static inline wuffs_base__animation_disposal  //
wuffs_base__frame_config__disposal(const wuffs_base__frame_config * c)2295 wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {
2296   return c ? c->private_impl.disposal : 0;
2297 }
2298 
2299 static inline wuffs_base__color_u32_argb_premul  //
wuffs_base__frame_config__background_color(const wuffs_base__frame_config * c)2300 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
2301   return c ? c->private_impl.background_color : 0;
2302 }
2303 
2304 #ifdef __cplusplus
2305 
2306 inline void  //
update(wuffs_base__rect_ie_u32 bounds,wuffs_base__flicks duration,uint64_t index,uint64_t io_position,wuffs_base__animation_blend blend,wuffs_base__animation_disposal disposal,wuffs_base__color_u32_argb_premul background_color)2307 wuffs_base__frame_config::update(
2308     wuffs_base__rect_ie_u32 bounds,
2309     wuffs_base__flicks duration,
2310     uint64_t index,
2311     uint64_t io_position,
2312     wuffs_base__animation_blend blend,
2313     wuffs_base__animation_disposal disposal,
2314     wuffs_base__color_u32_argb_premul background_color) {
2315   wuffs_base__frame_config__update(this, bounds, duration, index, io_position,
2316                                    blend, disposal, background_color);
2317 }
2318 
2319 inline wuffs_base__rect_ie_u32  //
bounds()2320 wuffs_base__frame_config::bounds() const {
2321   return wuffs_base__frame_config__bounds(this);
2322 }
2323 
2324 inline uint32_t  //
width()2325 wuffs_base__frame_config::width() const {
2326   return wuffs_base__frame_config__width(this);
2327 }
2328 
2329 inline uint32_t  //
height()2330 wuffs_base__frame_config::height() const {
2331   return wuffs_base__frame_config__height(this);
2332 }
2333 
2334 inline wuffs_base__flicks  //
duration()2335 wuffs_base__frame_config::duration() const {
2336   return wuffs_base__frame_config__duration(this);
2337 }
2338 
2339 inline uint64_t  //
index()2340 wuffs_base__frame_config::index() const {
2341   return wuffs_base__frame_config__index(this);
2342 }
2343 
2344 inline uint64_t  //
io_position()2345 wuffs_base__frame_config::io_position() const {
2346   return wuffs_base__frame_config__io_position(this);
2347 }
2348 
2349 inline wuffs_base__animation_blend  //
blend()2350 wuffs_base__frame_config::blend() const {
2351   return wuffs_base__frame_config__blend(this);
2352 }
2353 
2354 inline wuffs_base__animation_disposal  //
disposal()2355 wuffs_base__frame_config::disposal() const {
2356   return wuffs_base__frame_config__disposal(this);
2357 }
2358 
2359 inline wuffs_base__color_u32_argb_premul  //
background_color()2360 wuffs_base__frame_config::background_color() const {
2361   return wuffs_base__frame_config__background_color(this);
2362 }
2363 
2364 #endif  // __cplusplus
2365 
2366 // --------
2367 
2368 typedef struct {
2369   wuffs_base__pixel_config pixcfg;
2370 
2371   // Do not access the private_impl's fields directly. There is no API/ABI
2372   // compatibility or safety guarantee if you do so.
2373   struct {
2374     wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX];
2375     // TODO: color spaces.
2376   } private_impl;
2377 
2378 #ifdef __cplusplus
2379   inline wuffs_base__status set_from_slice(wuffs_base__pixel_config* pixcfg,
2380                                            wuffs_base__slice_u8 pixbuf_memory);
2381   inline wuffs_base__status set_from_table(wuffs_base__pixel_config* pixcfg,
2382                                            wuffs_base__table_u8 pixbuf_memory);
2383   inline wuffs_base__slice_u8 palette();
2384   inline wuffs_base__pixel_format pixel_format() const;
2385   inline wuffs_base__table_u8 plane(uint32_t p);
2386 #endif  // __cplusplus
2387 
2388 } wuffs_base__pixel_buffer;
2389 
2390 static inline wuffs_base__pixel_buffer  //
wuffs_base__null_pixel_buffer()2391 wuffs_base__null_pixel_buffer() {
2392   wuffs_base__pixel_buffer ret;
2393   ret.pixcfg = wuffs_base__null_pixel_config();
2394   ret.private_impl.planes[0] = wuffs_base__null_table_u8();
2395   ret.private_impl.planes[1] = wuffs_base__null_table_u8();
2396   ret.private_impl.planes[2] = wuffs_base__null_table_u8();
2397   ret.private_impl.planes[3] = wuffs_base__null_table_u8();
2398   return ret;
2399 }
2400 
2401 static inline wuffs_base__status  //
wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer * b,wuffs_base__pixel_config * pixcfg,wuffs_base__slice_u8 pixbuf_memory)2402 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* b,
2403                                          wuffs_base__pixel_config* pixcfg,
2404                                          wuffs_base__slice_u8 pixbuf_memory) {
2405   if (!b) {
2406     return wuffs_base__error__bad_receiver;
2407   }
2408   memset(b, 0, sizeof(*b));
2409   if (!pixcfg) {
2410     return wuffs_base__error__bad_argument;
2411   }
2412   if (wuffs_base__pixel_format__is_planar(pixcfg->private_impl.pixfmt)) {
2413     // TODO: support planar pixel formats, concious of pixel subsampling.
2414     return wuffs_base__error__unsupported_option;
2415   }
2416   uint32_t bits_per_pixel =
2417       wuffs_base__pixel_format__bits_per_pixel(pixcfg->private_impl.pixfmt);
2418   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
2419     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
2420     return wuffs_base__error__unsupported_option;
2421   }
2422   uint64_t bytes_per_pixel = bits_per_pixel / 8;
2423 
2424   uint8_t* ptr = pixbuf_memory.ptr;
2425   uint64_t len = pixbuf_memory.len;
2426   if (wuffs_base__pixel_format__is_indexed(pixcfg->private_impl.pixfmt)) {
2427     // Split a 1024 byte chunk (256 palette entries × 4 bytes per entry) from
2428     // the start of pixbuf_memory. We split from the start, not the end, so
2429     // that the both chunks' pointers have the same alignment as the original
2430     // pointer, up to an alignment of 1024.
2431     if (len < 1024) {
2432       return wuffs_base__error__bad_argument_length_too_short;
2433     }
2434     wuffs_base__table_u8* tab =
2435         &b->private_impl.planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
2436     tab->ptr = ptr;
2437     tab->width = 1024;
2438     tab->height = 1;
2439     tab->stride = 1024;
2440     ptr += 1024;
2441     len -= 1024;
2442   }
2443 
2444   uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *
2445                 ((uint64_t)pixcfg->private_impl.height);
2446   size_t width = (size_t)(pixcfg->private_impl.width);
2447   if ((wh > (UINT64_MAX / bytes_per_pixel)) ||
2448       (width > (SIZE_MAX / bytes_per_pixel))) {
2449     return wuffs_base__error__bad_argument;
2450   }
2451   wh *= bytes_per_pixel;
2452   width *= bytes_per_pixel;
2453   if (wh > len) {
2454     return wuffs_base__error__bad_argument_length_too_short;
2455   }
2456 
2457   b->pixcfg = *pixcfg;
2458   wuffs_base__table_u8* tab = &b->private_impl.planes[0];
2459   tab->ptr = ptr;
2460   tab->width = width;
2461   tab->height = pixcfg->private_impl.height;
2462   tab->stride = width;
2463   return NULL;
2464 }
2465 
2466 static inline wuffs_base__status  //
wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer * b,wuffs_base__pixel_config * pixcfg,wuffs_base__table_u8 pixbuf_memory)2467 wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* b,
2468                                          wuffs_base__pixel_config* pixcfg,
2469                                          wuffs_base__table_u8 pixbuf_memory) {
2470   if (!b) {
2471     return wuffs_base__error__bad_receiver;
2472   }
2473   memset(b, 0, sizeof(*b));
2474   if (!pixcfg ||
2475       wuffs_base__pixel_format__is_planar(pixcfg->private_impl.pixfmt)) {
2476     return wuffs_base__error__bad_argument;
2477   }
2478   uint32_t bits_per_pixel =
2479       wuffs_base__pixel_format__bits_per_pixel(pixcfg->private_impl.pixfmt);
2480   if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
2481     // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
2482     return wuffs_base__error__unsupported_option;
2483   }
2484   uint64_t bytes_per_pixel = bits_per_pixel / 8;
2485 
2486   uint64_t width_in_bytes =
2487       ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
2488   if ((width_in_bytes > pixbuf_memory.width) ||
2489       (pixcfg->private_impl.height > pixbuf_memory.height)) {
2490     return wuffs_base__error__bad_argument;
2491   }
2492 
2493   b->pixcfg = *pixcfg;
2494   b->private_impl.planes[0] = pixbuf_memory;
2495   return NULL;
2496 }
2497 
2498 // wuffs_base__pixel_buffer__palette returns the palette color data. If
2499 // non-empty, it will have length 1024.
2500 static inline wuffs_base__slice_u8  //
wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer * b)2501 wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* b) {
2502   if (b &&
2503       wuffs_base__pixel_format__is_indexed(b->pixcfg.private_impl.pixfmt)) {
2504     wuffs_base__table_u8* tab =
2505         &b->private_impl.planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
2506     if ((tab->width == 1024) && (tab->height == 1)) {
2507       return wuffs_base__make_slice_u8(tab->ptr, 1024);
2508     }
2509   }
2510   return wuffs_base__make_slice_u8(NULL, 0);
2511 }
2512 
2513 static inline wuffs_base__pixel_format  //
wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer * b)2514 wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* b) {
2515   if (b) {
2516     return b->pixcfg.private_impl.pixfmt;
2517   }
2518   return WUFFS_BASE__PIXEL_FORMAT__INVALID;
2519 }
2520 
2521 static inline wuffs_base__table_u8  //
wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer * b,uint32_t p)2522 wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* b, uint32_t p) {
2523   if (b && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) {
2524     return b->private_impl.planes[p];
2525   }
2526 
2527   wuffs_base__table_u8 ret;
2528   ret.ptr = NULL;
2529   ret.width = 0;
2530   ret.height = 0;
2531   ret.stride = 0;
2532   return ret;
2533 }
2534 
2535 #ifdef __cplusplus
2536 
2537 inline wuffs_base__status  //
set_from_slice(wuffs_base__pixel_config * pixcfg,wuffs_base__slice_u8 pixbuf_memory)2538 wuffs_base__pixel_buffer::set_from_slice(wuffs_base__pixel_config* pixcfg,
2539                                          wuffs_base__slice_u8 pixbuf_memory) {
2540   return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg, pixbuf_memory);
2541 }
2542 
2543 inline wuffs_base__status  //
set_from_table(wuffs_base__pixel_config * pixcfg,wuffs_base__table_u8 pixbuf_memory)2544 wuffs_base__pixel_buffer::set_from_table(wuffs_base__pixel_config* pixcfg,
2545                                          wuffs_base__table_u8 pixbuf_memory) {
2546   return wuffs_base__pixel_buffer__set_from_table(this, pixcfg, pixbuf_memory);
2547 }
2548 
2549 inline wuffs_base__slice_u8  //
palette()2550 wuffs_base__pixel_buffer::palette() {
2551   return wuffs_base__pixel_buffer__palette(this);
2552 }
2553 
2554 inline wuffs_base__pixel_format  //
pixel_format()2555 wuffs_base__pixel_buffer::pixel_format() const {
2556   return wuffs_base__pixel_buffer__pixel_format(this);
2557 }
2558 
2559 inline wuffs_base__table_u8  //
plane(uint32_t p)2560 wuffs_base__pixel_buffer::plane(uint32_t p) {
2561   return wuffs_base__pixel_buffer__plane(this, p);
2562 }
2563 
2564 #endif  // __cplusplus
2565 
2566 // --------
2567 
2568 typedef struct {
2569   // Do not access the private_impl's fields directly. There is no API/ABI
2570   // compatibility or safety guarantee if you do so.
2571   struct {
2572     uint8_t TODO;
2573   } private_impl;
2574 
2575 #ifdef __cplusplus
2576 #endif  // __cplusplus
2577 
2578 } wuffs_base__decode_frame_options;
2579 
2580 #ifdef __cplusplus
2581 
2582 #endif  // __cplusplus
2583 
2584 // --------
2585 
2586 typedef struct {
2587   // Do not access the private_impl's fields directly. There is no API/ABI
2588   // compatibility or safety guarantee if you do so.
2589   struct {
2590     // TODO: should the func type take restrict pointers?
2591     uint64_t (*func)(wuffs_base__slice_u8 dst,
2592                      wuffs_base__slice_u8 dst_palette,
2593                      wuffs_base__slice_u8 src);
2594   } private_impl;
2595 
2596 #ifdef __cplusplus
2597   inline wuffs_base__status prepare(wuffs_base__pixel_format dst_format,
2598                                     wuffs_base__slice_u8 dst_palette,
2599                                     wuffs_base__pixel_format src_format,
2600                                     wuffs_base__slice_u8 src_palette);
2601   inline uint64_t swizzle_interleaved(wuffs_base__slice_u8 dst,
2602                                       wuffs_base__slice_u8 dst_palette,
2603                                       wuffs_base__slice_u8 src) const;
2604 #endif  // __cplusplus
2605 
2606 } wuffs_base__pixel_swizzler;
2607 
2608 wuffs_base__status  //
2609 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
2610                                     wuffs_base__pixel_format dst_format,
2611                                     wuffs_base__slice_u8 dst_palette,
2612                                     wuffs_base__pixel_format src_format,
2613                                     wuffs_base__slice_u8 src_palette);
2614 
2615 uint64_t  //
2616 wuffs_base__pixel_swizzler__swizzle_interleaved(
2617     const wuffs_base__pixel_swizzler* p,
2618     wuffs_base__slice_u8 dst,
2619     wuffs_base__slice_u8 dst_palette,
2620     wuffs_base__slice_u8 src);
2621 
2622 #ifdef __cplusplus
2623 
2624 inline wuffs_base__status  //
prepare(wuffs_base__pixel_format dst_format,wuffs_base__slice_u8 dst_palette,wuffs_base__pixel_format src_format,wuffs_base__slice_u8 src_palette)2625 wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_format,
2626                                     wuffs_base__slice_u8 dst_palette,
2627                                     wuffs_base__pixel_format src_format,
2628                                     wuffs_base__slice_u8 src_palette) {
2629   return wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette,
2630                                              src_format, src_palette);
2631 }
2632 
2633 uint64_t  //
swizzle_interleaved(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)2634 wuffs_base__pixel_swizzler::swizzle_interleaved(
2635     wuffs_base__slice_u8 dst,
2636     wuffs_base__slice_u8 dst_palette,
2637     wuffs_base__slice_u8 src) const {
2638   return wuffs_base__pixel_swizzler__swizzle_interleaved(this, dst, dst_palette,
2639                                                          src);
2640 }
2641 
2642 #endif  // __cplusplus
2643 
2644 #ifdef __cplusplus
2645 }  // extern "C"
2646 #endif
2647 
2648 #ifdef __clang__
2649 #pragma clang diagnostic pop
2650 #endif
2651 
2652 #ifdef __cplusplus
2653 extern "C" {
2654 #endif
2655 
2656 // ---------------- Status Codes
2657 
2658 // ---------------- Public Consts
2659 
2660 // ---------------- Struct Declarations
2661 
2662 typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
2663 
2664 // ---------------- Public Initializer Prototypes
2665 
2666 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
2667 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
2668 //
2669 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
2670 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
2671 
2672 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
2673 wuffs_adler32__hasher__initialize(wuffs_adler32__hasher* self,
2674                                   size_t sizeof_star_self,
2675                                   uint64_t wuffs_version,
2676                                   uint32_t initialize_flags);
2677 
2678 size_t  //
2679 sizeof__wuffs_adler32__hasher();
2680 
2681 // ---------------- Public Function Prototypes
2682 
2683 WUFFS_BASE__MAYBE_STATIC uint32_t  //
2684 wuffs_adler32__hasher__update(wuffs_adler32__hasher* self,
2685                               wuffs_base__slice_u8 a_x);
2686 
2687 // ---------------- Struct Definitions
2688 
2689 // These structs' fields, and the sizeof them, are private implementation
2690 // details that aren't guaranteed to be stable across Wuffs versions.
2691 //
2692 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
2693 
2694 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
2695 
2696 struct wuffs_adler32__hasher__struct {
2697 #ifdef WUFFS_IMPLEMENTATION
2698 
2699   // Do not access the private_impl's or private_data's fields directly. There
2700   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
2701   // the wuffs_foo__bar__baz functions.
2702   //
2703   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
2704   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
2705 
2706   struct {
2707     uint32_t magic;
2708     uint32_t active_coroutine;
2709 
2710     uint32_t f_state;
2711     bool f_started;
2712 
2713   } private_impl;
2714 
2715 #else  // WUFFS_IMPLEMENTATION
2716 
2717   // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
2718   // large enough to discourage trying to allocate one on the stack. The sizeof
2719   // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
2720   // struct) is not part of the public, stable, memory-safe API. Call
2721   // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
2722   // first argument) instead of fiddling with bar.private_impl.qux fields.
2723   //
2724   // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
2725   // defines C++ convenience methods. These methods forward on "this", so that
2726   // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
2727  private:
2728   union {
2729     uint32_t align_as_per_magic_field;
2730     uint8_t placeholder[1073741824];  // 1 GiB.
2731   } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
2732 
2733  public:
2734 
2735 #endif  // WUFFS_IMPLEMENTATION
2736 
2737 #ifdef __cplusplus
2738 
2739   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
initializewuffs_adler32__hasher__struct2740   initialize(size_t sizeof_star_self,
2741              uint64_t wuffs_version,
2742              uint32_t initialize_flags) {
2743     return wuffs_adler32__hasher__initialize(this, sizeof_star_self,
2744                                              wuffs_version, initialize_flags);
2745   }
2746 
2747   inline uint32_t  //
updatewuffs_adler32__hasher__struct2748   update(wuffs_base__slice_u8 a_x) {
2749     return wuffs_adler32__hasher__update(this, a_x);
2750   }
2751 
2752 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
2753   // Disallow copy and assign.
2754   wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
2755   wuffs_adler32__hasher__struct& operator=(
2756       const wuffs_adler32__hasher__struct&) = delete;
2757 #endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
2758 
2759 #endif  // __cplusplus
2760 
2761 };  // struct wuffs_adler32__hasher__struct
2762 
2763 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
2764 
2765 #ifdef __cplusplus
2766 }  // extern "C"
2767 #endif
2768 
2769 #ifdef __cplusplus
2770 extern "C" {
2771 #endif
2772 
2773 // ---------------- Status Codes
2774 
2775 // ---------------- Public Consts
2776 
2777 // ---------------- Struct Declarations
2778 
2779 typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
2780 
2781 // ---------------- Public Initializer Prototypes
2782 
2783 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
2784 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
2785 //
2786 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
2787 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
2788 
2789 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
2790 wuffs_crc32__ieee_hasher__initialize(wuffs_crc32__ieee_hasher* self,
2791                                      size_t sizeof_star_self,
2792                                      uint64_t wuffs_version,
2793                                      uint32_t initialize_flags);
2794 
2795 size_t  //
2796 sizeof__wuffs_crc32__ieee_hasher();
2797 
2798 // ---------------- Public Function Prototypes
2799 
2800 WUFFS_BASE__MAYBE_STATIC uint32_t  //
2801 wuffs_crc32__ieee_hasher__update(wuffs_crc32__ieee_hasher* self,
2802                                  wuffs_base__slice_u8 a_x);
2803 
2804 // ---------------- Struct Definitions
2805 
2806 // These structs' fields, and the sizeof them, are private implementation
2807 // details that aren't guaranteed to be stable across Wuffs versions.
2808 //
2809 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
2810 
2811 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
2812 
2813 struct wuffs_crc32__ieee_hasher__struct {
2814 #ifdef WUFFS_IMPLEMENTATION
2815 
2816   // Do not access the private_impl's or private_data's fields directly. There
2817   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
2818   // the wuffs_foo__bar__baz functions.
2819   //
2820   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
2821   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
2822 
2823   struct {
2824     uint32_t magic;
2825     uint32_t active_coroutine;
2826 
2827     uint32_t f_state;
2828 
2829   } private_impl;
2830 
2831 #else  // WUFFS_IMPLEMENTATION
2832 
2833   // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
2834   // large enough to discourage trying to allocate one on the stack. The sizeof
2835   // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
2836   // struct) is not part of the public, stable, memory-safe API. Call
2837   // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
2838   // first argument) instead of fiddling with bar.private_impl.qux fields.
2839   //
2840   // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
2841   // defines C++ convenience methods. These methods forward on "this", so that
2842   // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
2843  private:
2844   union {
2845     uint32_t align_as_per_magic_field;
2846     uint8_t placeholder[1073741824];  // 1 GiB.
2847   } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
2848 
2849  public:
2850 
2851 #endif  // WUFFS_IMPLEMENTATION
2852 
2853 #ifdef __cplusplus
2854 
2855   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
initializewuffs_crc32__ieee_hasher__struct2856   initialize(size_t sizeof_star_self,
2857              uint64_t wuffs_version,
2858              uint32_t initialize_flags) {
2859     return wuffs_crc32__ieee_hasher__initialize(
2860         this, sizeof_star_self, wuffs_version, initialize_flags);
2861   }
2862 
2863   inline uint32_t  //
updatewuffs_crc32__ieee_hasher__struct2864   update(wuffs_base__slice_u8 a_x) {
2865     return wuffs_crc32__ieee_hasher__update(this, a_x);
2866   }
2867 
2868 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
2869   // Disallow copy and assign.
2870   wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) =
2871       delete;
2872   wuffs_crc32__ieee_hasher__struct& operator=(
2873       const wuffs_crc32__ieee_hasher__struct&) = delete;
2874 #endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
2875 
2876 #endif  // __cplusplus
2877 
2878 };  // struct wuffs_crc32__ieee_hasher__struct
2879 
2880 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
2881 
2882 #ifdef __cplusplus
2883 }  // extern "C"
2884 #endif
2885 
2886 #ifdef __cplusplus
2887 extern "C" {
2888 #endif
2889 
2890 // ---------------- Status Codes
2891 
2892 extern const char* wuffs_deflate__error__bad_huffman_code_over_subscribed;
2893 extern const char* wuffs_deflate__error__bad_huffman_code_under_subscribed;
2894 extern const char* wuffs_deflate__error__bad_huffman_code_length_count;
2895 extern const char* wuffs_deflate__error__bad_huffman_code_length_repetition;
2896 extern const char* wuffs_deflate__error__bad_huffman_code;
2897 extern const char* wuffs_deflate__error__bad_huffman_minimum_code_length;
2898 extern const char* wuffs_deflate__error__bad_block;
2899 extern const char* wuffs_deflate__error__bad_distance;
2900 extern const char* wuffs_deflate__error__bad_distance_code_count;
2901 extern const char* wuffs_deflate__error__bad_literal_length_code_count;
2902 extern const char* wuffs_deflate__error__inconsistent_stored_block_length;
2903 extern const char* wuffs_deflate__error__missing_end_of_block_code;
2904 extern const char* wuffs_deflate__error__no_huffman_codes;
2905 
2906 // ---------------- Public Consts
2907 
2908 #define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
2909 
2910 static const uint64_t                                       //
2911     wuffs_deflate__decoder_workbuf_len_max_incl_worst_case  //
2912         WUFFS_BASE__POTENTIALLY_UNUSED = 1;
2913 
2914 // ---------------- Struct Declarations
2915 
2916 typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
2917 
2918 // ---------------- Public Initializer Prototypes
2919 
2920 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
2921 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
2922 //
2923 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
2924 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
2925 
2926 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
2927 wuffs_deflate__decoder__initialize(wuffs_deflate__decoder* self,
2928                                    size_t sizeof_star_self,
2929                                    uint64_t wuffs_version,
2930                                    uint32_t initialize_flags);
2931 
2932 size_t  //
2933 sizeof__wuffs_deflate__decoder();
2934 
2935 // ---------------- Public Function Prototypes
2936 
2937 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
2938 wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder* self);
2939 
2940 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
2941 wuffs_deflate__decoder__decode_io_writer(wuffs_deflate__decoder* self,
2942                                          wuffs_base__io_buffer* a_dst,
2943                                          wuffs_base__io_buffer* a_src,
2944                                          wuffs_base__slice_u8 a_workbuf);
2945 
2946 // ---------------- Struct Definitions
2947 
2948 // These structs' fields, and the sizeof them, are private implementation
2949 // details that aren't guaranteed to be stable across Wuffs versions.
2950 //
2951 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
2952 
2953 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
2954 
2955 struct wuffs_deflate__decoder__struct {
2956 #ifdef WUFFS_IMPLEMENTATION
2957 
2958   // Do not access the private_impl's or private_data's fields directly. There
2959   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
2960   // the wuffs_foo__bar__baz functions.
2961   //
2962   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
2963   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
2964 
2965   struct {
2966     uint32_t magic;
2967     uint32_t active_coroutine;
2968 
2969     uint32_t f_bits;
2970     uint32_t f_n_bits;
2971     uint32_t f_history_index;
2972     uint32_t f_n_huffs_bits[2];
2973     bool f_end_of_block;
2974 
2975     uint32_t p_decode_io_writer[1];
2976     uint32_t p_decode_blocks[1];
2977     uint32_t p_decode_uncompressed[1];
2978     uint32_t p_init_dynamic_huffman[1];
2979     uint32_t p_decode_huffman_slow[1];
2980   } private_impl;
2981 
2982   struct {
2983     uint32_t f_huffs[2][1024];
2984     uint8_t f_history[32768];
2985     uint8_t f_code_lengths[320];
2986 
2987     struct {
2988       uint32_t v_final;
2989     } s_decode_blocks[1];
2990     struct {
2991       uint32_t v_length;
2992       uint64_t scratch;
2993     } s_decode_uncompressed[1];
2994     struct {
2995       uint32_t v_bits;
2996       uint32_t v_n_bits;
2997       uint32_t v_n_lit;
2998       uint32_t v_n_dist;
2999       uint32_t v_n_clen;
3000       uint32_t v_i;
3001       uint32_t v_mask;
3002       uint32_t v_table_entry;
3003       uint32_t v_n_extra_bits;
3004       uint8_t v_rep_symbol;
3005       uint32_t v_rep_count;
3006     } s_init_dynamic_huffman[1];
3007     struct {
3008       uint32_t v_bits;
3009       uint32_t v_n_bits;
3010       uint32_t v_table_entry;
3011       uint32_t v_table_entry_n_bits;
3012       uint32_t v_lmask;
3013       uint32_t v_dmask;
3014       uint32_t v_redir_top;
3015       uint32_t v_redir_mask;
3016       uint32_t v_length;
3017       uint32_t v_dist_minus_1;
3018       uint32_t v_hlen;
3019       uint32_t v_hdist;
3020     } s_decode_huffman_slow[1];
3021   } private_data;
3022 
3023 #else  // WUFFS_IMPLEMENTATION
3024 
3025   // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
3026   // large enough to discourage trying to allocate one on the stack. The sizeof
3027   // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
3028   // struct) is not part of the public, stable, memory-safe API. Call
3029   // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
3030   // first argument) instead of fiddling with bar.private_impl.qux fields.
3031   //
3032   // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
3033   // defines C++ convenience methods. These methods forward on "this", so that
3034   // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
3035  private:
3036   union {
3037     uint32_t align_as_per_magic_field;
3038     uint8_t placeholder[1073741824];  // 1 GiB.
3039   } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
3040 
3041  public:
3042 
3043 #endif  // WUFFS_IMPLEMENTATION
3044 
3045 #ifdef __cplusplus
3046 
3047   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
initializewuffs_deflate__decoder__struct3048   initialize(size_t sizeof_star_self,
3049              uint64_t wuffs_version,
3050              uint32_t initialize_flags) {
3051     return wuffs_deflate__decoder__initialize(this, sizeof_star_self,
3052                                               wuffs_version, initialize_flags);
3053   }
3054 
3055   inline wuffs_base__range_ii_u64  //
workbuf_lenwuffs_deflate__decoder__struct3056   workbuf_len() const {
3057     return wuffs_deflate__decoder__workbuf_len(this);
3058   }
3059 
3060   inline wuffs_base__status  //
decode_io_writerwuffs_deflate__decoder__struct3061   decode_io_writer(wuffs_base__io_buffer* a_dst,
3062                    wuffs_base__io_buffer* a_src,
3063                    wuffs_base__slice_u8 a_workbuf) {
3064     return wuffs_deflate__decoder__decode_io_writer(this, a_dst, a_src,
3065                                                     a_workbuf);
3066   }
3067 
3068 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3069   // Disallow copy and assign.
3070   wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) =
3071       delete;
3072   wuffs_deflate__decoder__struct& operator=(
3073       const wuffs_deflate__decoder__struct&) = delete;
3074 #endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3075 
3076 #endif  // __cplusplus
3077 
3078 };  // struct wuffs_deflate__decoder__struct
3079 
3080 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3081 
3082 #ifdef __cplusplus
3083 }  // extern "C"
3084 #endif
3085 
3086 #ifdef __cplusplus
3087 extern "C" {
3088 #endif
3089 
3090 // ---------------- Status Codes
3091 
3092 extern const char* wuffs_lzw__error__bad_code;
3093 
3094 // ---------------- Public Consts
3095 
3096 #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
3097 
3098 static const uint64_t                                   //
3099     wuffs_lzw__decoder_workbuf_len_max_incl_worst_case  //
3100         WUFFS_BASE__POTENTIALLY_UNUSED = 0;
3101 
3102 // ---------------- Struct Declarations
3103 
3104 typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
3105 
3106 // ---------------- Public Initializer Prototypes
3107 
3108 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
3109 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
3110 //
3111 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
3112 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
3113 
3114 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
3115 wuffs_lzw__decoder__initialize(wuffs_lzw__decoder* self,
3116                                size_t sizeof_star_self,
3117                                uint64_t wuffs_version,
3118                                uint32_t initialize_flags);
3119 
3120 size_t  //
3121 sizeof__wuffs_lzw__decoder();
3122 
3123 // ---------------- Public Function Prototypes
3124 
3125 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
3126 wuffs_lzw__decoder__set_literal_width(wuffs_lzw__decoder* self, uint32_t a_lw);
3127 
3128 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
3129 wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder* self);
3130 
3131 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3132 wuffs_lzw__decoder__decode_io_writer(wuffs_lzw__decoder* self,
3133                                      wuffs_base__io_buffer* a_dst,
3134                                      wuffs_base__io_buffer* a_src,
3135                                      wuffs_base__slice_u8 a_workbuf);
3136 
3137 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8  //
3138 wuffs_lzw__decoder__flush(wuffs_lzw__decoder* self);
3139 
3140 // ---------------- Struct Definitions
3141 
3142 // These structs' fields, and the sizeof them, are private implementation
3143 // details that aren't guaranteed to be stable across Wuffs versions.
3144 //
3145 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
3146 
3147 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3148 
3149 struct wuffs_lzw__decoder__struct {
3150 #ifdef WUFFS_IMPLEMENTATION
3151 
3152   // Do not access the private_impl's or private_data's fields directly. There
3153   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
3154   // the wuffs_foo__bar__baz functions.
3155   //
3156   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
3157   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
3158 
3159   struct {
3160     uint32_t magic;
3161     uint32_t active_coroutine;
3162 
3163     uint32_t f_set_literal_width_arg;
3164     uint32_t f_literal_width;
3165     uint32_t f_clear_code;
3166     uint32_t f_end_code;
3167     uint32_t f_save_code;
3168     uint32_t f_prev_code;
3169     uint32_t f_width;
3170     uint32_t f_bits;
3171     uint32_t f_n_bits;
3172     uint32_t f_output_ri;
3173     uint32_t f_output_wi;
3174     uint32_t f_read_from_return_value;
3175     uint16_t f_prefixes[4096];
3176 
3177     uint32_t p_decode_io_writer[1];
3178     uint32_t p_write_to[1];
3179   } private_impl;
3180 
3181   struct {
3182     uint8_t f_suffixes[4096][8];
3183     uint16_t f_lm1s[4096];
3184     uint8_t f_output[8199];
3185 
3186   } private_data;
3187 
3188 #else  // WUFFS_IMPLEMENTATION
3189 
3190   // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
3191   // large enough to discourage trying to allocate one on the stack. The sizeof
3192   // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
3193   // struct) is not part of the public, stable, memory-safe API. Call
3194   // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
3195   // first argument) instead of fiddling with bar.private_impl.qux fields.
3196   //
3197   // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
3198   // defines C++ convenience methods. These methods forward on "this", so that
3199   // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
3200  private:
3201   union {
3202     uint32_t align_as_per_magic_field;
3203     uint8_t placeholder[1073741824];  // 1 GiB.
3204   } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
3205 
3206  public:
3207 
3208 #endif  // WUFFS_IMPLEMENTATION
3209 
3210 #ifdef __cplusplus
3211 
3212   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
initializewuffs_lzw__decoder__struct3213   initialize(size_t sizeof_star_self,
3214              uint64_t wuffs_version,
3215              uint32_t initialize_flags) {
3216     return wuffs_lzw__decoder__initialize(this, sizeof_star_self, wuffs_version,
3217                                           initialize_flags);
3218   }
3219 
3220   inline wuffs_base__empty_struct  //
set_literal_widthwuffs_lzw__decoder__struct3221   set_literal_width(uint32_t a_lw) {
3222     return wuffs_lzw__decoder__set_literal_width(this, a_lw);
3223   }
3224 
3225   inline wuffs_base__range_ii_u64  //
workbuf_lenwuffs_lzw__decoder__struct3226   workbuf_len() const {
3227     return wuffs_lzw__decoder__workbuf_len(this);
3228   }
3229 
3230   inline wuffs_base__status  //
decode_io_writerwuffs_lzw__decoder__struct3231   decode_io_writer(wuffs_base__io_buffer* a_dst,
3232                    wuffs_base__io_buffer* a_src,
3233                    wuffs_base__slice_u8 a_workbuf) {
3234     return wuffs_lzw__decoder__decode_io_writer(this, a_dst, a_src, a_workbuf);
3235   }
3236 
3237   inline wuffs_base__slice_u8  //
flushwuffs_lzw__decoder__struct3238   flush() {
3239     return wuffs_lzw__decoder__flush(this);
3240   }
3241 
3242 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3243   // Disallow copy and assign.
3244   wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
3245   wuffs_lzw__decoder__struct& operator=(const wuffs_lzw__decoder__struct&) =
3246       delete;
3247 #endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3248 
3249 #endif  // __cplusplus
3250 
3251 };  // struct wuffs_lzw__decoder__struct
3252 
3253 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3254 
3255 #ifdef __cplusplus
3256 }  // extern "C"
3257 #endif
3258 
3259 #ifdef __cplusplus
3260 extern "C" {
3261 #endif
3262 
3263 // ---------------- Status Codes
3264 
3265 extern const char* wuffs_gif__error__bad_block;
3266 extern const char* wuffs_gif__error__bad_extension_label;
3267 extern const char* wuffs_gif__error__bad_frame_size;
3268 extern const char* wuffs_gif__error__bad_graphic_control;
3269 extern const char* wuffs_gif__error__bad_header;
3270 extern const char* wuffs_gif__error__bad_literal_width;
3271 extern const char* wuffs_gif__error__bad_palette;
3272 
3273 // ---------------- Public Consts
3274 
3275 #define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
3276 
3277 static const uint64_t                                   //
3278     wuffs_gif__decoder_workbuf_len_max_incl_worst_case  //
3279         WUFFS_BASE__POTENTIALLY_UNUSED = 1;
3280 
3281 #define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328
3282 
3283 static const uint32_t                          //
3284     wuffs_gif__quirk_delay_num_decoded_frames  //
3285         WUFFS_BASE__POTENTIALLY_UNUSED = 1041635328;
3286 
3287 #define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND \
3288   1041635329
3289 
3290 static const uint32_t                                                  //
3291     wuffs_gif__quirk_first_frame_local_palette_means_black_background  //
3292         WUFFS_BASE__POTENTIALLY_UNUSED = 1041635329;
3293 
3294 #define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330
3295 
3296 static const uint32_t                        //
3297     wuffs_gif__quirk_honor_background_color  //
3298         WUFFS_BASE__POTENTIALLY_UNUSED = 1041635330;
3299 
3300 #define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331
3301 
3302 static const uint32_t                            //
3303     wuffs_gif__quirk_ignore_too_much_pixel_data  //
3304         WUFFS_BASE__POTENTIALLY_UNUSED = 1041635331;
3305 
3306 #define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332
3307 
3308 static const uint32_t                         //
3309     wuffs_gif__quirk_image_bounds_are_strict  //
3310         WUFFS_BASE__POTENTIALLY_UNUSED = 1041635332;
3311 
3312 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333
3313 
3314 static const uint32_t                    //
3315     wuffs_gif__quirk_reject_empty_frame  //
3316         WUFFS_BASE__POTENTIALLY_UNUSED = 1041635333;
3317 
3318 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334
3319 
3320 static const uint32_t                      //
3321     wuffs_gif__quirk_reject_empty_palette  //
3322         WUFFS_BASE__POTENTIALLY_UNUSED = 1041635334;
3323 
3324 // ---------------- Struct Declarations
3325 
3326 typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder;
3327 
3328 // ---------------- Public Initializer Prototypes
3329 
3330 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
3331 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
3332 //
3333 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
3334 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
3335 
3336 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
3337 wuffs_gif__decoder__initialize(wuffs_gif__decoder* self,
3338                                size_t sizeof_star_self,
3339                                uint64_t wuffs_version,
3340                                uint32_t initialize_flags);
3341 
3342 size_t  //
3343 sizeof__wuffs_gif__decoder();
3344 
3345 // ---------------- Public Function Prototypes
3346 
3347 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
3348 wuffs_gif__decoder__set_quirk_enabled(wuffs_gif__decoder* self,
3349                                       uint32_t a_quirk,
3350                                       bool a_enabled);
3351 
3352 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3353 wuffs_gif__decoder__decode_image_config(wuffs_gif__decoder* self,
3354                                         wuffs_base__image_config* a_dst,
3355                                         wuffs_base__io_buffer* a_src);
3356 
3357 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
3358 wuffs_gif__decoder__set_report_metadata(wuffs_gif__decoder* self,
3359                                         uint32_t a_fourcc,
3360                                         bool a_report);
3361 
3362 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3363 wuffs_gif__decoder__ack_metadata_chunk(wuffs_gif__decoder* self,
3364                                        wuffs_base__io_buffer* a_src);
3365 
3366 WUFFS_BASE__MAYBE_STATIC uint32_t  //
3367 wuffs_gif__decoder__metadata_fourcc(const wuffs_gif__decoder* self);
3368 
3369 WUFFS_BASE__MAYBE_STATIC uint64_t  //
3370 wuffs_gif__decoder__metadata_chunk_length(const wuffs_gif__decoder* self);
3371 
3372 WUFFS_BASE__MAYBE_STATIC uint32_t  //
3373 wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder* self);
3374 
3375 WUFFS_BASE__MAYBE_STATIC uint64_t  //
3376 wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder* self);
3377 
3378 WUFFS_BASE__MAYBE_STATIC uint64_t  //
3379 wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder* self);
3380 
3381 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32  //
3382 wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder* self);
3383 
3384 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
3385 wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder* self);
3386 
3387 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3388 wuffs_gif__decoder__restart_frame(wuffs_gif__decoder* self,
3389                                   uint64_t a_index,
3390                                   uint64_t a_io_position);
3391 
3392 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3393 wuffs_gif__decoder__decode_frame_config(wuffs_gif__decoder* self,
3394                                         wuffs_base__frame_config* a_dst,
3395                                         wuffs_base__io_buffer* a_src);
3396 
3397 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3398 wuffs_gif__decoder__decode_frame(wuffs_gif__decoder* self,
3399                                  wuffs_base__pixel_buffer* a_dst,
3400                                  wuffs_base__io_buffer* a_src,
3401                                  wuffs_base__slice_u8 a_workbuf,
3402                                  wuffs_base__decode_frame_options* a_opts);
3403 
3404 // ---------------- Struct Definitions
3405 
3406 // These structs' fields, and the sizeof them, are private implementation
3407 // details that aren't guaranteed to be stable across Wuffs versions.
3408 //
3409 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
3410 
3411 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3412 
3413 struct wuffs_gif__decoder__struct {
3414 #ifdef WUFFS_IMPLEMENTATION
3415 
3416   // Do not access the private_impl's or private_data's fields directly. There
3417   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
3418   // the wuffs_foo__bar__baz functions.
3419   //
3420   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
3421   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
3422 
3423   struct {
3424     uint32_t magic;
3425     uint32_t active_coroutine;
3426 
3427     uint32_t f_width;
3428     uint32_t f_height;
3429     uint8_t f_call_sequence;
3430     bool f_ignore_metadata;
3431     bool f_report_metadata_iccp;
3432     bool f_report_metadata_xmp;
3433     uint32_t f_metadata_fourcc_value;
3434     uint64_t f_metadata_chunk_length_value;
3435     uint64_t f_metadata_io_position;
3436     bool f_quirk_enabled_delay_num_decoded_frames;
3437     bool f_quirk_enabled_first_frame_local_palette_means_black_background;
3438     bool f_quirk_enabled_honor_background_color;
3439     bool f_quirk_enabled_ignore_too_much_pixel_data;
3440     bool f_quirk_enabled_image_bounds_are_strict;
3441     bool f_quirk_enabled_reject_empty_frame;
3442     bool f_quirk_enabled_reject_empty_palette;
3443     bool f_delayed_num_decoded_frames;
3444     bool f_end_of_data;
3445     bool f_restarted;
3446     bool f_previous_lzw_decode_ended_abruptly;
3447     bool f_has_global_palette;
3448     uint8_t f_interlace;
3449     bool f_seen_num_loops;
3450     uint32_t f_num_loops;
3451     uint32_t f_background_color_u32_argb_premul;
3452     uint32_t f_black_color_u32_argb_premul;
3453     bool f_gc_has_transparent_index;
3454     uint8_t f_gc_transparent_index;
3455     uint8_t f_gc_disposal;
3456     uint64_t f_gc_duration;
3457     uint64_t f_frame_config_io_position;
3458     uint64_t f_num_decoded_frame_configs_value;
3459     uint64_t f_num_decoded_frames_value;
3460     uint32_t f_frame_rect_x0;
3461     uint32_t f_frame_rect_y0;
3462     uint32_t f_frame_rect_x1;
3463     uint32_t f_frame_rect_y1;
3464     uint32_t f_dst_x;
3465     uint32_t f_dst_y;
3466     wuffs_base__range_ie_u32 f_dirty_y;
3467     uint64_t f_compressed_ri;
3468     uint64_t f_compressed_wi;
3469     wuffs_base__pixel_swizzler f_swizzler;
3470 
3471     uint32_t p_decode_image_config[1];
3472     uint32_t p_ack_metadata_chunk[1];
3473     uint32_t p_decode_frame_config[1];
3474     uint32_t p_skip_frame[1];
3475     uint32_t p_decode_frame[1];
3476     uint32_t p_decode_up_to_id_part1[1];
3477     uint32_t p_decode_header[1];
3478     uint32_t p_decode_lsd[1];
3479     uint32_t p_decode_extension[1];
3480     uint32_t p_skip_blocks[1];
3481     uint32_t p_decode_ae[1];
3482     uint32_t p_decode_gc[1];
3483     uint32_t p_decode_id_part0[1];
3484     uint32_t p_decode_id_part1[1];
3485     uint32_t p_decode_id_part2[1];
3486   } private_impl;
3487 
3488   struct {
3489     uint8_t f_compressed[4096];
3490     uint8_t f_palettes[2][1024];
3491     uint8_t f_dst_palette[1024];
3492     wuffs_lzw__decoder f_lzw;
3493 
3494     struct {
3495       uint8_t v_blend;
3496       uint32_t v_background_color;
3497     } s_decode_frame_config[1];
3498     struct {
3499       uint64_t scratch;
3500     } s_skip_frame[1];
3501     struct {
3502       uint8_t v_c[6];
3503       uint32_t v_i;
3504     } s_decode_header[1];
3505     struct {
3506       uint8_t v_flags;
3507       uint8_t v_background_color_index;
3508       uint32_t v_num_palette_entries;
3509       uint32_t v_i;
3510       uint64_t scratch;
3511     } s_decode_lsd[1];
3512     struct {
3513       uint64_t scratch;
3514     } s_skip_blocks[1];
3515     struct {
3516       uint8_t v_block_size;
3517       bool v_is_animexts;
3518       bool v_is_netscape;
3519       bool v_is_iccp;
3520       bool v_is_xmp;
3521       uint64_t scratch;
3522     } s_decode_ae[1];
3523     struct {
3524       uint64_t scratch;
3525     } s_decode_gc[1];
3526     struct {
3527       uint64_t scratch;
3528     } s_decode_id_part0[1];
3529     struct {
3530       uint8_t v_which_palette;
3531       uint32_t v_num_palette_entries;
3532       uint32_t v_i;
3533       uint64_t scratch;
3534     } s_decode_id_part1[1];
3535     struct {
3536       uint64_t v_block_size;
3537       bool v_need_block_size;
3538       wuffs_base__status v_lzw_status;
3539       uint64_t scratch;
3540     } s_decode_id_part2[1];
3541   } private_data;
3542 
3543 #else  // WUFFS_IMPLEMENTATION
3544 
3545   // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
3546   // large enough to discourage trying to allocate one on the stack. The sizeof
3547   // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
3548   // struct) is not part of the public, stable, memory-safe API. Call
3549   // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
3550   // first argument) instead of fiddling with bar.private_impl.qux fields.
3551   //
3552   // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
3553   // defines C++ convenience methods. These methods forward on "this", so that
3554   // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
3555  private:
3556   union {
3557     uint32_t align_as_per_magic_field;
3558     uint8_t placeholder[1073741824];  // 1 GiB.
3559   } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
3560 
3561  public:
3562 
3563 #endif  // WUFFS_IMPLEMENTATION
3564 
3565 #ifdef __cplusplus
3566 
3567   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
initializewuffs_gif__decoder__struct3568   initialize(size_t sizeof_star_self,
3569              uint64_t wuffs_version,
3570              uint32_t initialize_flags) {
3571     return wuffs_gif__decoder__initialize(this, sizeof_star_self, wuffs_version,
3572                                           initialize_flags);
3573   }
3574 
3575   inline wuffs_base__empty_struct  //
set_quirk_enabledwuffs_gif__decoder__struct3576   set_quirk_enabled(uint32_t a_quirk, bool a_enabled) {
3577     return wuffs_gif__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
3578   }
3579 
3580   inline wuffs_base__status  //
decode_image_configwuffs_gif__decoder__struct3581   decode_image_config(wuffs_base__image_config* a_dst,
3582                       wuffs_base__io_buffer* a_src) {
3583     return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
3584   }
3585 
3586   inline wuffs_base__empty_struct  //
set_report_metadatawuffs_gif__decoder__struct3587   set_report_metadata(uint32_t a_fourcc, bool a_report) {
3588     return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
3589   }
3590 
3591   inline wuffs_base__status  //
ack_metadata_chunkwuffs_gif__decoder__struct3592   ack_metadata_chunk(wuffs_base__io_buffer* a_src) {
3593     return wuffs_gif__decoder__ack_metadata_chunk(this, a_src);
3594   }
3595 
3596   inline uint32_t  //
metadata_fourccwuffs_gif__decoder__struct3597   metadata_fourcc() const {
3598     return wuffs_gif__decoder__metadata_fourcc(this);
3599   }
3600 
3601   inline uint64_t  //
metadata_chunk_lengthwuffs_gif__decoder__struct3602   metadata_chunk_length() const {
3603     return wuffs_gif__decoder__metadata_chunk_length(this);
3604   }
3605 
3606   inline uint32_t  //
num_animation_loopswuffs_gif__decoder__struct3607   num_animation_loops() const {
3608     return wuffs_gif__decoder__num_animation_loops(this);
3609   }
3610 
3611   inline uint64_t  //
num_decoded_frame_configswuffs_gif__decoder__struct3612   num_decoded_frame_configs() const {
3613     return wuffs_gif__decoder__num_decoded_frame_configs(this);
3614   }
3615 
3616   inline uint64_t  //
num_decoded_frameswuffs_gif__decoder__struct3617   num_decoded_frames() const {
3618     return wuffs_gif__decoder__num_decoded_frames(this);
3619   }
3620 
3621   inline wuffs_base__rect_ie_u32  //
frame_dirty_rectwuffs_gif__decoder__struct3622   frame_dirty_rect() const {
3623     return wuffs_gif__decoder__frame_dirty_rect(this);
3624   }
3625 
3626   inline wuffs_base__range_ii_u64  //
workbuf_lenwuffs_gif__decoder__struct3627   workbuf_len() const {
3628     return wuffs_gif__decoder__workbuf_len(this);
3629   }
3630 
3631   inline wuffs_base__status  //
restart_framewuffs_gif__decoder__struct3632   restart_frame(uint64_t a_index, uint64_t a_io_position) {
3633     return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
3634   }
3635 
3636   inline wuffs_base__status  //
decode_frame_configwuffs_gif__decoder__struct3637   decode_frame_config(wuffs_base__frame_config* a_dst,
3638                       wuffs_base__io_buffer* a_src) {
3639     return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
3640   }
3641 
3642   inline wuffs_base__status  //
decode_framewuffs_gif__decoder__struct3643   decode_frame(wuffs_base__pixel_buffer* a_dst,
3644                wuffs_base__io_buffer* a_src,
3645                wuffs_base__slice_u8 a_workbuf,
3646                wuffs_base__decode_frame_options* a_opts) {
3647     return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_workbuf,
3648                                             a_opts);
3649   }
3650 
3651 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3652   // Disallow copy and assign.
3653   wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
3654   wuffs_gif__decoder__struct& operator=(const wuffs_gif__decoder__struct&) =
3655       delete;
3656 #endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3657 
3658 #endif  // __cplusplus
3659 
3660 };  // struct wuffs_gif__decoder__struct
3661 
3662 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3663 
3664 #ifdef __cplusplus
3665 }  // extern "C"
3666 #endif
3667 
3668 #ifdef __cplusplus
3669 extern "C" {
3670 #endif
3671 
3672 // ---------------- Status Codes
3673 
3674 extern const char* wuffs_gzip__error__bad_checksum;
3675 extern const char* wuffs_gzip__error__bad_compression_method;
3676 extern const char* wuffs_gzip__error__bad_encoding_flags;
3677 extern const char* wuffs_gzip__error__bad_header;
3678 
3679 // ---------------- Public Consts
3680 
3681 #define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
3682 
3683 static const uint64_t                                    //
3684     wuffs_gzip__decoder_workbuf_len_max_incl_worst_case  //
3685         WUFFS_BASE__POTENTIALLY_UNUSED = 1;
3686 
3687 // ---------------- Struct Declarations
3688 
3689 typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
3690 
3691 // ---------------- Public Initializer Prototypes
3692 
3693 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
3694 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
3695 //
3696 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
3697 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
3698 
3699 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
3700 wuffs_gzip__decoder__initialize(wuffs_gzip__decoder* self,
3701                                 size_t sizeof_star_self,
3702                                 uint64_t wuffs_version,
3703                                 uint32_t initialize_flags);
3704 
3705 size_t  //
3706 sizeof__wuffs_gzip__decoder();
3707 
3708 // ---------------- Public Function Prototypes
3709 
3710 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
3711 wuffs_gzip__decoder__set_ignore_checksum(wuffs_gzip__decoder* self, bool a_ic);
3712 
3713 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
3714 wuffs_gzip__decoder__workbuf_len(const wuffs_gzip__decoder* self);
3715 
3716 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3717 wuffs_gzip__decoder__decode_io_writer(wuffs_gzip__decoder* self,
3718                                       wuffs_base__io_buffer* a_dst,
3719                                       wuffs_base__io_buffer* a_src,
3720                                       wuffs_base__slice_u8 a_workbuf);
3721 
3722 // ---------------- Struct Definitions
3723 
3724 // These structs' fields, and the sizeof them, are private implementation
3725 // details that aren't guaranteed to be stable across Wuffs versions.
3726 //
3727 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
3728 
3729 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3730 
3731 struct wuffs_gzip__decoder__struct {
3732 #ifdef WUFFS_IMPLEMENTATION
3733 
3734   // Do not access the private_impl's or private_data's fields directly. There
3735   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
3736   // the wuffs_foo__bar__baz functions.
3737   //
3738   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
3739   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
3740 
3741   struct {
3742     uint32_t magic;
3743     uint32_t active_coroutine;
3744 
3745     bool f_ignore_checksum;
3746 
3747     uint32_t p_decode_io_writer[1];
3748   } private_impl;
3749 
3750   struct {
3751     wuffs_crc32__ieee_hasher f_checksum;
3752     wuffs_deflate__decoder f_flate;
3753 
3754     struct {
3755       uint8_t v_flags;
3756       uint32_t v_checksum_got;
3757       uint32_t v_decoded_length_got;
3758       uint32_t v_checksum_want;
3759       uint64_t scratch;
3760     } s_decode_io_writer[1];
3761   } private_data;
3762 
3763 #else  // WUFFS_IMPLEMENTATION
3764 
3765   // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
3766   // large enough to discourage trying to allocate one on the stack. The sizeof
3767   // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
3768   // struct) is not part of the public, stable, memory-safe API. Call
3769   // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
3770   // first argument) instead of fiddling with bar.private_impl.qux fields.
3771   //
3772   // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
3773   // defines C++ convenience methods. These methods forward on "this", so that
3774   // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
3775  private:
3776   union {
3777     uint32_t align_as_per_magic_field;
3778     uint8_t placeholder[1073741824];  // 1 GiB.
3779   } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
3780 
3781  public:
3782 
3783 #endif  // WUFFS_IMPLEMENTATION
3784 
3785 #ifdef __cplusplus
3786 
3787   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
initializewuffs_gzip__decoder__struct3788   initialize(size_t sizeof_star_self,
3789              uint64_t wuffs_version,
3790              uint32_t initialize_flags) {
3791     return wuffs_gzip__decoder__initialize(this, sizeof_star_self,
3792                                            wuffs_version, initialize_flags);
3793   }
3794 
3795   inline wuffs_base__empty_struct  //
set_ignore_checksumwuffs_gzip__decoder__struct3796   set_ignore_checksum(bool a_ic) {
3797     return wuffs_gzip__decoder__set_ignore_checksum(this, a_ic);
3798   }
3799 
3800   inline wuffs_base__range_ii_u64  //
workbuf_lenwuffs_gzip__decoder__struct3801   workbuf_len() const {
3802     return wuffs_gzip__decoder__workbuf_len(this);
3803   }
3804 
3805   inline wuffs_base__status  //
decode_io_writerwuffs_gzip__decoder__struct3806   decode_io_writer(wuffs_base__io_buffer* a_dst,
3807                    wuffs_base__io_buffer* a_src,
3808                    wuffs_base__slice_u8 a_workbuf) {
3809     return wuffs_gzip__decoder__decode_io_writer(this, a_dst, a_src, a_workbuf);
3810   }
3811 
3812 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3813   // Disallow copy and assign.
3814   wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
3815   wuffs_gzip__decoder__struct& operator=(const wuffs_gzip__decoder__struct&) =
3816       delete;
3817 #endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3818 
3819 #endif  // __cplusplus
3820 
3821 };  // struct wuffs_gzip__decoder__struct
3822 
3823 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3824 
3825 #ifdef __cplusplus
3826 }  // extern "C"
3827 #endif
3828 
3829 #ifdef __cplusplus
3830 extern "C" {
3831 #endif
3832 
3833 // ---------------- Status Codes
3834 
3835 extern const char* wuffs_zlib__error__bad_checksum;
3836 extern const char* wuffs_zlib__error__bad_compression_method;
3837 extern const char* wuffs_zlib__error__bad_compression_window_size;
3838 extern const char* wuffs_zlib__error__bad_parity_check;
3839 
3840 // ---------------- Public Consts
3841 
3842 #define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
3843 
3844 static const uint64_t                                    //
3845     wuffs_zlib__decoder_workbuf_len_max_incl_worst_case  //
3846         WUFFS_BASE__POTENTIALLY_UNUSED = 1;
3847 
3848 // ---------------- Struct Declarations
3849 
3850 typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
3851 
3852 // ---------------- Public Initializer Prototypes
3853 
3854 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
3855 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
3856 //
3857 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
3858 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
3859 
3860 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
3861 wuffs_zlib__decoder__initialize(wuffs_zlib__decoder* self,
3862                                 size_t sizeof_star_self,
3863                                 uint64_t wuffs_version,
3864                                 uint32_t initialize_flags);
3865 
3866 size_t  //
3867 sizeof__wuffs_zlib__decoder();
3868 
3869 // ---------------- Public Function Prototypes
3870 
3871 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
3872 wuffs_zlib__decoder__set_ignore_checksum(wuffs_zlib__decoder* self, bool a_ic);
3873 
3874 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
3875 wuffs_zlib__decoder__workbuf_len(const wuffs_zlib__decoder* self);
3876 
3877 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
3878 wuffs_zlib__decoder__decode_io_writer(wuffs_zlib__decoder* self,
3879                                       wuffs_base__io_buffer* a_dst,
3880                                       wuffs_base__io_buffer* a_src,
3881                                       wuffs_base__slice_u8 a_workbuf);
3882 
3883 // ---------------- Struct Definitions
3884 
3885 // These structs' fields, and the sizeof them, are private implementation
3886 // details that aren't guaranteed to be stable across Wuffs versions.
3887 //
3888 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
3889 
3890 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3891 
3892 struct wuffs_zlib__decoder__struct {
3893 #ifdef WUFFS_IMPLEMENTATION
3894 
3895   // Do not access the private_impl's or private_data's fields directly. There
3896   // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
3897   // the wuffs_foo__bar__baz functions.
3898   //
3899   // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
3900   // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
3901 
3902   struct {
3903     uint32_t magic;
3904     uint32_t active_coroutine;
3905 
3906     bool f_ignore_checksum;
3907 
3908     uint32_t p_decode_io_writer[1];
3909   } private_impl;
3910 
3911   struct {
3912     wuffs_adler32__hasher f_checksum;
3913     wuffs_deflate__decoder f_flate;
3914 
3915     struct {
3916       uint32_t v_checksum_got;
3917       uint64_t scratch;
3918     } s_decode_io_writer[1];
3919   } private_data;
3920 
3921 #else  // WUFFS_IMPLEMENTATION
3922 
3923   // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is
3924   // large enough to discourage trying to allocate one on the stack. The sizeof
3925   // the real private_impl (and the sizeof the real outermost wuffs_foo__bar
3926   // struct) is not part of the public, stable, memory-safe API. Call
3927   // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their
3928   // first argument) instead of fiddling with bar.private_impl.qux fields.
3929   //
3930   // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still
3931   // defines C++ convenience methods. These methods forward on "this", so that
3932   // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
3933  private:
3934   union {
3935     uint32_t align_as_per_magic_field;
3936     uint8_t placeholder[1073741824];  // 1 GiB.
3937   } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD;
3938 
3939  public:
3940 
3941 #endif  // WUFFS_IMPLEMENTATION
3942 
3943 #ifdef __cplusplus
3944 
3945   inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT  //
initializewuffs_zlib__decoder__struct3946   initialize(size_t sizeof_star_self,
3947              uint64_t wuffs_version,
3948              uint32_t initialize_flags) {
3949     return wuffs_zlib__decoder__initialize(this, sizeof_star_self,
3950                                            wuffs_version, initialize_flags);
3951   }
3952 
3953   inline wuffs_base__empty_struct  //
set_ignore_checksumwuffs_zlib__decoder__struct3954   set_ignore_checksum(bool a_ic) {
3955     return wuffs_zlib__decoder__set_ignore_checksum(this, a_ic);
3956   }
3957 
3958   inline wuffs_base__range_ii_u64  //
workbuf_lenwuffs_zlib__decoder__struct3959   workbuf_len() const {
3960     return wuffs_zlib__decoder__workbuf_len(this);
3961   }
3962 
3963   inline wuffs_base__status  //
decode_io_writerwuffs_zlib__decoder__struct3964   decode_io_writer(wuffs_base__io_buffer* a_dst,
3965                    wuffs_base__io_buffer* a_src,
3966                    wuffs_base__slice_u8 a_workbuf) {
3967     return wuffs_zlib__decoder__decode_io_writer(this, a_dst, a_src, a_workbuf);
3968   }
3969 
3970 #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3971   // Disallow copy and assign.
3972   wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
3973   wuffs_zlib__decoder__struct& operator=(const wuffs_zlib__decoder__struct&) =
3974       delete;
3975 #endif  // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
3976 
3977 #endif  // __cplusplus
3978 
3979 };  // struct wuffs_zlib__decoder__struct
3980 
3981 #endif  // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
3982 
3983 #ifdef __cplusplus
3984 }  // extern "C"
3985 #endif
3986 
3987 // WUFFS C HEADER ENDS HERE.
3988 #ifdef WUFFS_IMPLEMENTATION
3989 
3990 // GCC does not warn for unused *static inline* functions, but clang does.
3991 #ifdef __clang__
3992 #pragma clang diagnostic push
3993 #pragma clang diagnostic ignored "-Wunused-function"
3994 #endif
3995 
3996 #ifdef __cplusplus
3997 extern "C" {
3998 #endif
3999 
4000 static inline wuffs_base__empty_struct  //
wuffs_base__ignore_status(wuffs_base__status z)4001 wuffs_base__ignore_status(wuffs_base__status z) {
4002   return wuffs_base__make_empty_struct();
4003 }
4004 
4005 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
4006 // It's not foolproof, given C doesn't automatically zero memory before use,
4007 // but it should catch 99.99% of cases.
4008 //
4009 // Its (non-zero) value is arbitrary, based on md5sum("wuffs").
4010 #define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
4011 
4012 // WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
4013 // error was previously encountered.
4014 //
4015 // Its (non-zero) value is arbitrary, based on md5sum("disabled").
4016 #define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
4017 
4018 // Denote intentional fallthroughs for -Wimplicit-fallthrough.
4019 //
4020 // The order matters here. Clang also defines "__GNUC__".
4021 #if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)
4022 #define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]
4023 #elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)
4024 #define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))
4025 #else
4026 #define WUFFS_BASE__FALLTHROUGH
4027 #endif
4028 
4029 // Use switch cases for coroutine suspension points, similar to the technique
4030 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
4031 //
4032 // We use trivial macros instead of an explicit assignment and case statement
4033 // so that clang-format doesn't get confused by the unusual "case"s.
4034 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
4035 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
4036   coro_susp_point = n;                            \
4037   WUFFS_BASE__FALLTHROUGH;                        \
4038   case n:;
4039 
4040 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
4041   if (!status) {                                                \
4042     goto ok;                                                    \
4043   } else if (*status != '$') {                                  \
4044     goto exit;                                                  \
4045   }                                                             \
4046   coro_susp_point = n;                                          \
4047   goto suspend;                                                 \
4048   case n:;
4049 
4050 // Clang also defines "__GNUC__".
4051 #if defined(__GNUC__)
4052 #define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
4053 #define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
4054 #else
4055 #define WUFFS_BASE__LIKELY(expr) (expr)
4056 #define WUFFS_BASE__UNLIKELY(expr) (expr)
4057 #endif
4058 
4059 // The helpers below are functions, instead of macros, because their arguments
4060 // can be an expression that we shouldn't evaluate more than once.
4061 //
4062 // They are static, so that linking multiple wuffs .o files won't complain about
4063 // duplicate function definitions.
4064 //
4065 // They are explicitly marked inline, even if modern compilers don't use the
4066 // inline attribute to guide optimizations such as inlining, to avoid the
4067 // -Wunused-function warning, and we like to compile with -Wall -Werror.
4068 
4069 // ---------------- Numeric Types
4070 
4071 static inline uint8_t  //
wuffs_base__load_u8be(uint8_t * p)4072 wuffs_base__load_u8be(uint8_t* p) {
4073   return p[0];
4074 }
4075 
4076 static inline uint16_t  //
wuffs_base__load_u16be(uint8_t * p)4077 wuffs_base__load_u16be(uint8_t* p) {
4078   return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
4079 }
4080 
4081 static inline uint16_t  //
wuffs_base__load_u16le(uint8_t * p)4082 wuffs_base__load_u16le(uint8_t* p) {
4083   return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
4084 }
4085 
4086 static inline uint32_t  //
wuffs_base__load_u24be(uint8_t * p)4087 wuffs_base__load_u24be(uint8_t* p) {
4088   return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
4089          ((uint32_t)(p[2]) << 0);
4090 }
4091 
4092 static inline uint32_t  //
wuffs_base__load_u24le(uint8_t * p)4093 wuffs_base__load_u24le(uint8_t* p) {
4094   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
4095          ((uint32_t)(p[2]) << 16);
4096 }
4097 
4098 static inline uint32_t  //
wuffs_base__load_u32be(uint8_t * p)4099 wuffs_base__load_u32be(uint8_t* p) {
4100   return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
4101          ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
4102 }
4103 
4104 static inline uint32_t  //
wuffs_base__load_u32le(uint8_t * p)4105 wuffs_base__load_u32le(uint8_t* p) {
4106   return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
4107          ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
4108 }
4109 
4110 static inline uint64_t  //
wuffs_base__load_u40be(uint8_t * p)4111 wuffs_base__load_u40be(uint8_t* p) {
4112   return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
4113          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
4114          ((uint64_t)(p[4]) << 0);
4115 }
4116 
4117 static inline uint64_t  //
wuffs_base__load_u40le(uint8_t * p)4118 wuffs_base__load_u40le(uint8_t* p) {
4119   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
4120          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
4121          ((uint64_t)(p[4]) << 32);
4122 }
4123 
4124 static inline uint64_t  //
wuffs_base__load_u48be(uint8_t * p)4125 wuffs_base__load_u48be(uint8_t* p) {
4126   return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
4127          ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
4128          ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
4129 }
4130 
4131 static inline uint64_t  //
wuffs_base__load_u48le(uint8_t * p)4132 wuffs_base__load_u48le(uint8_t* p) {
4133   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
4134          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
4135          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
4136 }
4137 
4138 static inline uint64_t  //
wuffs_base__load_u56be(uint8_t * p)4139 wuffs_base__load_u56be(uint8_t* p) {
4140   return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
4141          ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
4142          ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
4143          ((uint64_t)(p[6]) << 0);
4144 }
4145 
4146 static inline uint64_t  //
wuffs_base__load_u56le(uint8_t * p)4147 wuffs_base__load_u56le(uint8_t* p) {
4148   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
4149          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
4150          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
4151          ((uint64_t)(p[6]) << 48);
4152 }
4153 
4154 static inline uint64_t  //
wuffs_base__load_u64be(uint8_t * p)4155 wuffs_base__load_u64be(uint8_t* p) {
4156   return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
4157          ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
4158          ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
4159          ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
4160 }
4161 
4162 static inline uint64_t  //
wuffs_base__load_u64le(uint8_t * p)4163 wuffs_base__load_u64le(uint8_t* p) {
4164   return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
4165          ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
4166          ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
4167          ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
4168 }
4169 
4170 // --------
4171 
4172 static inline void  //
wuffs_base__store_u8be(uint8_t * p,uint8_t x)4173 wuffs_base__store_u8be(uint8_t* p, uint8_t x) {
4174   p[0] = x;
4175 }
4176 
4177 static inline void  //
wuffs_base__store_u16be(uint8_t * p,uint16_t x)4178 wuffs_base__store_u16be(uint8_t* p, uint16_t x) {
4179   p[0] = (uint8_t)(x >> 8);
4180   p[1] = (uint8_t)(x >> 0);
4181 }
4182 
4183 static inline void  //
wuffs_base__store_u16le(uint8_t * p,uint16_t x)4184 wuffs_base__store_u16le(uint8_t* p, uint16_t x) {
4185   p[0] = (uint8_t)(x >> 0);
4186   p[1] = (uint8_t)(x >> 8);
4187 }
4188 
4189 static inline void  //
wuffs_base__store_u24be(uint8_t * p,uint32_t x)4190 wuffs_base__store_u24be(uint8_t* p, uint32_t x) {
4191   p[0] = (uint8_t)(x >> 16);
4192   p[1] = (uint8_t)(x >> 8);
4193   p[2] = (uint8_t)(x >> 0);
4194 }
4195 
4196 static inline void  //
wuffs_base__store_u24le(uint8_t * p,uint32_t x)4197 wuffs_base__store_u24le(uint8_t* p, uint32_t x) {
4198   p[0] = (uint8_t)(x >> 0);
4199   p[1] = (uint8_t)(x >> 8);
4200   p[2] = (uint8_t)(x >> 16);
4201 }
4202 
4203 static inline void  //
wuffs_base__store_u32be(uint8_t * p,uint32_t x)4204 wuffs_base__store_u32be(uint8_t* p, uint32_t x) {
4205   p[0] = (uint8_t)(x >> 24);
4206   p[1] = (uint8_t)(x >> 16);
4207   p[2] = (uint8_t)(x >> 8);
4208   p[3] = (uint8_t)(x >> 0);
4209 }
4210 
4211 static inline void  //
wuffs_base__store_u32le(uint8_t * p,uint32_t x)4212 wuffs_base__store_u32le(uint8_t* p, uint32_t x) {
4213   p[0] = (uint8_t)(x >> 0);
4214   p[1] = (uint8_t)(x >> 8);
4215   p[2] = (uint8_t)(x >> 16);
4216   p[3] = (uint8_t)(x >> 24);
4217 }
4218 
4219 static inline void  //
wuffs_base__store_u40be(uint8_t * p,uint64_t x)4220 wuffs_base__store_u40be(uint8_t* p, uint64_t x) {
4221   p[0] = (uint8_t)(x >> 32);
4222   p[1] = (uint8_t)(x >> 24);
4223   p[2] = (uint8_t)(x >> 16);
4224   p[3] = (uint8_t)(x >> 8);
4225   p[4] = (uint8_t)(x >> 0);
4226 }
4227 
4228 static inline void  //
wuffs_base__store_u40le(uint8_t * p,uint64_t x)4229 wuffs_base__store_u40le(uint8_t* p, uint64_t x) {
4230   p[0] = (uint8_t)(x >> 0);
4231   p[1] = (uint8_t)(x >> 8);
4232   p[2] = (uint8_t)(x >> 16);
4233   p[3] = (uint8_t)(x >> 24);
4234   p[4] = (uint8_t)(x >> 32);
4235 }
4236 
4237 static inline void  //
wuffs_base__store_u48be(uint8_t * p,uint64_t x)4238 wuffs_base__store_u48be(uint8_t* p, uint64_t x) {
4239   p[0] = (uint8_t)(x >> 40);
4240   p[1] = (uint8_t)(x >> 32);
4241   p[2] = (uint8_t)(x >> 24);
4242   p[3] = (uint8_t)(x >> 16);
4243   p[4] = (uint8_t)(x >> 8);
4244   p[5] = (uint8_t)(x >> 0);
4245 }
4246 
4247 static inline void  //
wuffs_base__store_u48le(uint8_t * p,uint64_t x)4248 wuffs_base__store_u48le(uint8_t* p, uint64_t x) {
4249   p[0] = (uint8_t)(x >> 0);
4250   p[1] = (uint8_t)(x >> 8);
4251   p[2] = (uint8_t)(x >> 16);
4252   p[3] = (uint8_t)(x >> 24);
4253   p[4] = (uint8_t)(x >> 32);
4254   p[5] = (uint8_t)(x >> 40);
4255 }
4256 
4257 static inline void  //
wuffs_base__store_u56be(uint8_t * p,uint64_t x)4258 wuffs_base__store_u56be(uint8_t* p, uint64_t x) {
4259   p[0] = (uint8_t)(x >> 48);
4260   p[1] = (uint8_t)(x >> 40);
4261   p[2] = (uint8_t)(x >> 32);
4262   p[3] = (uint8_t)(x >> 24);
4263   p[4] = (uint8_t)(x >> 16);
4264   p[5] = (uint8_t)(x >> 8);
4265   p[6] = (uint8_t)(x >> 0);
4266 }
4267 
4268 static inline void  //
wuffs_base__store_u56le(uint8_t * p,uint64_t x)4269 wuffs_base__store_u56le(uint8_t* p, uint64_t x) {
4270   p[0] = (uint8_t)(x >> 0);
4271   p[1] = (uint8_t)(x >> 8);
4272   p[2] = (uint8_t)(x >> 16);
4273   p[3] = (uint8_t)(x >> 24);
4274   p[4] = (uint8_t)(x >> 32);
4275   p[5] = (uint8_t)(x >> 40);
4276   p[6] = (uint8_t)(x >> 48);
4277 }
4278 
4279 static inline void  //
wuffs_base__store_u64be(uint8_t * p,uint64_t x)4280 wuffs_base__store_u64be(uint8_t* p, uint64_t x) {
4281   p[0] = (uint8_t)(x >> 56);
4282   p[1] = (uint8_t)(x >> 48);
4283   p[2] = (uint8_t)(x >> 40);
4284   p[3] = (uint8_t)(x >> 32);
4285   p[4] = (uint8_t)(x >> 24);
4286   p[5] = (uint8_t)(x >> 16);
4287   p[6] = (uint8_t)(x >> 8);
4288   p[7] = (uint8_t)(x >> 0);
4289 }
4290 
4291 static inline void  //
wuffs_base__store_u64le(uint8_t * p,uint64_t x)4292 wuffs_base__store_u64le(uint8_t* p, uint64_t x) {
4293   p[0] = (uint8_t)(x >> 0);
4294   p[1] = (uint8_t)(x >> 8);
4295   p[2] = (uint8_t)(x >> 16);
4296   p[3] = (uint8_t)(x >> 24);
4297   p[4] = (uint8_t)(x >> 32);
4298   p[5] = (uint8_t)(x >> 40);
4299   p[6] = (uint8_t)(x >> 48);
4300   p[7] = (uint8_t)(x >> 56);
4301 }
4302 
4303 // --------
4304 
4305 extern const uint8_t wuffs_base__low_bits_mask__u8[9];
4306 extern const uint16_t wuffs_base__low_bits_mask__u16[17];
4307 extern const uint32_t wuffs_base__low_bits_mask__u32[33];
4308 extern const uint64_t wuffs_base__low_bits_mask__u64[65];
4309 
4310 #define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
4311 #define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
4312 #define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
4313 #define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
4314 
4315 // --------
4316 
4317 static inline void  //
wuffs_base__u8__sat_add_indirect(uint8_t * x,uint8_t y)4318 wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
4319   *x = wuffs_base__u8__sat_add(*x, y);
4320 }
4321 
4322 static inline void  //
wuffs_base__u8__sat_sub_indirect(uint8_t * x,uint8_t y)4323 wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
4324   *x = wuffs_base__u8__sat_sub(*x, y);
4325 }
4326 
4327 static inline void  //
wuffs_base__u16__sat_add_indirect(uint16_t * x,uint16_t y)4328 wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
4329   *x = wuffs_base__u16__sat_add(*x, y);
4330 }
4331 
4332 static inline void  //
wuffs_base__u16__sat_sub_indirect(uint16_t * x,uint16_t y)4333 wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
4334   *x = wuffs_base__u16__sat_sub(*x, y);
4335 }
4336 
4337 static inline void  //
wuffs_base__u32__sat_add_indirect(uint32_t * x,uint32_t y)4338 wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
4339   *x = wuffs_base__u32__sat_add(*x, y);
4340 }
4341 
4342 static inline void  //
wuffs_base__u32__sat_sub_indirect(uint32_t * x,uint32_t y)4343 wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
4344   *x = wuffs_base__u32__sat_sub(*x, y);
4345 }
4346 
4347 static inline void  //
wuffs_base__u64__sat_add_indirect(uint64_t * x,uint64_t y)4348 wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
4349   *x = wuffs_base__u64__sat_add(*x, y);
4350 }
4351 
4352 static inline void  //
wuffs_base__u64__sat_sub_indirect(uint64_t * x,uint64_t y)4353 wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
4354   *x = wuffs_base__u64__sat_sub(*x, y);
4355 }
4356 
4357 // ---------------- Slices and Tables
4358 
4359 // wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
4360 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s,uint64_t up_to)4361 wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
4362   if ((uint64_t)(s.len) > up_to) {
4363     s.len = up_to;
4364   }
4365   return s;
4366 }
4367 
4368 // wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
4369 static inline wuffs_base__slice_u8  //
wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s,uint64_t up_to)4370 wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
4371   if ((uint64_t)(s.len) > up_to) {
4372     s.ptr += (uint64_t)(s.len) - up_to;
4373     s.len = up_to;
4374   }
4375   return s;
4376 }
4377 
4378 // wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
4379 // where len is the minimum of dst.len and src.len.
4380 //
4381 // Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
4382 // slice) is valid and results in a no-op.
4383 static inline uint64_t  //
wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src)4384 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
4385                                       wuffs_base__slice_u8 src) {
4386   size_t len = dst.len < src.len ? dst.len : src.len;
4387   if (len > 0) {
4388     memmove(dst.ptr, src.ptr, len);
4389   }
4390   return len;
4391 }
4392 
4393 // --------
4394 
4395 static inline wuffs_base__slice_u8  //
wuffs_base__table_u8__row(wuffs_base__table_u8 t,uint32_t y)4396 wuffs_base__table_u8__row(wuffs_base__table_u8 t, uint32_t y) {
4397   if (y < t.height) {
4398     return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
4399   }
4400   return wuffs_base__make_slice_u8(NULL, 0);
4401 }
4402 
4403   // ---------------- Slices and Tables (Utility)
4404 
4405 #define wuffs_base__utility__null_slice_u8 wuffs_base__null_slice_u8
4406 
4407 // ---------------- Ranges and Rects
4408 
4409 static inline uint32_t  //
wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32 * r)4410 wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) {
4411   return r->min_incl;
4412 }
4413 
4414 static inline uint32_t  //
wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32 * r)4415 wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) {
4416   return r->max_incl;
4417 }
4418 
4419 static inline uint32_t  //
wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32 * r)4420 wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) {
4421   return r->min_incl;
4422 }
4423 
4424 static inline uint32_t  //
wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32 * r)4425 wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) {
4426   return r->max_excl;
4427 }
4428 
4429 static inline uint64_t  //
wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64 * r)4430 wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) {
4431   return r->min_incl;
4432 }
4433 
4434 static inline uint64_t  //
wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64 * r)4435 wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) {
4436   return r->max_incl;
4437 }
4438 
4439 static inline uint64_t  //
wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64 * r)4440 wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) {
4441   return r->min_incl;
4442 }
4443 
4444 static inline uint64_t  //
wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64 * r)4445 wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) {
4446   return r->max_excl;
4447 }
4448 
4449   // ---------------- Ranges and Rects (Utility)
4450 
4451 #define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
4452 #define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
4453 #define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
4454 #define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
4455 #define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
4456 #define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
4457 
4458 // ---------------- I/O
4459 
4460 // "Null" as in "/dev/null", not as in "nullptr".
4461 //
4462 // TODO: ensure that this is zero-initialized.
4463 static wuffs_base__io_buffer wuffs_base__global__null_io_buffer;
4464 
4465 static inline wuffs_base__io_buffer*  //
wuffs_base__null_io_reader()4466 wuffs_base__null_io_reader() {
4467   return &wuffs_base__global__null_io_buffer;
4468 }
4469 
4470 static inline wuffs_base__io_buffer*  //
wuffs_base__null_io_writer()4471 wuffs_base__null_io_writer() {
4472   return &wuffs_base__global__null_io_buffer;
4473 }
4474 
4475 static inline uint64_t  //
wuffs_base__io__count_since(uint64_t mark,uint64_t index)4476 wuffs_base__io__count_since(uint64_t mark, uint64_t index) {
4477   if (index >= mark) {
4478     return index - mark;
4479   }
4480   return 0;
4481 }
4482 
4483 static inline wuffs_base__slice_u8  //
wuffs_base__io__since(uint64_t mark,uint64_t index,uint8_t * ptr)4484 wuffs_base__io__since(uint64_t mark, uint64_t index, uint8_t* ptr) {
4485   if (index >= mark) {
4486     return wuffs_base__make_slice_u8(ptr + mark, index - mark);
4487   }
4488   return wuffs_base__make_slice_u8(NULL, 0);
4489 }
4490 
4491 static inline uint32_t  //
wuffs_base__io_writer__copy_n_from_history(uint8_t ** ptr_iop_w,uint8_t * io1_w,uint8_t * io2_w,uint32_t length,uint32_t distance)4492 wuffs_base__io_writer__copy_n_from_history(uint8_t** ptr_iop_w,
4493                                            uint8_t* io1_w,
4494                                            uint8_t* io2_w,
4495                                            uint32_t length,
4496                                            uint32_t distance) {
4497   if (!distance) {
4498     return 0;
4499   }
4500   uint8_t* p = *ptr_iop_w;
4501   if ((size_t)(p - io1_w) < (size_t)(distance)) {
4502     return 0;
4503   }
4504   uint8_t* q = p - distance;
4505   size_t n = (size_t)(io2_w - p);
4506   if ((size_t)(length) > n) {
4507     length = (uint32_t)(n);
4508   } else {
4509     n = (size_t)(length);
4510   }
4511   // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
4512   // is mostly because 3 is the minimum length for the deflate format. This
4513   // function implementation shouldn't overfit to that one format. Perhaps the
4514   // copy_n_from_history Wuffs method should also take an unroll hint argument,
4515   // and the cgen can look if that argument is the constant expression '3'.
4516   //
4517   // See also wuffs_base__io_writer__copy_n_from_history_fast below.
4518   //
4519   // Alternatively, or additionally, have a sloppy_copy_n_from_history method
4520   // that copies 8 bytes at a time, possibly writing more than length bytes?
4521   for (; n >= 3; n -= 3) {
4522     *p++ = *q++;
4523     *p++ = *q++;
4524     *p++ = *q++;
4525   }
4526   for (; n; n--) {
4527     *p++ = *q++;
4528   }
4529   *ptr_iop_w = p;
4530   return length;
4531 }
4532 
4533 // wuffs_base__io_writer__copy_n_from_history_fast is like the
4534 // wuffs_base__io_writer__copy_n_from_history function above, but has stronger
4535 // pre-conditions. The caller needs to prove that:
4536 //  - distance >  0
4537 //  - distance <= (*ptr_iop_w - io1_w)
4538 //  - length   <= (io2_w      - *ptr_iop_w)
4539 static inline uint32_t  //
wuffs_base__io_writer__copy_n_from_history_fast(uint8_t ** ptr_iop_w,uint8_t * io1_w,uint8_t * io2_w,uint32_t length,uint32_t distance)4540 wuffs_base__io_writer__copy_n_from_history_fast(uint8_t** ptr_iop_w,
4541                                                 uint8_t* io1_w,
4542                                                 uint8_t* io2_w,
4543                                                 uint32_t length,
4544                                                 uint32_t distance) {
4545   uint8_t* p = *ptr_iop_w;
4546   uint8_t* q = p - distance;
4547   uint32_t n = length;
4548   for (; n >= 3; n -= 3) {
4549     *p++ = *q++;
4550     *p++ = *q++;
4551     *p++ = *q++;
4552   }
4553   for (; n; n--) {
4554     *p++ = *q++;
4555   }
4556   *ptr_iop_w = p;
4557   return length;
4558 }
4559 
4560 static inline uint32_t  //
wuffs_base__io_writer__copy_n_from_reader(uint8_t ** ptr_iop_w,uint8_t * io2_w,uint32_t length,uint8_t ** ptr_iop_r,uint8_t * io2_r)4561 wuffs_base__io_writer__copy_n_from_reader(uint8_t** ptr_iop_w,
4562                                           uint8_t* io2_w,
4563                                           uint32_t length,
4564                                           uint8_t** ptr_iop_r,
4565                                           uint8_t* io2_r) {
4566   uint8_t* iop_w = *ptr_iop_w;
4567   size_t n = length;
4568   if (n > ((size_t)(io2_w - iop_w))) {
4569     n = (size_t)(io2_w - iop_w);
4570   }
4571   uint8_t* iop_r = *ptr_iop_r;
4572   if (n > ((size_t)(io2_r - iop_r))) {
4573     n = (size_t)(io2_r - iop_r);
4574   }
4575   if (n > 0) {
4576     memmove(iop_w, iop_r, n);
4577     *ptr_iop_w += n;
4578     *ptr_iop_r += n;
4579   }
4580   return (uint32_t)(n);
4581 }
4582 
4583 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)4584 wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
4585                                        uint8_t* io2_w,
4586                                        wuffs_base__slice_u8 src) {
4587   uint8_t* iop_w = *ptr_iop_w;
4588   size_t n = src.len;
4589   if (n > ((size_t)(io2_w - iop_w))) {
4590     n = (size_t)(io2_w - iop_w);
4591   }
4592   if (n > 0) {
4593     memmove(iop_w, src.ptr, n);
4594     *ptr_iop_w += n;
4595   }
4596   return (uint64_t)(n);
4597 }
4598 
4599 static inline uint32_t  //
wuffs_base__io_writer__copy_n_from_slice(uint8_t ** ptr_iop_w,uint8_t * io2_w,uint32_t length,wuffs_base__slice_u8 src)4600 wuffs_base__io_writer__copy_n_from_slice(uint8_t** ptr_iop_w,
4601                                          uint8_t* io2_w,
4602                                          uint32_t length,
4603                                          wuffs_base__slice_u8 src) {
4604   uint8_t* iop_w = *ptr_iop_w;
4605   size_t n = src.len;
4606   if (n > length) {
4607     n = length;
4608   }
4609   if (n > ((size_t)(io2_w - iop_w))) {
4610     n = (size_t)(io2_w - iop_w);
4611   }
4612   if (n > 0) {
4613     memmove(iop_w, src.ptr, n);
4614     *ptr_iop_w += n;
4615   }
4616   return (uint32_t)(n);
4617 }
4618 
4619 static inline wuffs_base__io_buffer*  //
wuffs_base__io_reader__set(wuffs_base__io_buffer * b,uint8_t ** ptr_iop_r,uint8_t ** ptr_io0_r,uint8_t ** ptr_io1_r,uint8_t ** ptr_io2_r,wuffs_base__slice_u8 data)4620 wuffs_base__io_reader__set(wuffs_base__io_buffer* b,
4621                            uint8_t** ptr_iop_r,
4622                            uint8_t** ptr_io0_r,
4623                            uint8_t** ptr_io1_r,
4624                            uint8_t** ptr_io2_r,
4625                            wuffs_base__slice_u8 data) {
4626   b->data = data;
4627   b->meta.wi = data.len;
4628   b->meta.ri = 0;
4629   b->meta.pos = 0;
4630   b->meta.closed = false;
4631 
4632   *ptr_iop_r = data.ptr;
4633   *ptr_io0_r = data.ptr;
4634   *ptr_io1_r = data.ptr;
4635   *ptr_io2_r = data.ptr + data.len;
4636 
4637   return b;
4638 }
4639 
4640 static inline wuffs_base__slice_u8  //
wuffs_base__io_reader__take(uint8_t ** ptr_iop_r,uint8_t * io2_r,uint64_t n)4641 wuffs_base__io_reader__take(uint8_t** ptr_iop_r, uint8_t* io2_r, uint64_t n) {
4642   if (n <= ((size_t)(io2_r - *ptr_iop_r))) {
4643     uint8_t* p = *ptr_iop_r;
4644     *ptr_iop_r += n;
4645     return wuffs_base__make_slice_u8(p, n);
4646   }
4647   return wuffs_base__make_slice_u8(NULL, 0);
4648 }
4649 
4650 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)4651 wuffs_base__io_writer__set(wuffs_base__io_buffer* b,
4652                            uint8_t** ptr_iop_w,
4653                            uint8_t** ptr_io0_w,
4654                            uint8_t** ptr_io1_w,
4655                            uint8_t** ptr_io2_w,
4656                            wuffs_base__slice_u8 data) {
4657   b->data = data;
4658   b->meta.wi = 0;
4659   b->meta.ri = 0;
4660   b->meta.pos = 0;
4661   b->meta.closed = false;
4662 
4663   *ptr_iop_w = data.ptr;
4664   *ptr_io0_w = data.ptr;
4665   *ptr_io1_w = data.ptr;
4666   *ptr_io2_w = data.ptr + data.len;
4667 
4668   return b;
4669 }
4670 
4671   // ---------------- I/O (Utility)
4672 
4673 #define wuffs_base__utility__null_io_reader wuffs_base__null_io_reader
4674 #define wuffs_base__utility__null_io_writer wuffs_base__null_io_writer
4675 
4676   // ---------------- Memory Allocation
4677 
4678   // ---------------- Images
4679 
4680 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE)
4681 
4682 const uint8_t wuffs_base__low_bits_mask__u8[9] = {
4683     0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF,
4684 };
4685 
4686 const uint16_t wuffs_base__low_bits_mask__u16[17] = {
4687     0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
4688     0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
4689 };
4690 
4691 const uint32_t wuffs_base__low_bits_mask__u32[33] = {
4692     0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
4693     0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
4694     0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
4695     0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
4696     0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
4697     0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
4698 };
4699 
4700 const uint64_t wuffs_base__low_bits_mask__u64[65] = {
4701     0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
4702     0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
4703     0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
4704     0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
4705     0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
4706     0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
4707     0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
4708     0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
4709     0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
4710     0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
4711     0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
4712     0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
4713     0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
4714     0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
4715     0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
4716     0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
4717     0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
4718     0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
4719     0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
4720     0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
4721     0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
4722     0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
4723 };
4724 
4725 const char* wuffs_base__warning__end_of_data = "@base: end of data";
4726 const char* wuffs_base__warning__metadata_reported = "@base: metadata reported";
4727 const char* wuffs_base__suspension__short_read = "$base: short read";
4728 const char* wuffs_base__suspension__short_write = "$base: short write";
4729 const char* wuffs_base__error__bad_i_o_position = "#base: bad I/O position";
4730 const char* wuffs_base__error__bad_argument_length_too_short =
4731     "#base: bad argument (length too short)";
4732 const char* wuffs_base__error__bad_argument = "#base: bad argument";
4733 const char* wuffs_base__error__bad_call_sequence = "#base: bad call sequence";
4734 const char* wuffs_base__error__bad_receiver = "#base: bad receiver";
4735 const char* wuffs_base__error__bad_restart = "#base: bad restart";
4736 const char* wuffs_base__error__bad_sizeof_receiver =
4737     "#base: bad sizeof receiver";
4738 const char* wuffs_base__error__bad_workbuf_length = "#base: bad workbuf length";
4739 const char* wuffs_base__error__bad_wuffs_version = "#base: bad wuffs version";
4740 const char* wuffs_base__error__cannot_return_a_suspension =
4741     "#base: cannot return a suspension";
4742 const char* wuffs_base__error__disabled_by_previous_error =
4743     "#base: disabled by previous error";
4744 const char* wuffs_base__error__initialize_falsely_claimed_already_zeroed =
4745     "#base: initialize falsely claimed already zeroed";
4746 const char* wuffs_base__error__initialize_not_called =
4747     "#base: initialize not called";
4748 const char* wuffs_base__error__interleaved_coroutine_calls =
4749     "#base: interleaved coroutine calls";
4750 const char* wuffs_base__error__not_enough_data = "#base: not enough data";
4751 const char* wuffs_base__error__unsupported_option = "#base: unsupported option";
4752 const char* wuffs_base__error__too_much_data = "#base: too much data";
4753 
4754 // ---------------- Images
4755 
4756 const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
4757     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
4758     0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
4759 };
4760 
4761 static uint64_t  //
wuffs_base__pixel_swizzler__copy_1_1(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)4762 wuffs_base__pixel_swizzler__copy_1_1(wuffs_base__slice_u8 dst,
4763                                      wuffs_base__slice_u8 dst_palette,
4764                                      wuffs_base__slice_u8 src) {
4765   return wuffs_base__slice_u8__copy_from_slice(dst, src);
4766 }
4767 
4768 static uint64_t  //
wuffs_base__pixel_swizzler__copy_3_1(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)4769 wuffs_base__pixel_swizzler__copy_3_1(wuffs_base__slice_u8 dst,
4770                                      wuffs_base__slice_u8 dst_palette,
4771                                      wuffs_base__slice_u8 src) {
4772   if (dst_palette.len != 1024) {
4773     return 0;
4774   }
4775   size_t dst_len3 = dst.len / 3;
4776   size_t len = dst_len3 < src.len ? dst_len3 : src.len;
4777   uint8_t* d = dst.ptr;
4778   uint8_t* s = src.ptr;
4779   size_t n = len;
4780 
4781   // N is the loop unroll count.
4782   const int N = 4;
4783 
4784   // The comparison in the while condition is ">", not ">=", because with ">=",
4785   // the last 4-byte store could write past the end of the dst slice.
4786   //
4787   // Each 4-byte store writes one too many bytes, but a subsequent store will
4788   // overwrite that with the correct byte. There is always another store,
4789   // whether a 4-byte store in this loop or a 1-byte store in the next loop.
4790   while (n > N) {
4791     wuffs_base__store_u32le(
4792         d + (0 * 3),
4793         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));
4794     wuffs_base__store_u32le(
4795         d + (1 * 3),
4796         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));
4797     wuffs_base__store_u32le(
4798         d + (2 * 3),
4799         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));
4800     wuffs_base__store_u32le(
4801         d + (3 * 3),
4802         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));
4803 
4804     s += 1 * N;
4805     d += 3 * N;
4806     n -= (size_t)(1 * N);
4807   }
4808 
4809   while (n >= 1) {
4810     uint32_t color =
4811         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4));
4812     d[0] = (uint8_t)(color >> 0);
4813     d[1] = (uint8_t)(color >> 8);
4814     d[2] = (uint8_t)(color >> 16);
4815 
4816     s += 1 * 1;
4817     d += 3 * 1;
4818     n -= (size_t)(1 * 1);
4819   }
4820 
4821   return len;
4822 }
4823 static uint64_t  //
wuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)4824 wuffs_base__pixel_swizzler__copy_4_1(wuffs_base__slice_u8 dst,
4825                                      wuffs_base__slice_u8 dst_palette,
4826                                      wuffs_base__slice_u8 src) {
4827   if (dst_palette.len != 1024) {
4828     return 0;
4829   }
4830   size_t dst_len4 = dst.len / 4;
4831   size_t len = dst_len4 < src.len ? dst_len4 : src.len;
4832   uint8_t* d = dst.ptr;
4833   uint8_t* s = src.ptr;
4834   size_t n = len;
4835 
4836   // N is the loop unroll count.
4837   const int N = 4;
4838 
4839   while (n >= N) {
4840     wuffs_base__store_u32le(
4841         d + (0 * 4),
4842         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));
4843     wuffs_base__store_u32le(
4844         d + (1 * 4),
4845         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[1]) * 4)));
4846     wuffs_base__store_u32le(
4847         d + (2 * 4),
4848         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[2]) * 4)));
4849     wuffs_base__store_u32le(
4850         d + (3 * 4),
4851         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[3]) * 4)));
4852 
4853     s += 1 * N;
4854     d += 4 * N;
4855     n -= (size_t)(1 * N);
4856   }
4857 
4858   while (n >= 1) {
4859     wuffs_base__store_u32le(
4860         d + (0 * 4),
4861         wuffs_base__load_u32le(dst_palette.ptr + ((uint32_t)(s[0]) * 4)));
4862 
4863     s += 1 * 1;
4864     d += 4 * 1;
4865     n -= (size_t)(1 * 1);
4866   }
4867 
4868   return len;
4869 }
4870 
4871 static uint64_t  //
wuffs_base__pixel_swizzler__swap_rgbx_bgrx(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src)4872 wuffs_base__pixel_swizzler__swap_rgbx_bgrx(wuffs_base__slice_u8 dst,
4873                                            wuffs_base__slice_u8 src) {
4874   size_t len4 = (dst.len < src.len ? dst.len : src.len) / 4;
4875   uint8_t* d = dst.ptr;
4876   uint8_t* s = src.ptr;
4877 
4878   size_t n = len4;
4879   while (n--) {
4880     uint8_t b0 = s[0];
4881     uint8_t b1 = s[1];
4882     uint8_t b2 = s[2];
4883     uint8_t b3 = s[3];
4884     d[0] = b2;
4885     d[1] = b1;
4886     d[2] = b0;
4887     d[3] = b3;
4888     s += 4;
4889     d += 4;
4890   }
4891   return len4 * 4;
4892 }
4893 
4894 wuffs_base__status  //
wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_format,wuffs_base__slice_u8 dst_palette,wuffs_base__pixel_format src_format,wuffs_base__slice_u8 src_palette)4895 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
4896                                     wuffs_base__pixel_format dst_format,
4897                                     wuffs_base__slice_u8 dst_palette,
4898                                     wuffs_base__pixel_format src_format,
4899                                     wuffs_base__slice_u8 src_palette) {
4900   if (!p) {
4901     return wuffs_base__error__bad_receiver;
4902   }
4903 
4904   // TODO: support many more formats.
4905 
4906   uint64_t (*func)(wuffs_base__slice_u8 dst, wuffs_base__slice_u8 dst_palette,
4907                    wuffs_base__slice_u8 src) = NULL;
4908 
4909   switch (src_format) {
4910     case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
4911       switch (dst_format) {
4912         case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
4913         case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
4914         case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
4915           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
4916               1024) {
4917             break;
4918           }
4919           func = wuffs_base__pixel_swizzler__copy_1_1;
4920           break;
4921         case WUFFS_BASE__PIXEL_FORMAT__BGR:
4922           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
4923               1024) {
4924             break;
4925           }
4926           func = wuffs_base__pixel_swizzler__copy_3_1;
4927           break;
4928         case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
4929         case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
4930         case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
4931           if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
4932               1024) {
4933             break;
4934           }
4935           func = wuffs_base__pixel_swizzler__copy_4_1;
4936           break;
4937         case WUFFS_BASE__PIXEL_FORMAT__RGB:
4938           if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,
4939                                                          src_palette) != 1024) {
4940             break;
4941           }
4942           func = wuffs_base__pixel_swizzler__copy_3_1;
4943           break;
4944         case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
4945         case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
4946         case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
4947           if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,
4948                                                          src_palette) != 1024) {
4949             break;
4950           }
4951           func = wuffs_base__pixel_swizzler__copy_4_1;
4952           break;
4953         default:
4954           break;
4955       }
4956       break;
4957 
4958     default:
4959       break;
4960   }
4961 
4962   p->private_impl.func = func;
4963   return func ? NULL : wuffs_base__error__unsupported_option;
4964 }
4965 
4966 uint64_t  //
wuffs_base__pixel_swizzler__swizzle_interleaved(const wuffs_base__pixel_swizzler * p,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)4967 wuffs_base__pixel_swizzler__swizzle_interleaved(
4968     const wuffs_base__pixel_swizzler* p,
4969     wuffs_base__slice_u8 dst,
4970     wuffs_base__slice_u8 dst_palette,
4971     wuffs_base__slice_u8 src) {
4972   if (p && p->private_impl.func) {
4973     return (*(p->private_impl.func))(dst, dst_palette, src);
4974   }
4975   return 0;
4976 }
4977 
4978 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
4979         // defined(WUFFS_CONFIG__MODULE__BASE)
4980 
4981 #ifdef __cplusplus
4982 }  // extern "C"
4983 #endif
4984 
4985 #ifdef __clang__
4986 #pragma clang diagnostic pop
4987 #endif
4988 
4989 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
4990 
4991 // ---------------- Status Codes Implementations
4992 
4993 // ---------------- Private Consts
4994 
4995 // ---------------- Private Initializer Prototypes
4996 
4997 // ---------------- Private Function Prototypes
4998 
4999 // ---------------- Initializer Implementations
5000 
5001 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 initialize_flags)5002 wuffs_adler32__hasher__initialize(wuffs_adler32__hasher* self,
5003                                   size_t sizeof_star_self,
5004                                   uint64_t wuffs_version,
5005                                   uint32_t initialize_flags) {
5006   if (!self) {
5007     return wuffs_base__error__bad_receiver;
5008   }
5009   if (sizeof(*self) != sizeof_star_self) {
5010     return wuffs_base__error__bad_sizeof_receiver;
5011   }
5012   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
5013       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
5014     return wuffs_base__error__bad_wuffs_version;
5015   }
5016 
5017   if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
5018 // The whole point of this if-check is to detect an uninitialized *self.
5019 // We disable the warning on GCC. Clang-5.0 does not have this warning.
5020 #if !defined(__clang__) && defined(__GNUC__)
5021 #pragma GCC diagnostic push
5022 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
5023 #endif
5024     if (self->private_impl.magic != 0) {
5025       return wuffs_base__error__initialize_falsely_claimed_already_zeroed;
5026     }
5027 #if !defined(__clang__) && defined(__GNUC__)
5028 #pragma GCC diagnostic pop
5029 #endif
5030   } else {
5031     void* p = &(self->private_impl);
5032     size_t n = sizeof(self->private_impl);
5033     if ((initialize_flags &
5034          WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
5035       p = self;
5036       n = sizeof(*self);
5037       initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
5038     }
5039     memset(p, 0, n);
5040   }
5041 
5042   self->private_impl.magic = WUFFS_BASE__MAGIC;
5043   return NULL;
5044 }
5045 
5046 size_t  //
sizeof__wuffs_adler32__hasher()5047 sizeof__wuffs_adler32__hasher() {
5048   return sizeof(wuffs_adler32__hasher);
5049 }
5050 
5051 // ---------------- Function Implementations
5052 
5053 // -------- func adler32.hasher.update
5054 
5055 WUFFS_BASE__MAYBE_STATIC uint32_t  //
wuffs_adler32__hasher__update(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)5056 wuffs_adler32__hasher__update(wuffs_adler32__hasher* self,
5057                               wuffs_base__slice_u8 a_x) {
5058   if (!self) {
5059     return 0;
5060   }
5061   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
5062     return 0;
5063   }
5064 
5065   uint32_t v_s1 = 0;
5066   uint32_t v_s2 = 0;
5067   wuffs_base__slice_u8 v_remaining = {0};
5068   wuffs_base__slice_u8 v_p = {0};
5069 
5070   if (!self->private_impl.f_started) {
5071     self->private_impl.f_started = true;
5072     self->private_impl.f_state = 1;
5073   }
5074   v_s1 = ((self->private_impl.f_state) & 0xFFFF);
5075   v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
5076   while (((uint64_t)(a_x.len)) > 0) {
5077     v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
5078     if (((uint64_t)(a_x.len)) > 5552) {
5079       v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552);
5080       a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552);
5081     }
5082     {
5083       wuffs_base__slice_u8 i_slice_p = a_x;
5084       v_p = i_slice_p;
5085       v_p.len = 1;
5086       uint8_t* i_end0_p = i_slice_p.ptr + (i_slice_p.len / 8) * 8;
5087       while (v_p.ptr < i_end0_p) {
5088         v_s1 += ((uint32_t)(v_p.ptr[0]));
5089         v_s2 += v_s1;
5090         v_p.ptr += 1;
5091         v_s1 += ((uint32_t)(v_p.ptr[0]));
5092         v_s2 += v_s1;
5093         v_p.ptr += 1;
5094         v_s1 += ((uint32_t)(v_p.ptr[0]));
5095         v_s2 += v_s1;
5096         v_p.ptr += 1;
5097         v_s1 += ((uint32_t)(v_p.ptr[0]));
5098         v_s2 += v_s1;
5099         v_p.ptr += 1;
5100         v_s1 += ((uint32_t)(v_p.ptr[0]));
5101         v_s2 += v_s1;
5102         v_p.ptr += 1;
5103         v_s1 += ((uint32_t)(v_p.ptr[0]));
5104         v_s2 += v_s1;
5105         v_p.ptr += 1;
5106         v_s1 += ((uint32_t)(v_p.ptr[0]));
5107         v_s2 += v_s1;
5108         v_p.ptr += 1;
5109         v_s1 += ((uint32_t)(v_p.ptr[0]));
5110         v_s2 += v_s1;
5111         v_p.ptr += 1;
5112       }
5113       v_p.len = 1;
5114       uint8_t* i_end1_p = i_slice_p.ptr + (i_slice_p.len / 1) * 1;
5115       while (v_p.ptr < i_end1_p) {
5116         v_s1 += ((uint32_t)(v_p.ptr[0]));
5117         v_s2 += v_s1;
5118         v_p.ptr += 1;
5119       }
5120     }
5121     v_s1 %= 65521;
5122     v_s2 %= 65521;
5123     a_x = v_remaining;
5124   }
5125   self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
5126   return self->private_impl.f_state;
5127 }
5128 
5129 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
5130         // defined(WUFFS_CONFIG__MODULE__ADLER32)
5131 
5132 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
5133 
5134 // ---------------- Status Codes Implementations
5135 
5136 // ---------------- Private Consts
5137 
5138 static const uint32_t                 //
5139     wuffs_crc32__ieee_table[16][256]  //
5140     WUFFS_BASE__POTENTIALLY_UNUSED = {
5141         {
5142             0,          1996959894, 3993919788, 2567524794, 124634137,
5143             1886057615, 3915621685, 2657392035, 249268274,  2044508324,
5144             3772115230, 2547177864, 162941995,  2125561021, 3887607047,
5145             2428444049, 498536548,  1789927666, 4089016648, 2227061214,
5146             450548861,  1843258603, 4107580753, 2211677639, 325883990,
5147             1684777152, 4251122042, 2321926636, 335633487,  1661365465,
5148             4195302755, 2366115317, 997073096,  1281953886, 3579855332,
5149             2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
5150             901097722,  1119000684, 3686517206, 2898065728, 853044451,
5151             1172266101, 3705015759, 2882616665, 651767980,  1373503546,
5152             3369554304, 3218104598, 565507253,  1454621731, 3485111705,
5153             3099436303, 671266974,  1594198024, 3322730930, 2970347812,
5154             795835527,  1483230225, 3244367275, 3060149565, 1994146192,
5155             31158534,   2563907772, 4023717930, 1907459465, 112637215,
5156             2680153253, 3904427059, 2013776290, 251722036,  2517215374,
5157             3775830040, 2137656763, 141376813,  2439277719, 3865271297,
5158             1802195444, 476864866,  2238001368, 4066508878, 1812370925,
5159             453092731,  2181625025, 4111451223, 1706088902, 314042704,
5160             2344532202, 4240017532, 1658658271, 366619977,  2362670323,
5161             4224994405, 1303535960, 984961486,  2747007092, 3569037538,
5162             1256170817, 1037604311, 2765210733, 3554079995, 1131014506,
5163             879679996,  2909243462, 3663771856, 1141124467, 855842277,
5164             2852801631, 3708648649, 1342533948, 654459306,  3188396048,
5165             3373015174, 1466479909, 544179635,  3110523913, 3462522015,
5166             1591671054, 702138776,  2966460450, 3352799412, 1504918807,
5167             783551873,  3082640443, 3233442989, 3988292384, 2596254646,
5168             62317068,   1957810842, 3939845945, 2647816111, 81470997,
5169             1943803523, 3814918930, 2489596804, 225274430,  2053790376,
5170             3826175755, 2466906013, 167816743,  2097651377, 4027552580,
5171             2265490386, 503444072,  1762050814, 4150417245, 2154129355,
5172             426522225,  1852507879, 4275313526, 2312317920, 282753626,
5173             1742555852, 4189708143, 2394877945, 397917763,  1622183637,
5174             3604390888, 2714866558, 953729732,  1340076626, 3518719985,
5175             2797360999, 1068828381, 1219638859, 3624741850, 2936675148,
5176             906185462,  1090812512, 3747672003, 2825379669, 829329135,
5177             1181335161, 3412177804, 3160834842, 628085408,  1382605366,
5178             3423369109, 3138078467, 570562233,  1426400815, 3317316542,
5179             2998733608, 733239954,  1555261956, 3268935591, 3050360625,
5180             752459403,  1541320221, 2607071920, 3965973030, 1969922972,
5181             40735498,   2617837225, 3943577151, 1913087877, 83908371,
5182             2512341634, 3803740692, 2075208622, 213261112,  2463272603,
5183             3855990285, 2094854071, 198958881,  2262029012, 4057260610,
5184             1759359992, 534414190,  2176718541, 4139329115, 1873836001,
5185             414664567,  2282248934, 4279200368, 1711684554, 285281116,
5186             2405801727, 4167216745, 1634467795, 376229701,  2685067896,
5187             3608007406, 1308918612, 956543938,  2808555105, 3495958263,
5188             1231636301, 1047427035, 2932959818, 3654703836, 1088359270,
5189             936918000,  2847714899, 3736837829, 1202900863, 817233897,
5190             3183342108, 3401237130, 1404277552, 615818150,  3134207493,
5191             3453421203, 1423857449, 601450431,  3009837614, 3294710456,
5192             1567103746, 711928724,  3020668471, 3272380065, 1510334235,
5193             755167117,
5194         },
5195         {
5196             0,          421212481,  842424962,  724390851,  1684849924,
5197             2105013317, 1448781702, 1329698503, 3369699848, 3519200073,
5198             4210026634, 3824474571, 2897563404, 3048111693, 2659397006,
5199             2274893007, 1254232657, 1406739216, 2029285587, 1643069842,
5200             783210325,  934667796,  479770071,  92505238,   2182846553,
5201             2600511768, 2955803355, 2838940570, 3866582365, 4285295644,
5202             3561045983, 3445231262, 2508465314, 2359236067, 2813478432,
5203             3198777185, 4058571174, 3908292839, 3286139684, 3670389349,
5204             1566420650, 1145479147, 1869335592, 1987116393, 959540142,
5205             539646703,  185010476,  303839341,  3745920755, 3327985586,
5206             3983561841, 4100678960, 3140154359, 2721170102, 2300350837,
5207             2416418868, 396344571,  243568058,  631889529,  1018359608,
5208             1945336319, 1793607870, 1103436669, 1490954812, 4034481925,
5209             3915546180, 3259968903, 3679722694, 2484439553, 2366552896,
5210             2787371139, 3208174018, 950060301,  565965900,  177645455,
5211             328046286,  1556873225, 1171730760, 1861902987, 2011255754,
5212             3132841300, 2745199637, 2290958294, 2442530455, 3738671184,
5213             3352078609, 3974232786, 4126854035, 1919080284, 1803150877,
5214             1079293406, 1498383519, 370020952,  253043481,  607678682,
5215             1025720731, 1711106983, 2095471334, 1472923941, 1322268772,
5216             26324643,   411738082,  866634785,  717028704,  2904875439,
5217             3024081134, 2668790573, 2248782444, 3376948395, 3495106026,
5218             4219356713, 3798300520, 792689142,  908347575,  487136116,
5219             68299317,   1263779058, 1380486579, 2036719216, 1618931505,
5220             3890672638, 4278043327, 3587215740, 3435896893, 2206873338,
5221             2593195963, 2981909624, 2829542713, 998479947,  580430090,
5222             162921161,  279890824,  1609522511, 1190423566, 1842954189,
5223             1958874764, 4082766403, 3930137346, 3245109441, 3631694208,
5224             2536953671, 2385372678, 2768287173, 3155920004, 1900120602,
5225             1750776667, 1131931800, 1517083097, 355290910,  204897887,
5226             656092572,  1040194781, 3113746450, 2692952403, 2343461520,
5227             2461357009, 3723805974, 3304059991, 4022511508, 4141455061,
5228             2919742697, 3072101800, 2620513899, 2234183466, 3396041197,
5229             3547351212, 4166851439, 3779471918, 1725839073, 2143618976,
5230             1424512099, 1307796770, 45282277,   464110244,  813994343,
5231             698327078,  3838160568, 4259225593, 3606301754, 3488152955,
5232             2158586812, 2578602749, 2996767038, 2877569151, 740041904,
5233             889656817,  506086962,  120682355,  1215357364, 1366020341,
5234             2051441462, 1667084919, 3422213966, 3538019855, 4190942668,
5235             3772220557, 2945847882, 3062702859, 2644537544, 2226864521,
5236             52649286,   439905287,  823476164,  672009861,  1733269570,
5237             2119477507, 1434057408, 1281543041, 2167981343, 2552493150,
5238             3004082077, 2853541596, 3847487515, 4233048410, 3613549209,
5239             3464057816, 1239502615, 1358593622, 2077699477, 1657543892,
5240             764250643,  882293586,  532408465,  111204816,  1585378284,
5241             1197851309, 1816695150, 1968414767, 974272232,  587794345,
5242             136598634,  289367339,  2527558116, 2411481253, 2760973158,
5243             3179948583, 4073438432, 3956313505, 3237863010, 3655790371,
5244             347922877,  229101820,  646611775,  1066513022, 1892689081,
5245             1774917112, 1122387515, 1543337850, 3697634229, 3313392372,
5246             3998419255, 4148705398, 3087642289, 2702352368, 2319436851,
5247             2468674930,
5248         },
5249         {
5250             0,          29518391,   59036782,   38190681,   118073564,
5251             114017003,  76381362,   89069189,   236147128,  265370511,
5252             228034006,  206958561,  152762724,  148411219,  178138378,
5253             190596925,  472294256,  501532999,  530741022,  509615401,
5254             456068012,  451764635,  413917122,  426358261,  305525448,
5255             334993663,  296822438,  275991697,  356276756,  352202787,
5256             381193850,  393929805,  944588512,  965684439,  1003065998,
5257             973863097,  1061482044, 1049003019, 1019230802, 1023561829,
5258             912136024,  933002607,  903529270,  874031361,  827834244,
5259             815125939,  852716522,  856752605,  611050896,  631869351,
5260             669987326,  640506825,  593644876,  580921211,  551983394,
5261             556069653,  712553512,  733666847,  704405574,  675154545,
5262             762387700,  749958851,  787859610,  792175277,  1889177024,
5263             1901651959, 1931368878, 1927033753, 2006131996, 1985040171,
5264             1947726194, 1976933189, 2122964088, 2135668303, 2098006038,
5265             2093965857, 2038461604, 2017599123, 2047123658, 2076625661,
5266             1824272048, 1836991623, 1866005214, 1861914857, 1807058540,
5267             1786244187, 1748062722, 1777547317, 1655668488, 1668093247,
5268             1630251878, 1625932113, 1705433044, 1684323811, 1713505210,
5269             1742760333, 1222101792, 1226154263, 1263738702, 1251046777,
5270             1339974652, 1310460363, 1281013650, 1301863845, 1187289752,
5271             1191637167, 1161842422, 1149379777, 1103966788, 1074747507,
5272             1112139306, 1133218845, 1425107024, 1429406311, 1467333694,
5273             1454888457, 1408811148, 1379576507, 1350309090, 1371438805,
5274             1524775400, 1528845279, 1499917702, 1487177649, 1575719220,
5275             1546255107, 1584350554, 1605185389, 3778354048, 3774312887,
5276             3803303918, 3816007129, 3862737756, 3892238699, 3854067506,
5277             3833203973, 4012263992, 4007927823, 3970080342, 3982554209,
5278             3895452388, 3924658387, 3953866378, 3932773565, 4245928176,
5279             4241609415, 4271336606, 4283762345, 4196012076, 4225268251,
5280             4187931714, 4166823541, 4076923208, 4072833919, 4035198246,
5281             4047918865, 4094247316, 4123732899, 4153251322, 4132437965,
5282             3648544096, 3636082519, 3673983246, 3678331705, 3732010428,
5283             3753090955, 3723829714, 3694611429, 3614117080, 3601426159,
5284             3572488374, 3576541825, 3496125444, 3516976691, 3555094634,
5285             3525581405, 3311336976, 3298595879, 3336186494, 3340255305,
5286             3260503756, 3281337595, 3251864226, 3222399125, 3410866088,
5287             3398419871, 3368647622, 3372945905, 3427010420, 3448139075,
5288             3485520666, 3456284973, 2444203584, 2423127159, 2452308526,
5289             2481530905, 2527477404, 2539934891, 2502093554, 2497740997,
5290             2679949304, 2659102159, 2620920726, 2650438049, 2562027300,
5291             2574714131, 2603727690, 2599670141, 2374579504, 2353749767,
5292             2383274334, 2412743529, 2323684844, 2336421851, 2298759554,
5293             2294686645, 2207933576, 2186809023, 2149495014, 2178734801,
5294             2224278612, 2236720739, 2266437690, 2262135309, 2850214048,
5295             2820717207, 2858812622, 2879680249, 2934667388, 2938704459,
5296             2909776914, 2897069605, 2817622296, 2788420399, 2759153014,
5297             2780249921, 2700618180, 2704950259, 2742877610, 2730399645,
5298             3049550800, 3020298727, 3057690558, 3078802825, 2999835404,
5299             3004150075, 2974355298, 2961925461, 3151438440, 3121956959,
5300             3092510214, 3113327665, 3168701108, 3172786307, 3210370778,
5301             3197646061,
5302         },
5303         {
5304             0,          3099354981, 2852767883, 313896942,  2405603159,
5305             937357362,  627793884,  2648127673, 3316918511, 2097696650,
5306             1874714724, 3607201537, 1255587768, 4067088605, 3772741427,
5307             1482887254, 1343838111, 3903140090, 4195393300, 1118632049,
5308             3749429448, 1741137837, 1970407491, 3452858150, 2511175536,
5309             756094997,  1067759611, 2266550430, 449832999,  2725482306,
5310             2965774508, 142231497,  2687676222, 412010587,  171665333,
5311             2995192016, 793786473,  2548850444, 2237264098, 1038456711,
5312             1703315409, 3711623348, 3482275674, 1999841343, 3940814982,
5313             1381529571, 1089329165, 4166106984, 4029413537, 1217896388,
5314             1512189994, 3802027855, 2135519222, 3354724499, 3577784189,
5315             1845280792, 899665998,  2367928107, 2677414085, 657096608,
5316             3137160985, 37822588,   284462994,  2823350519, 2601801789,
5317             598228824,  824021174,  2309093331, 343330666,  2898962447,
5318             3195996129, 113467524,  1587572946, 3860600759, 4104763481,
5319             1276501820, 3519211397, 1769898208, 2076913422, 3279374443,
5320             3406630818, 1941006535, 1627703081, 3652755532, 1148164341,
5321             4241751952, 3999682686, 1457141531, 247015245,  3053797416,
5322             2763059142, 470583459,  2178658330, 963106687,  735213713,
5323             2473467892, 992409347,  2207944806, 2435792776, 697522413,
5324             3024379988, 217581361,  508405983,  2800865210, 4271038444,
5325             1177467017, 1419450215, 3962007554, 1911572667, 3377213406,
5326             3690561584, 1665525589, 1799331996, 3548628985, 3241568279,
5327             2039091058, 3831314379, 1558270126, 1314193216, 4142438437,
5328             2928380019, 372764438,  75645176,   3158189981, 568925988,
5329             2572515393, 2346768303, 861712586,  3982079547, 1441124702,
5330             1196457648, 4293663189, 1648042348, 3666298377, 3358779879,
5331             1888390786, 686661332,  2421291441, 2196002399, 978858298,
5332             2811169155, 523464422,  226935048,  3040519789, 3175145892,
5333             100435649,  390670639,  2952089162, 841119475,  2325614998,
5334             2553003640, 546822429,  2029308235, 3225988654, 3539796416,
5335             1782671013, 4153826844, 1328167289, 1570739863, 3844338162,
5336             1298864389, 4124540512, 3882013070, 1608431339, 3255406162,
5337             2058742071, 1744848601, 3501990332, 2296328682, 811816591,
5338             584513889,  2590678532, 129869501,  3204563416, 2914283062,
5339             352848211,  494030490,  2781751807, 3078325777, 264757620,
5340             2450577869, 715964072,  941166918,  2158327331, 3636881013,
5341             1618608400, 1926213374, 3396585883, 1470427426, 4011365959,
5342             4255988137, 1158766284, 1984818694, 3471935843, 3695453837,
5343             1693991400, 4180638033, 1100160564, 1395044826, 3952793279,
5344             3019491049, 189112716,  435162722,  2706139399, 1016811966,
5345             2217162459, 2526189877, 774831696,  643086745,  2666061564,
5346             2354934034, 887166583,  2838900430, 294275499,  54519365,
5347             3145957664, 3823145334, 1532818963, 1240029693, 4048895640,
5348             1820460577, 3560857924, 3331051178, 2117577167, 3598663992,
5349             1858283101, 2088143283, 3301633750, 1495127663, 3785470218,
5350             4078182116, 1269332353, 332098007,  2876706482, 3116540252,
5351             25085497,   2628386432, 605395429,  916469259,  2384220526,
5352             2254837415, 1054503362, 745528876,  2496903497, 151290352,
5353             2981684885, 2735556987, 464596510,  1137851976, 4218313005,
5354             3923506883, 1365741990, 3434129695, 1946996346, 1723425172,
5355             3724871409,
5356         },
5357         {
5358             0,          1029712304, 2059424608, 1201699536, 4118849216,
5359             3370159984, 2403399072, 2988497936, 812665793,  219177585,
5360             1253054625, 2010132753, 3320900865, 4170237105, 3207642721,
5361             2186319825, 1625331586, 1568718386, 438355170,  658566482,
5362             2506109250, 2818578674, 4020265506, 3535817618, 1351670851,
5363             1844508147, 709922595,  389064339,  2769320579, 2557498163,
5364             3754961379, 3803185235, 3250663172, 4238411444, 3137436772,
5365             2254525908, 876710340,  153198708,  1317132964, 1944187668,
5366             4054934725, 3436268917, 2339452837, 3054575125, 70369797,
5367             961670069,  2129760613, 1133623509, 2703341702, 2621542710,
5368             3689016294, 3867263574, 1419845190, 1774270454, 778128678,
5369             318858390,  2438067015, 2888948471, 3952189479, 3606153623,
5370             1691440519, 1504803895, 504432359,  594620247,  1492342857,
5371             1704161785, 573770537,  525542041,  2910060169, 2417219385,
5372             3618876905, 3939730521, 1753420680, 1440954936, 306397416,
5373             790849880,  2634265928, 2690882808, 3888375336, 3668168600,
5374             940822475,  91481723,   1121164459, 2142483739, 3448989963,
5375             4042473659, 3075684971, 2318603227, 140739594,  889433530,
5376             1923340138, 1338244826, 4259521226, 3229813626, 2267247018,
5377             3124975642, 2570221389, 2756861693, 3824297005, 3734113693,
5378             1823658381, 1372780605, 376603373,  722643805,  2839690380,
5379             2485261628, 3548540908, 4007806556, 1556257356, 1638052860,
5380             637716780,  459464860,  4191346895, 3300051327, 2199040943,
5381             3195181599, 206718479,  825388991,  1989285231, 1274166495,
5382             3382881038, 4106388158, 3009607790, 2382549470, 1008864718,
5383             21111934,   1189240494, 2072147742, 2984685714, 2357631266,
5384             3408323570, 4131834434, 1147541074, 2030452706, 1051084082,
5385             63335554,   2174155603, 3170292451, 4216760371, 3325460867,
5386             1947622803, 1232499747, 248909555,  867575619,  3506841360,
5387             3966111392, 2881909872, 2527485376, 612794832,  434546784,
5388             1581699760, 1663499008, 3782634705, 3692447073, 2612412337,
5389             2799048193, 351717905,  697754529,  1849071985, 1398190273,
5390             1881644950, 1296545318, 182963446,  931652934,  2242328918,
5391             3100053734, 4284967478, 3255255942, 1079497815, 2100821479,
5392             983009079,  133672583,  3050795671, 2293717799, 3474399735,
5393             4067887175, 281479188,  765927844,  1778867060, 1466397380,
5394             3846680276, 3626469220, 2676489652, 2733102084, 548881365,
5395             500656741,  1517752501, 1729575173, 3577210133, 3898068133,
5396             2952246901, 2459410373, 3910527195, 3564487019, 2480257979,
5397             2931134987, 479546907,  569730987,  1716854139, 1530213579,
5398             3647316762, 3825568426, 2745561210, 2663766474, 753206746,
5399             293940330,  1445287610, 1799716618, 2314567513, 3029685993,
5400             4080348217, 3461678473, 2088098201, 1091956777, 112560889,
5401             1003856713, 3112514712, 2229607720, 3276105720, 4263857736,
5402             1275433560, 1902492648, 918929720,  195422344,  685033439,
5403             364179055,  1377080511, 1869921551, 3713294623, 3761522863,
5404             2811507327, 2599689167, 413436958,  633644462,  1650777982,
5405             1594160846, 3978570462, 3494118254, 2548332990, 2860797966,
5406             1211387997, 1968470509, 854852413,  261368461,  3182753437,
5407             2161434413, 3346310653, 4195650637, 2017729436, 1160000044,
5408             42223868,   1071931724, 2378480988, 2963576044, 4144295484,
5409             3395602316,
5410         },
5411         {
5412             0,          3411858341, 1304994059, 2257875630, 2609988118,
5413             1355649459, 3596215069, 486879416,  3964895853, 655315400,
5414             2711298918, 1791488195, 2009251963, 3164476382, 973758832,
5415             4048990933, 64357019,   3364540734, 1310630800, 2235723829,
5416             2554806413, 1394316072, 3582976390, 517157411,  4018503926,
5417             618222419,  2722963965, 1762783832, 1947517664, 3209171269,
5418             970744811,  4068520014, 128714038,  3438335635, 1248109629,
5419             2167961496, 2621261600, 1466012805, 3522553387, 447296910,
5420             3959392091, 547575038,  2788632144, 1835791861, 1886307661,
5421             3140622056, 1034314822, 4143626211, 75106221,   3475428360,
5422             1236444838, 2196665603, 2682996155, 1421317662, 3525567664,
5423             427767573,  3895035328, 594892389,  2782995659, 1857943406,
5424             1941489622, 3101955187, 1047553757, 4113347960, 257428076,
5425             3288652233, 1116777319, 2311878850, 2496219258, 1603640287,
5426             3640781169, 308099796,  3809183745, 676813732,  2932025610,
5427             1704983215, 2023410199, 3016104370, 894593820,  4262377657,
5428             210634999,  3352484690, 1095150076, 2316991065, 2535410401,
5429             1547934020, 3671583722, 294336591,  3772615322, 729897279,
5430             2903845777, 1716123700, 2068629644, 2953845545, 914647431,
5431             4258839074, 150212442,  3282623743, 1161604689, 2388688372,
5432             2472889676, 1480171241, 3735940167, 368132066,  3836185911,
5433             805002898,  2842635324, 1647574937, 2134298401, 3026852996,
5434             855535146,  4188192143, 186781121,  3229539940, 1189784778,
5435             2377547631, 2427670487, 1542429810, 3715886812, 371670393,
5436             3882979244, 741170185,  2864262823, 1642462466, 2095107514,
5437             3082559007, 824732849,  4201955092, 514856152,  3589064573,
5438             1400419795, 2552522358, 2233554638, 1316849003, 3370776517,
5439             62202976,   4075001525, 968836368,  3207280574, 1954014235,
5440             1769133219, 2720925446, 616199592,  4024870413, 493229635,
5441             3594175974, 1353627464, 2616354029, 2264355925, 1303087088,
5442             3409966430, 6498043,    4046820398, 979978123,  3170710821,
5443             2007099008, 1789187640, 2717386141, 661419827,  3962610838,
5444             421269998,  3527459403, 1423225061, 2676515648, 2190300152,
5445             1238466653, 3477467891, 68755798,   4115633027, 1041448998,
5446             3095868040, 1943789869, 1860096405, 2776760880, 588673182,
5447             3897205563, 449450869,  3516317904, 1459794558, 2623431131,
5448             2170245475, 1242006214, 3432247400, 131015629,  4137259288,
5449             1036337853, 3142660115, 1879958454, 1829294862, 2790523051,
5450             549483013,  3952910752, 300424884,  3669282065, 1545650111,
5451             2541513754, 2323209378, 1092980487, 3350330793, 216870412,
5452             4256931033, 921128828,  2960342482, 2066738807, 1714085583,
5453             2910195050, 736264132,  3770592353, 306060335,  3647131530,
5454             1610005796, 2494197377, 2309971513, 1123257756, 3295149874,
5455             255536279,  4268596802, 892423655,  3013951305, 2029645036,
5456             1711070292, 2929725425, 674528607,  3815288570, 373562242,
5457             3709388839, 1535949449, 2429577516, 2379569556, 1183418929,
5458             3223189663, 188820282,  4195850735, 827017802,  3084859620,
5459             2089020225, 1636228089, 2866415708, 743340786,  3876759895,
5460             361896217,  3738094268, 1482340370, 2466671543, 2382584591,
5461             1163888810, 3284924932, 144124321,  4190215028, 849168593,
5462             3020503679, 2136336858, 1649465698, 2836138695, 798521449,
5463             3838094284,
5464         },
5465         {
5466             0,          2792819636, 2543784233, 837294749,  4098827283,
5467             1379413927, 1674589498, 3316072078, 871321191,  2509784531,
5468             2758827854, 34034938,   3349178996, 1641505216, 1346337629,
5469             4131942633, 1742642382, 3249117050, 4030828007, 1446413907,
5470             2475800797, 904311657,  68069876,   2725880384, 1412551337,
5471             4064729373, 3283010432, 1708771380, 2692675258, 101317902,
5472             937551763,  2442587175, 3485284764, 1774858792, 1478633653,
5473             4266992385, 1005723023, 2642744891, 2892827814, 169477906,
5474             4233263099, 1512406095, 1808623314, 3451546982, 136139752,
5475             2926205020, 2676114113, 972376437,  2825102674, 236236518,
5476             1073525883, 2576072655, 1546420545, 4200303349, 3417542760,
5477             1841601500, 2609703733, 1039917185, 202635804,  2858742184,
5478             1875103526, 3384067218, 4166835727, 1579931067, 1141601657,
5479             3799809741, 3549717584, 1977839588, 2957267306, 372464350,
5480             668680259,  2175552503, 2011446046, 3516084394, 3766168119,
5481             1175200131, 2209029901, 635180217,  338955812,  2990736784,
5482             601221559,  2242044419, 3024812190, 306049834,  3617246628,
5483             1911408144, 1074125965, 3866285881, 272279504,  3058543716,
5484             2275784441, 567459149,  3832906691, 1107462263, 1944752874,
5485             3583875422, 2343980261, 767641425,  472473036,  3126744696,
5486             2147051766, 3649987394, 3899029983, 1309766251, 3092841090,
5487             506333494,  801510315,  2310084639, 1276520081, 3932237093,
5488             3683203000, 2113813516, 3966292011, 1243601823, 2079834370,
5489             3716205238, 405271608,  3192979340, 2411259153, 701492901,
5490             3750207052, 2045810168, 1209569125, 4000285905, 734575199,
5491             2378150379, 3159862134, 438345922,  2283203314, 778166598,
5492             529136603,  3120492655, 2086260449, 3660498261, 3955679176,
5493             1303499900, 3153699989, 495890209,  744928700,  2316418568,
5494             1337360518, 3921775410, 3626602927, 2120129051, 4022892092,
5495             1237286280, 2018993941, 3726666913, 461853231,  3186645403,
5496             2350400262, 711936178,  3693557851, 2052076527, 1270360434,
5497             3989775046, 677911624,  2384402428, 3220639073, 427820757,
5498             1202443118, 3789347034, 3493118535, 1984154099, 3018127229,
5499             362020041,  612099668,  2181885408, 1950653705, 3526596285,
5500             3822816288, 1168934804, 2148251930, 645706414,  395618355,
5501             2984485767, 544559008,  2248295444, 3085590153, 295523645,
5502             3560598451, 1917673479, 1134918298, 3855773998, 328860103,
5503             3052210803, 2214924526, 577903450,  3889505748, 1101147744,
5504             1883911421, 3594338121, 3424493451, 1785369663, 1535282850,
5505             4260726038, 944946072,  2653270060, 2949491377, 163225861,
5506             4294103532, 1501944408, 1752023237, 3457862513, 196998655,
5507             2915761739, 2619532502, 978710370,  2881684293, 229902577,
5508             1012666988, 2586515928, 1603020630, 4193987810, 3356702335,
5509             1852063179, 2553040162, 1046169238, 263412747,  2848217023,
5510             1818454321, 3390333573, 4227627032, 1569420204, 60859927,
5511             2782375331, 2487203646, 843627658,  4159668740, 1368951216,
5512             1617990445, 3322386585, 810543216,  2520310724, 2815490393,
5513             27783917,   3288386659, 1652017111, 1402985802, 4125677310,
5514             1685994201, 3255382381, 4091620336, 1435902020, 2419138250,
5515             910562686,  128847843,  2715354199, 1469150398, 4058414858,
5516             3222168983, 1719234083, 2749255853, 94984985,   876691844,
5517             2453031472,
5518         },
5519         {
5520             0,          3433693342, 1109723005, 2391738339, 2219446010,
5521             1222643300, 3329165703, 180685081,  3555007413, 525277995,
5522             2445286600, 1567235158, 1471092047, 2600801745, 361370162,
5523             3642757804, 2092642603, 2953916853, 1050555990, 4063508168,
5524             4176560081, 878395215,  3134470316, 1987983410, 2942184094,
5525             1676945920, 3984272867, 567356797,  722740324,  3887998202,
5526             1764827929, 2778407815, 4185285206, 903635656,  3142804779,
5527             2012833205, 2101111980, 2979425330, 1058630609, 4088621903,
5528             714308067,  3862526333, 1756790430, 2753330688, 2933487385,
5529             1651734407, 3975966820, 542535930,  2244825981, 1231508451,
5530             3353891840, 188896414,  25648519,   3442302233, 1134713594,
5531             2399689316, 1445480648, 2592229462, 336416693,  3634843435,
5532             3529655858, 516441772,  2420588879, 1559052753, 698204909,
5533             3845636723, 1807271312, 2803025166, 2916600855, 1635634313,
5534             4025666410, 593021940,  4202223960, 919787974,  3093159461,
5535             1962401467, 2117261218, 2996361020, 1008193759, 4038971457,
5536             1428616134, 2576151384, 386135227,  3685348389, 3513580860,
5537             499580322,  2471098945, 1608776415, 2260985971, 1248454893,
5538             3303468814, 139259792,  42591881,   3458459159, 1085071860,
5539             2349261162, 3505103035, 474062885,  2463016902, 1583654744,
5540             1419882049, 2550902495, 377792828,  3660491170, 51297038,
5541             3483679632, 1093385331, 2374089965, 2269427188, 1273935210,
5542             3311514249, 164344343,  2890961296, 1627033870, 4000683757,
5543             585078387,  672833386,  3836780532, 1782552599, 2794821769,
5544             2142603813, 3005188795, 1032883544, 4047146438, 4227826911,
5545             928351297,  3118105506, 1970307900, 1396409818, 2677114180,
5546             287212199,  3719594553, 3614542624, 467372990,  2505346141,
5547             1509854403, 2162073199, 1282711281, 3271268626, 240228748,
5548             76845205,   3359543307, 1186043880, 2317064054, 796964081,
5549             3811226735, 1839575948, 2702160658, 2882189835, 1734392469,
5550             3924802934, 625327592,  4234522436, 818917338,  3191908409,
5551             1927981223, 2016387518, 3028656416, 973776579,  4137723485,
5552             2857232268, 1726474002, 3899187441, 616751215,  772270454,
5553             3803048424, 1814228491, 2693328533, 2041117753, 3036871847,
5554             999160644,  4146592730, 4259508931, 826864221,  3217552830,
5555             1936586016, 3606501031, 442291769,  2496909786, 1484378436,
5556             1388107869, 2652297411, 278519584,  3694387134, 85183762,
5557             3384397196, 1194773103, 2342308593, 2170143720, 1307820918,
5558             3279733909, 265733131,  2057717559, 3054258089, 948125770,
5559             4096344276, 4276898253, 843467091,  3167309488, 1885556270,
5560             2839764098, 1709792284, 3949353983, 667704161,  755585656,
5561             3785577190, 1865176325, 2743489947, 102594076,  3401021058,
5562             1144549729, 2291298815, 2186770662, 1325234296, 3228729243,
5563             215514885,  3589828009, 424832311,  2547870420, 1534552650,
5564             1370645331, 2635621325, 328688686,  3745342640, 2211456353,
5565             1333405183, 3254067740, 224338562,  127544219,  3408931589,
5566             1170156774, 2299866232, 1345666772, 2627681866, 303053225,
5567             3736746295, 3565105198, 416624816,  2522494803, 1525692365,
5568             4285207626, 868291796,  3176010551, 1910772649, 2065767088,
5569             3079346734, 956571085,  4121828691, 747507711,  3760459617,
5570             1856702594, 2717976604, 2831417605, 1684930971, 3940615800,
5571             642451174,
5572         },
5573         {
5574             0,          393942083,  787884166,  965557445,  1575768332,
5575             1251427663, 1931114890, 1684106697, 3151536664, 2896410203,
5576             2502855326, 2186649309, 3862229780, 4048545623, 3368213394,
5577             3753496529, 2898281073, 3149616690, 2184604407, 2504883892,
5578             4046197629, 3864463166, 3755621371, 3366006712, 387506281,
5579             6550570,    971950319,  781573292,  1257550181, 1569695014,
5580             1677892067, 1937345952, 2196865699, 2508887776, 2886183461,
5581             3145514598, 3743273903, 3362179052, 4058774313, 3868258154,
5582             958996667,  777139448,  400492605,  10755198,   1690661303,
5583             1941857780, 1244879153, 1565019506, 775012562,  961205393,
5584             13101140,   398261271,  1943900638, 1688634781, 1563146584,
5585             1246801179, 2515100362, 2190636681, 3139390028, 2892258831,
5586             3355784134, 3749586821, 3874691904, 4052225795, 3734110983,
5587             3387496260, 4033096577, 3877584834, 2206093835, 2483373640,
5588             2911402637, 3136515790, 1699389727, 1915860316, 1270647193,
5589             1556585946, 950464531,  803071056,  374397077,  19647702,
5590             1917993334, 1697207605, 1554278896, 1272937907, 800985210,
5591             952435769,  21510396,   372452543,  3381322606, 3740399405,
5592             3883715560, 4027047851, 2489758306, 2199758369, 3130039012,
5593             2917895847, 1550025124, 1259902439, 1922410786, 1710144865,
5594             26202280,   385139947,  796522542,  939715693,  3887801276,
5595             4039129087, 3377269562, 3728088953, 3126293168, 2905368307,
5596             2493602358, 2212122229, 4037264341, 3889747862, 3730172755,
5597             3375300368, 2907673305, 3124004506, 2209987167, 2495786524,
5598             1266377165, 1543533966, 1703758155, 1928748296, 379007169,
5599             32253058,   945887303,  790236164,  1716846671, 1898845196,
5600             1218652361, 1608006794, 1002000707, 750929152,  357530053,
5601             36990342,   3717046871, 3405166100, 4084959953, 3825245842,
5602             2153902939, 2535122712, 2929187805, 3119304606, 3398779454,
5603             3723384445, 3831720632, 4078468859, 2541294386, 2147616625,
5604             3113171892, 2935238647, 1900929062, 1714877541, 1606142112,
5605             1220599011, 748794154,  1004184937, 39295404,   355241455,
5606             3835986668, 4091516591, 3394415210, 3710500393, 3108557792,
5607             2922629027, 2545875814, 2160455461, 1601970420, 1208431799,
5608             1904871538, 1727077425, 43020792,   367748539,  744905086,
5609             991776061,  1214562461, 1595921630, 1720903707, 1911159896,
5610             361271697,  49513938,   998160663,  738569556,  4089209477,
5611             3838277318, 3712633347, 3392233024, 2924491657, 3106613194,
5612             2158369551, 2547846988, 3100050248, 2948339467, 2519804878,
5613             2169126797, 3844821572, 4065347079, 3420289730, 3701894785,
5614             52404560,   342144275,  770279894,  982687125,  1593045084,
5615             1233708063, 1879431386, 1736363161, 336019769,  58479994,
5616             988899775,  764050940,  1240141877, 1586496630, 1729968307,
5617             1885744368, 2950685473, 3097818978, 2166999975, 2522013668,
5618             4063474221, 3846743662, 3703937707, 3418263272, 976650731,
5619             760059304,  348170605,  62635310,   1742393575, 1889649828,
5620             1227683937, 1582820386, 2179867635, 2526361520, 2937588597,
5621             3093503798, 3691148031, 3413731004, 4076100217, 3851374138,
5622             2532754330, 2173556697, 3087067932, 2944139103, 3407516310,
5623             3697379029, 3857496592, 4070026835, 758014338,  978679233,
5624             64506116,   346250567,  1891774606, 1740186829, 1580472328,
5625             1229917259,
5626         },
5627         {
5628             0,          4022496062, 83218493,   3946298115, 166436986,
5629             3861498692, 220098631,  3806075769, 332873972,  4229245898,
5630             388141257,  4175494135, 440197262,  4127099824, 516501683,
5631             4044053389, 665747944,  3362581206, 593187285,  3432594155,
5632             776282514,  3246869164, 716239279,  3312622225, 880394524,
5633             3686509090, 814485793,  3746462239, 1033003366, 3528460888,
5634             963096923,  3601193573, 1331495888, 2694801646, 1269355501,
5635             2758457555, 1186374570, 2843003028, 1111716759, 2910918825,
5636             1552565028, 3007850522, 1484755737, 3082680359, 1432478558,
5637             3131279456, 1368666979, 3193329757, 1760789048, 2268195078,
5638             1812353541, 2210675003, 1628971586, 2396670332, 1710092927,
5639             2318375233, 2066006732, 2498144754, 2144408305, 2417195471,
5640             1926193846, 2634877320, 1983558283, 2583222709, 2662991776,
5641             1903717534, 2588923805, 1972223139, 2538711002, 2022952164,
5642             2477029351, 2087066841, 2372749140, 1655647338, 2308478825,
5643             1717238871, 2223433518, 1799654416, 2155034387, 1873894445,
5644             3105130056, 1456926070, 3185661557, 1378041163, 2969511474,
5645             1597852940, 3020617231, 1539874097, 2864957116, 1157737858,
5646             2922780289, 1106542015, 2737333958, 1290407416, 2816325371,
5647             1210047941, 3521578096, 1042640718, 3574781005, 986759027,
5648             3624707082, 936300340,  3707335735, 859512585,  3257943172,
5649             770846650,  3334837433, 688390023,  3420185854, 605654976,
5650             3475911875, 552361981,  4132013464, 428600998,  4072428965,
5651             494812827,  4288816610, 274747100,  4216845791, 345349857,
5652             3852387692, 173846098,  3781891409, 245988975,  3967116566,
5653             62328360,   3900749099, 121822741,  3859089665, 164061759,
5654             3807435068, 221426178,  4025395579, 2933317,    3944446278,
5655             81334904,   4124199413, 437265099,  4045904328, 518386422,
5656             4231653775, 335250097,  4174133682, 386814604,  3249244393,
5657             778691543,  3311294676, 714879978,  3359647891, 662848429,
5658             3434477742, 595039120,  3531393053, 1035903779, 3599308832,
5659             961245982,  3684132967, 877986649,  3747788890, 815846244,
5660             2841119441, 1184522735, 2913852140, 1114616274, 2696129195,
5661             1332855189, 2756082326, 1266946472, 3129952805, 1431118107,
5662             3195705880, 1371074854, 3009735263, 1554415969, 3079748194,
5663             1481855324, 2398522169, 1630855175, 2315475716, 1707159610,
5664             2266835779, 1759461501, 2213084030, 1814728768, 2636237773,
5665             1927520499, 2580814832, 1981182158, 2496293815, 2064121993,
5666             2420095882, 2147340468, 2025787041, 2541577631, 2085281436,
5667             2475210146, 1901375195, 2660681189, 1973518054, 2590184920,
5668             1801997909, 2225743211, 1872600680, 2153772374, 1652813359,
5669             2369881361, 1719025170, 2310296876, 1594986313, 2966676599,
5670             1541693300, 3022402634, 1459236659, 3107472397, 1376780046,
5671             3184366640, 1288097725, 2734990467, 1211309952, 2817619134,
5672             1160605639, 2867791097, 1104723962, 2920993988, 937561457,
5673             3626001999, 857201996,  3704993394, 1040821515, 3519792693,
5674             989625654,  3577615880, 607473029,  3421972155, 549494200,
5675             3473077894, 769584639,  3256649409, 690699714,  3337180924,
5676             273452185,  4287555495, 347692196,  4219156378, 430386403,
5677             4133832669, 491977950,  4069562336, 60542061,   3965298515,
5678             124656720,  3903616878, 175139863,  3853649705, 243645482,
5679             3779581716,
5680         },
5681         {
5682             0,          3247366080, 1483520449, 2581751297, 2967040898,
5683             1901571138, 3904227907, 691737987,  3133399365, 2068659845,
5684             3803142276, 589399876,  169513671,  3415493895, 1383475974,
5685             2482566342, 2935407819, 1870142219, 4137319690, 924099274,
5686             506443593,  3751897225, 1178799752, 2278412616, 339027342,
5687             3585866318, 1280941135, 2379694991, 2766951948, 1700956620,
5688             4236308429, 1024339981, 2258407383, 1192382487, 3740284438,
5689             528411094,  910556245,  4157285269, 1848198548, 2946996820,
5690             1012887186, 4258378066, 1681119059, 2780629139, 2357599504,
5691             1292419792, 3572147409, 358906641,  678054684,  3924071644,
5692             1879503581, 2978491677, 2561882270, 1497229150, 3235873119,
5693             22109855,   2460592729, 1395094937, 3401913240, 189516888,
5694             577821147,  3825075739, 2048679962, 3146956762, 3595049455,
5695             398902831,  2384764974, 1336573934, 1720805997, 2803873197,
5696             1056822188, 4285729900, 1821112490, 2902796138, 887570795,
5697             4117339819, 3696397096, 500978920,  2218668777, 1169222953,
5698             2025774372, 3106931428, 550659301,  3780950821, 3362238118,
5699             166293862,  2416645991, 1367722151, 3262987361, 66315169,
5700             2584839584, 1537170016, 1923370979, 3005911075, 717813282,
5701             3947244002, 1356109368, 2438613496, 146288633,  3375820857,
5702             3759007162, 562248314,  3093388411, 2045739963, 3927406461,
5703             731490493,  2994458300, 1945440636, 1523451135, 2604718911,
5704             44219710,   3274466046, 4263662323, 1068272947, 2790189874,
5705             1740649714, 1325080945, 2406874801, 379033776,  3608758128,
5706             1155642294, 2238671990, 479005303,  3708016055, 4097359924,
5707             901128180,  2891217397, 1843045941, 2011248031, 3060787807,
5708             797805662,  3993195422, 3342353949, 112630237,  2673147868,
5709             1591353372, 3441611994, 212601626,  2504944923, 1421914843,
5710             2113644376, 3161815192, 630660761,  3826893145, 3642224980,
5711             412692116,  2172340373, 1089836885, 1775141590, 2822790422,
5712             832715543,  4029474007, 1674842129, 2723860433, 1001957840,
5713             4197873168, 3540870035, 310623315,  2338445906, 1257178514,
5714             4051548744, 821257608,  2836464521, 1755307081, 1101318602,
5715             2150241802, 432566283,  3628511179, 1270766349, 2318435533,
5716             332587724,  3529260300, 4217841807, 988411727,  2735444302,
5717             1652903566, 1602977411, 2651169091, 132630338,  3328776322,
5718             4015131905, 786223809,  3074340032, 1991273216, 3846741958,
5719             616972294,  3173262855, 2091579847, 1435626564, 2485072772,
5720             234706309,  3430124101, 2712218736, 1613231024, 4190475697,
5721             944458353,  292577266,  3506339890, 1226630707, 2291284467,
5722             459984181,  3672380149, 1124496628, 2189994804, 2880683703,
5723             1782407543, 4091479926, 844224694,  257943739,  3469817723,
5724             1462980986, 2529005242, 3213269817, 2114471161, 3890881272,
5725             644152632,  3046902270, 1947391550, 3991973951, 746483711,
5726             88439420,   3301680572, 1563018173, 2628197501, 657826727,
5727             3871046759, 2136545894, 3201811878, 2548879397, 1449267173,
5728             3481299428, 235845156,  2650161890, 1551408418, 3315268387,
5729             68429027,   758067552,  3970035360, 1967360161, 3033356129,
5730             2311284588, 1213053100, 3517963949, 270598509,  958010606,
5731             4170500910, 1635167535, 2700636911, 855672361,  4069415401,
5732             1802256360, 2866995240, 2212099499, 1113008747, 3686091882,
5733             440112042,
5734         },
5735         {
5736             0,          2611301487, 3963330207, 2006897392, 50740095,
5737             2560849680, 4013794784, 1956178319, 101480190,  2645113489,
5738             3929532513, 1905435662, 84561281,   2662269422, 3912356638,
5739             1922342769, 202960380,  2545787283, 3760419683, 2072395532,
5740             253679235,  2495322860, 3810871324, 2021655667, 169122562,
5741             2444351341, 3861841309, 2106214898, 152215677,  2461527058,
5742             3844685538, 2123133581, 405920760,  2207553431, 4094313831,
5743             1873742088, 456646791,  2157096168, 4144791064, 1823027831,
5744             507358470,  2241388905, 4060492697, 1772322806, 490444409,
5745             2258557462, 4043311334, 1789215881, 338245124,  2408348267,
5746             4161972379, 1672996084, 388959611,  2357870868, 4212429796,
5747             1622269835, 304431354,  2306870421, 4263435877, 1706791434,
5748             287538053,  2324051946, 4246267162, 1723705717, 811841520,
5749             2881944479, 3696765295, 1207788800, 862293135,  2831204576,
5750             3747484176, 1157324415, 913293582,  2915732833, 3662962577,
5751             1106318334, 896137841,  2932651550, 3646055662, 1123494017,
5752             1014716940, 2816349795, 3493905555, 1273334012, 1065181555,
5753             2765630748, 3544645612, 1222882179, 980888818,  2714919069,
5754             3595350637, 1307180546, 963712909,  2731826146, 3578431762,
5755             1324336509, 676490248,  3019317351, 3295277719, 1607253752,
5756             726947703,  2968591128, 3345992168, 1556776327, 777919222,
5757             3053147801, 3261432937, 1505806342, 760750473,  3070062054,
5758             3244539670, 1522987897, 608862708,  3220163995, 3362856811,
5759             1406423812, 659339915,  3169449700, 3413582868, 1355966587,
5760             575076106,  3118709605, 3464325525, 1440228858, 557894773,
5761             3135602714, 3447411434, 1457397381, 1623683040, 4217512847,
5762             2365387135, 391757072,  1673614495, 4167309552, 2415577600,
5763             341804655,  1724586270, 4251866481, 2331019137, 290835438,
5764             1707942497, 4268256782, 2314648830, 307490961,  1826587164,
5765             4152020595, 2162433155, 457265388,  1876539747, 4101829900,
5766             2212636668, 407333779,  1792275682, 4051089549, 2263378557,
5767             491595282,  1775619997, 4067460082, 2246988034, 508239213,
5768             2029433880, 3813931127, 2496473735, 258500328,  2079362919,
5769             3763716872, 2546668024, 208559511,  2130363110, 3848244873,
5770             2462145657, 157552662,  2113730969, 3864638966, 2445764358,
5771             174205801,  1961777636, 4014675339, 2564147067, 57707284,
5772             2011718299, 3964481268, 2614361092, 7778411,    1927425818,
5773             3913769845, 2665066885, 92077546,   1910772837, 3930150922,
5774             2648673018, 108709525,  1352980496, 3405878399, 3164554895,
5775             658115296,  1403183983, 3355946752, 3214507504, 607924639,
5776             1453895406, 3440239233, 3130208369, 557218846,  1437504913,
5777             3456883198, 3113552654, 573589345,  1555838444, 3340335491,
5778             2961681267, 723707676,  1606028947, 3290383100, 3011612684,
5779             673504355,  1521500946, 3239382909, 3062619533, 758026722,
5780             1505130605, 3256038402, 3045975794, 774417053,  1217725416,
5781             3543158663, 2762906999, 1057739032, 1267939479, 3493229816,
5782             2812847624, 1007544935, 1318679830, 3577493881, 2728586121,
5783             956803046,  1302285929, 3594125830, 2711933174, 973184153,
5784             1150152212, 3743982203, 2830528651, 856898788,  1200346475,
5785             3694041348, 2880457716, 806684571,  1115789546, 3643069573,
5786             2931426933, 891243034,  1099408277, 3659722746, 2914794762,
5787             907637093,
5788         },
5789         {
5790             0,          3717650821, 1616688459, 3184159950, 3233376918,
5791             489665299,  2699419613, 2104690264, 1510200173, 2274691816,
5792             979330598,  3888758691, 2595928571, 1194090622, 4209380528,
5793             661706037,  3020400346, 1771143007, 3562738577, 164481556,
5794             1958661196, 2837976521, 350386439,  3379863682, 3993269687,
5795             865250354,  2388181244, 1406015865, 784146209,  4079732388,
5796             1323412074, 2474079215, 3011398645, 1860735600, 3542286014,
5797             246687547,  1942430051, 2924607718, 328963112,  3456978349,
5798             3917322392, 887832861,  2300653011, 1421341782, 700772878,
5799             4099025803, 1234716485, 2483986112, 125431087,  3673109674,
5800             1730500708, 3132326369, 3351283641, 441867836,  2812031730,
5801             2047535991, 1568292418, 2163009479, 1025936137, 3769651852,
5802             2646824148, 1079348561, 4255113631, 537475098,  3180171691,
5803             1612400686, 3721471200, 4717925,    2100624189, 2694980280,
5804             493375094,  3237910515, 3884860102, 974691139,  2278750093,
5805             1514417672, 657926224,  4204917205, 1198234907, 2600289438,
5806             160053105,  3558665972, 1775665722, 3024116671, 3375586791,
5807             346391650,  2842683564, 1962488105, 1401545756, 2384412057,
5808             869618007,  3997403346, 2469432970, 1319524111, 4083956673,
5809             788193860,  250862174,  3546612699, 1856990997, 3006903952,
5810             3461001416, 333211981,  2920678787, 1937824774, 1425017139,
5811             2305216694, 883735672,  3912918525, 2487837605, 1239398944,
5812             4095071982, 696455019,  3136584836, 1734518017, 3668494799,
5813             121507914,  2051872274, 2816200599, 437363545,  3347544796,
5814             3774328809, 1029797484, 2158697122, 1564328743, 542033279,
5815             4258798842, 1074950196, 2642717105, 2691310871, 2113731730,
5816             3224801372, 497043929,  1624461185, 3175454212, 9435850,
5817             3709412175, 4201248378, 671035391,  2587181873, 1201904308,
5818             986750188,  3880142185, 1519135143, 2266689570, 342721485,
5819             3388693064, 1949382278, 2846355203, 3570723163, 155332830,
5820             3028835344, 1763607957, 1315852448, 2482538789, 775087595,
5821             4087626862, 2396469814, 1396827059, 4002123645, 857560824,
5822             320106210,  3464673127, 1934154665, 2933785132, 3551331444,
5823             238804465,  3018961215, 1852270778, 1226292623, 2491507722,
5824             692783300,  4108177729, 2309936921, 1412959900, 3924976210,
5825             879016919,  2803091512, 2055541181, 3343875443, 450471158,
5826             1739236014, 3124525867, 133568485,  3663777376, 4245691221,
5827             545702608,  2639048222, 1088059291, 1034514883, 3762268230,
5828             1576387720, 2153979149, 501724348,  3228659001, 2109407735,
5829             2687359090, 3713981994, 13109167,   3171052385, 1620357860,
5830             1206151121, 2591211092, 666423962,  4197321503, 2271022407,
5831             1523307714, 3875649548, 982999433,  2850034278, 1953942499,
5832             3384583981, 338329256,  1767471344, 3033506165, 151375291,
5833             3566408766, 4091789579, 779425934,  2478797888, 1311354309,
5834             861580189,  4006375960, 1392910038, 2391852883, 2929327945,
5835             1930372812, 3469036034, 324244359,  1847629279, 3015068762,
5836             243015828,  3555391761, 4103744548, 688715169,  2496043375,
5837             1229996266, 874727090,  3920994103, 1417671673, 2313759356,
5838             446585235,  3339223062, 2059594968, 2807313757, 3660002053,
5839             129100416,  3128657486, 1743609803, 1084066558, 2634765179,
5840             549535669,  4250396208, 2149900392, 1571961325, 3765982499,
5841             1039043750,
5842         },
5843         {
5844             0,          2635063670, 3782132909, 2086741467, 430739227,
5845             2225303149, 4173482934, 1707977408, 861478454,  2924937024,
5846             3526875803, 1329085421, 720736557,  3086643291, 3415954816,
5847             1452586230, 1722956908, 4223524122, 2279405761, 450042295,
5848             2132718455, 3792785921, 2658170842, 58693292,   1441473114,
5849             3370435372, 3028674295, 696911745,  1279765825, 3511176247,
5850             2905172460, 807831706,  3445913816, 1349228974, 738901109,
5851             2969918723, 3569940419, 1237784245, 900084590,  2829701656,
5852             4265436910, 1664255896, 525574723,  2187084597, 3885099509,
5853             2057177219, 117386584,  2616249390, 2882946228, 920233410,
5854             1253605401, 3619119471, 2994391983, 796207833,  1393823490,
5855             3457937012, 2559531650, 92322804,   2044829231, 3840835417,
5856             2166609305, 472659183,  1615663412, 4249022530, 1102706673,
5857             3702920839, 2698457948, 1037619754, 1477802218, 3306854812,
5858             3111894087, 611605809,  1927342535, 4025419953, 2475568490,
5859             243387420,  1800169180, 4131620778, 2317525617, 388842247,
5860             655084445,  3120835307, 3328511792, 1533734470, 1051149446,
5861             2745738736, 3754524715, 1120297309, 340972971,  2304586973,
5862             4114354438, 1748234352, 234773168,  2431761350, 3968900637,
5863             1906278251, 2363330345, 299003487,  1840466820, 4038896370,
5864             2507210802, 142532932,  1948239007, 3910149609, 3213136159,
5865             579563625,  1592415666, 3286611140, 2787646980, 992477042,
5866             1195825833, 3662232543, 3933188933, 2002801203, 184645608,
5867             2517538462, 4089658462, 1858919720, 313391347,  2409765253,
5868             3644239219, 1144605701, 945318366,  2773977256, 3231326824,
5869             1570095902, 569697989,  3170568115, 2205413346, 511446676,
5870             1646078799, 4279421497, 2598330617, 131105167,  2075239508,
5871             3871229218, 2955604436, 757403810,  1363424633, 3427521551,
5872             2844163791, 881434553,  1223211618, 3588709140, 3854685070,
5873             2026779384, 78583587,   2577462869, 4235025557, 1633861091,
5874             486774840,  2148301134, 3600338360, 1268198606, 938871061,
5875             2868504675, 3476308643, 1379640277, 777684494,  3008718712,
5876             1310168890, 3541595724, 2943964055, 846639841,  1471879201,
5877             3400857943, 3067468940, 735723002,  2102298892, 3762382970,
5878             2619362721, 19901655,   1692534295, 4193118049, 2240594618,
5879             411247564,  681945942,  3047836192, 3385552891, 1422167693,
5880             822682701,  2886124859, 3496468704, 1298661782, 469546336,
5881             2264093718, 4203901389, 1738379451, 38812283,   2673859341,
5882             3812556502, 2117148576, 3268024339, 1606809957, 598006974,
5883             3198893512, 3680933640, 1181316734, 973624229,  2802299603,
5884             4052944421, 1822222163, 285065864,  2381456382, 3896478014,
5885             1966106696, 156323219,  2489232613, 2759337087, 964150537,
5886             1159127250, 3625517476, 3184831332, 551242258,  1555722185,
5887             3249901247, 2535537225, 170842943,  1984954084, 3946848146,
5888             2391651666, 327308324,  1877176831, 4075589769, 263086283,
5889             2460058045, 4005602406, 1942963472, 369291216,  2332888742,
5890             4151061373, 1784924683, 1022852861, 2717425547, 3717839440,
5891             1083595558, 626782694,  3092517008, 3291821387, 1497027645,
5892             1763466407, 4094934481, 2289211402, 360544636,  1890636732,
5893             3988730570, 2447251217, 215086695,  1514488465, 3343557607,
5894             3140191804, 639919946,  1139395978, 3739626748, 2726758695,
5895             1065936977,
5896         },
5897         {
5898             0,          3120290792, 2827399569, 293431929,  2323408227,
5899             864534155,  586863858,  2600537882, 3481914503, 1987188591,
5900             1729068310, 3740575486, 1173727716, 4228805132, 3983743093,
5901             1418249117, 1147313999, 4254680231, 3974377182, 1428157750,
5902             3458136620, 2011505092, 1721256893, 3747844181, 2347455432,
5903             839944224,  594403929,  2593536433, 26687147,   3094146371,
5904             2836498234, 283794642,  2294627998, 826205558,  541298447,
5905             2578994407, 45702141,   3141697557, 2856315500, 331624836,
5906             1196225049, 4273416689, 4023010184, 1446090848, 3442513786,
5907             1959480466, 1706436331, 3696098563, 3433538001, 1968994873,
5908             1679888448, 3722103720, 1188807858, 4280295258, 3999102243,
5909             1470541515, 53374294,   3134568126, 2879970503, 307431215,
5910             2303854645, 816436189,  567589284,  2553242188, 3405478781,
5911             1929420949, 1652411116, 3682996484, 1082596894, 4185703926,
5912             3892424591, 1375368295, 91404282,   3163122706, 2918450795,
5913             336584067,  2400113305, 922028401,  663249672,  2658384096,
5914             2392450098, 929185754,  639587747,  2682555979, 82149713,
5915             3172883129, 2892181696, 362343208,  1091578037, 4176212829,
5916             3918960932, 1349337804, 3412872662, 1922537022, 1676344391,
5917             3658557359, 1111377379, 4224032267, 3937989746, 1396912026,
5918             3359776896, 1908013928, 1623494929, 3644803833, 2377615716,
5919             877417100,  623982837,  2630542109, 130804743,  3190831087,
5920             2941083030, 381060734,  106748588,  3215393092, 2933549885,
5921             388083925,  2350956495, 903570471,  614862430,  2640172470,
5922             3386185259, 1882115523, 1632872378, 3634920530, 1135178568,
5923             4199721120, 3945775833, 1389631793, 1317531835, 4152109907,
5924             3858841898, 1610259138, 3304822232, 2097172016, 1820140617,
5925             3582394273, 2165193788, 955639764,  696815021,  2423477829,
5926             192043359,  2995356343, 2750736590, 437203750,  182808564,
5927             3005133852, 2724453989, 462947725,  2157513367, 962777471,
5928             673168134,  2447663342, 3312231283, 2090301595, 1844056802,
5929             3557935370, 1326499344, 4142603768, 3885397889, 1584245865,
5930             3326266917, 2142836173, 1858371508, 3611272284, 1279175494,
5931             4123357358, 3837270743, 1564721471, 164299426,  2955991370,
5932             2706223923, 414607579,  2209834945, 978107433,  724686416,
5933             2462715320, 2183156074, 1004243586, 715579643,  2472360723,
5934             140260361,  2980573153, 2698675608, 421617264,  1302961645,
5935             4099032581, 3845074044, 1557460884, 3352688782, 2116952934,
5936             1867729183, 3601371895, 2222754758, 1032278062, 754596439,
5937             2499928511, 234942117,  3086693709, 2793824052, 528319708,
5938             1274365761, 4061043881, 3816027856, 1518873912, 3246989858,
5939             2020800970, 1762628531, 3505670235, 3223196809, 2045103969,
5940             1754834200, 3512958704, 1247965674, 4086934018, 3806642299,
5941             1528765331, 261609486,  3060532198, 2802936223, 518697591,
5942             2246819181, 1007707781, 762121468,  2492913428, 213497176,
5943             3041029808, 2755593417, 499441441,  2261110843, 1061030867,
5944             776167850,  2545465922, 3274734047, 2060165687, 1807140942,
5945             3528266662, 1229724860, 4038575956, 3788156205, 1479636677,
5946             1222322711, 4045468159, 3764231046, 1504067694, 3265744756,
5947             2069664924, 1780612837, 3554288909, 2270357136, 1051278712,
5948             802445057,  2519698665, 221152243,  3033880603, 2779263586,
5949             475261322,
5950         },
5951         {
5952             0,          2926088593, 2275419491, 701019378,  3560000647,
5953             2052709654, 1402038756, 4261017717, 1930665807, 3715829470,
5954             4105419308, 1524313021, 2804077512, 155861593,  545453739,
5955             2397726522, 3861331614, 1213181711, 1636244477, 3488582252,
5956             840331801,  2625561480, 3048626042, 467584747,  2503254481,
5957             995897408,  311723186,  3170637091, 1090907478, 4016929991,
5958             3332753461, 1758288292, 390036349,  3109546732, 2426363422,
5959             1056427919, 3272488954, 1835443819, 1152258713, 3938878216,
5960             1680663602, 3393484195, 3817652561, 1306808512, 2954733749,
5961             510998820,  935169494,  2580880455, 4044899811, 1601229938,
5962             1991794816, 3637571857, 623446372,  2336332021, 2726898695,
5963             216120726,  2181814956, 744704829,  95158223,   2881711710,
5964             1446680107, 4166125498, 3516576584, 2146575065, 780072698,
5965             2148951915, 2849952665, 129384968,  4199529085, 1411853292,
5966             2112855838, 3548843663, 1567451573, 4077254692, 3670887638,
5967             1957027143, 2304517426, 657765539,  251396177,  2694091200,
5968             3361327204, 1714510325, 1341779207, 3784408214, 476611811,
5969             2986349938, 2613617024, 899690513,  3142211371, 354600634,
5970             1021997640, 2458051545, 1870338988, 3239283261, 3906682575,
5971             1186180958, 960597383,  2536053782, 3202459876, 277428597,
5972             3983589632, 1125666961, 1792074851, 3300423154, 1246892744,
5973             3829039961, 3455203243, 1671079482, 2657312335, 806080478,
5974             432241452,  3081497277, 3748049689, 1896751752, 1489409658,
5975             4138600427, 190316446,  2772397583, 2365053693, 580864876,
5976             2893360214, 35503559,   735381813,  2243795108, 2017747153,
5977             3593269568, 4293150130, 1368183843, 1560145396, 4069882981,
5978             3680356503, 1966430470, 2295112051, 648294626,  258769936,
5979             2701399425, 804156091,  2173100842, 2823706584, 103204425,
5980             4225711676, 1438101421, 2088704863, 3524758222, 3134903146,
5981             347226875,  1031468553, 2467456920, 1860935661, 3229814396,
5982             3914054286, 1193487135, 3385412645, 1738661300, 1315531078,
5983             3758225623, 502792354,  3012596019, 2589468097, 875607120,
5984             1271043721, 3853125400, 3429020650, 1644831355, 2683558414,
5985             832261023,  408158061,  3057348348, 953223622,  2528745559,
5986             3211865253, 286899508,  3974120769, 1116263632, 1799381026,
5987             3307794867, 2917509143, 59586950,   709201268,  2217549029,
5988             2043995280, 3619452161, 4269064691, 1344032866, 3740677976,
5989             1889445577, 1498812987, 4148069290, 180845535,  2762992206,
5990             2372361916, 588238637,  1921194766, 3706423967, 4112727661,
5991             1531686908, 2796705673, 148555288,  554857194,  2407195515,
5992             26248257,   2952271312, 2251333922, 676868275,  3584149702,
5993             2076793175, 1375858085, 4234771508, 2493785488, 986493953,
5994             319029491,  3178008930, 1083533591, 4009621638, 3342158964,
5995             1767759333, 3887577823, 1239362382, 1612160956, 3464433197,
5996             864482904,  2649647049, 3022443323, 441336490,  1706844275,
5997             3419730402, 3793503504, 1282724993, 2978819316, 535149925,
5998             908921239,  2554697734, 380632892,  3100077741, 2433735263,
5999             1063734222, 3265180603, 1828069930, 1161729752, 3948283721,
6000             2207997677, 770953084,  71007118,   2857626143, 1470763626,
6001             4190274555, 3490330377, 2120394392, 4035494306, 1591758899,
6002             1999168705, 3644880208, 616140069,  2328960180, 2736367686,
6003             225524183,
6004         },
6005 };
6006 
6007 // ---------------- Private Initializer Prototypes
6008 
6009 // ---------------- Private Function Prototypes
6010 
6011 // ---------------- Initializer Implementations
6012 
6013 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 initialize_flags)6014 wuffs_crc32__ieee_hasher__initialize(wuffs_crc32__ieee_hasher* self,
6015                                      size_t sizeof_star_self,
6016                                      uint64_t wuffs_version,
6017                                      uint32_t initialize_flags) {
6018   if (!self) {
6019     return wuffs_base__error__bad_receiver;
6020   }
6021   if (sizeof(*self) != sizeof_star_self) {
6022     return wuffs_base__error__bad_sizeof_receiver;
6023   }
6024   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
6025       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
6026     return wuffs_base__error__bad_wuffs_version;
6027   }
6028 
6029   if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
6030 // The whole point of this if-check is to detect an uninitialized *self.
6031 // We disable the warning on GCC. Clang-5.0 does not have this warning.
6032 #if !defined(__clang__) && defined(__GNUC__)
6033 #pragma GCC diagnostic push
6034 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
6035 #endif
6036     if (self->private_impl.magic != 0) {
6037       return wuffs_base__error__initialize_falsely_claimed_already_zeroed;
6038     }
6039 #if !defined(__clang__) && defined(__GNUC__)
6040 #pragma GCC diagnostic pop
6041 #endif
6042   } else {
6043     void* p = &(self->private_impl);
6044     size_t n = sizeof(self->private_impl);
6045     if ((initialize_flags &
6046          WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
6047       p = self;
6048       n = sizeof(*self);
6049       initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
6050     }
6051     memset(p, 0, n);
6052   }
6053 
6054   self->private_impl.magic = WUFFS_BASE__MAGIC;
6055   return NULL;
6056 }
6057 
6058 size_t  //
sizeof__wuffs_crc32__ieee_hasher()6059 sizeof__wuffs_crc32__ieee_hasher() {
6060   return sizeof(wuffs_crc32__ieee_hasher);
6061 }
6062 
6063 // ---------------- Function Implementations
6064 
6065 // -------- func crc32.ieee_hasher.update
6066 
6067 WUFFS_BASE__MAYBE_STATIC uint32_t  //
wuffs_crc32__ieee_hasher__update(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)6068 wuffs_crc32__ieee_hasher__update(wuffs_crc32__ieee_hasher* self,
6069                                  wuffs_base__slice_u8 a_x) {
6070   if (!self) {
6071     return 0;
6072   }
6073   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
6074     return 0;
6075   }
6076 
6077   uint32_t v_s = 0;
6078   wuffs_base__slice_u8 v_p = {0};
6079 
6080   v_s = (4294967295 ^ self->private_impl.f_state);
6081   {
6082     wuffs_base__slice_u8 i_slice_p = a_x;
6083     v_p = i_slice_p;
6084     v_p.len = 16;
6085     uint8_t* i_end0_p = i_slice_p.ptr + (i_slice_p.len / 32) * 32;
6086     while (v_p.ptr < i_end0_p) {
6087       v_s ^=
6088           ((((uint32_t)(v_p.ptr[0])) << 0) | (((uint32_t)(v_p.ptr[1])) << 8) |
6089            (((uint32_t)(v_p.ptr[2])) << 16) | (((uint32_t)(v_p.ptr[3])) << 24));
6090       v_s = (wuffs_crc32__ieee_table[0][v_p.ptr[15]] ^
6091              wuffs_crc32__ieee_table[1][v_p.ptr[14]] ^
6092              wuffs_crc32__ieee_table[2][v_p.ptr[13]] ^
6093              wuffs_crc32__ieee_table[3][v_p.ptr[12]] ^
6094              wuffs_crc32__ieee_table[4][v_p.ptr[11]] ^
6095              wuffs_crc32__ieee_table[5][v_p.ptr[10]] ^
6096              wuffs_crc32__ieee_table[6][v_p.ptr[9]] ^
6097              wuffs_crc32__ieee_table[7][v_p.ptr[8]] ^
6098              wuffs_crc32__ieee_table[8][v_p.ptr[7]] ^
6099              wuffs_crc32__ieee_table[9][v_p.ptr[6]] ^
6100              wuffs_crc32__ieee_table[10][v_p.ptr[5]] ^
6101              wuffs_crc32__ieee_table[11][v_p.ptr[4]] ^
6102              wuffs_crc32__ieee_table[12][(255 & (v_s >> 24))] ^
6103              wuffs_crc32__ieee_table[13][(255 & (v_s >> 16))] ^
6104              wuffs_crc32__ieee_table[14][(255 & (v_s >> 8))] ^
6105              wuffs_crc32__ieee_table[15][(255 & (v_s >> 0))]);
6106       v_p.ptr += 16;
6107       v_s ^=
6108           ((((uint32_t)(v_p.ptr[0])) << 0) | (((uint32_t)(v_p.ptr[1])) << 8) |
6109            (((uint32_t)(v_p.ptr[2])) << 16) | (((uint32_t)(v_p.ptr[3])) << 24));
6110       v_s = (wuffs_crc32__ieee_table[0][v_p.ptr[15]] ^
6111              wuffs_crc32__ieee_table[1][v_p.ptr[14]] ^
6112              wuffs_crc32__ieee_table[2][v_p.ptr[13]] ^
6113              wuffs_crc32__ieee_table[3][v_p.ptr[12]] ^
6114              wuffs_crc32__ieee_table[4][v_p.ptr[11]] ^
6115              wuffs_crc32__ieee_table[5][v_p.ptr[10]] ^
6116              wuffs_crc32__ieee_table[6][v_p.ptr[9]] ^
6117              wuffs_crc32__ieee_table[7][v_p.ptr[8]] ^
6118              wuffs_crc32__ieee_table[8][v_p.ptr[7]] ^
6119              wuffs_crc32__ieee_table[9][v_p.ptr[6]] ^
6120              wuffs_crc32__ieee_table[10][v_p.ptr[5]] ^
6121              wuffs_crc32__ieee_table[11][v_p.ptr[4]] ^
6122              wuffs_crc32__ieee_table[12][(255 & (v_s >> 24))] ^
6123              wuffs_crc32__ieee_table[13][(255 & (v_s >> 16))] ^
6124              wuffs_crc32__ieee_table[14][(255 & (v_s >> 8))] ^
6125              wuffs_crc32__ieee_table[15][(255 & (v_s >> 0))]);
6126       v_p.ptr += 16;
6127     }
6128     v_p.len = 16;
6129     uint8_t* i_end1_p = i_slice_p.ptr + (i_slice_p.len / 16) * 16;
6130     while (v_p.ptr < i_end1_p) {
6131       v_s ^=
6132           ((((uint32_t)(v_p.ptr[0])) << 0) | (((uint32_t)(v_p.ptr[1])) << 8) |
6133            (((uint32_t)(v_p.ptr[2])) << 16) | (((uint32_t)(v_p.ptr[3])) << 24));
6134       v_s = (wuffs_crc32__ieee_table[0][v_p.ptr[15]] ^
6135              wuffs_crc32__ieee_table[1][v_p.ptr[14]] ^
6136              wuffs_crc32__ieee_table[2][v_p.ptr[13]] ^
6137              wuffs_crc32__ieee_table[3][v_p.ptr[12]] ^
6138              wuffs_crc32__ieee_table[4][v_p.ptr[11]] ^
6139              wuffs_crc32__ieee_table[5][v_p.ptr[10]] ^
6140              wuffs_crc32__ieee_table[6][v_p.ptr[9]] ^
6141              wuffs_crc32__ieee_table[7][v_p.ptr[8]] ^
6142              wuffs_crc32__ieee_table[8][v_p.ptr[7]] ^
6143              wuffs_crc32__ieee_table[9][v_p.ptr[6]] ^
6144              wuffs_crc32__ieee_table[10][v_p.ptr[5]] ^
6145              wuffs_crc32__ieee_table[11][v_p.ptr[4]] ^
6146              wuffs_crc32__ieee_table[12][(255 & (v_s >> 24))] ^
6147              wuffs_crc32__ieee_table[13][(255 & (v_s >> 16))] ^
6148              wuffs_crc32__ieee_table[14][(255 & (v_s >> 8))] ^
6149              wuffs_crc32__ieee_table[15][(255 & (v_s >> 0))]);
6150       v_p.ptr += 16;
6151     }
6152     v_p.len = 1;
6153     uint8_t* i_end2_p = i_slice_p.ptr + (i_slice_p.len / 1) * 1;
6154     while (v_p.ptr < i_end2_p) {
6155       v_s =
6156           (wuffs_crc32__ieee_table[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^
6157            (v_s >> 8));
6158       v_p.ptr += 1;
6159     }
6160   }
6161   self->private_impl.f_state = (4294967295 ^ v_s);
6162   return self->private_impl.f_state;
6163 }
6164 
6165 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
6166         // defined(WUFFS_CONFIG__MODULE__CRC32)
6167 
6168 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
6169 
6170 // ---------------- Status Codes Implementations
6171 
6172 const char* wuffs_deflate__error__bad_huffman_code_over_subscribed =
6173     "#deflate: bad Huffman code (over-subscribed)";
6174 const char* wuffs_deflate__error__bad_huffman_code_under_subscribed =
6175     "#deflate: bad Huffman code (under-subscribed)";
6176 const char* wuffs_deflate__error__bad_huffman_code_length_count =
6177     "#deflate: bad Huffman code length count";
6178 const char* wuffs_deflate__error__bad_huffman_code_length_repetition =
6179     "#deflate: bad Huffman code length repetition";
6180 const char* wuffs_deflate__error__bad_huffman_code =
6181     "#deflate: bad Huffman code";
6182 const char* wuffs_deflate__error__bad_huffman_minimum_code_length =
6183     "#deflate: bad Huffman minimum code length";
6184 const char* wuffs_deflate__error__bad_block = "#deflate: bad block";
6185 const char* wuffs_deflate__error__bad_distance = "#deflate: bad distance";
6186 const char* wuffs_deflate__error__bad_distance_code_count =
6187     "#deflate: bad distance code count";
6188 const char* wuffs_deflate__error__bad_literal_length_code_count =
6189     "#deflate: bad literal/length code count";
6190 const char* wuffs_deflate__error__inconsistent_stored_block_length =
6191     "#deflate: inconsistent stored block length";
6192 const char* wuffs_deflate__error__missing_end_of_block_code =
6193     "#deflate: missing end-of-block code";
6194 const char* wuffs_deflate__error__no_huffman_codes =
6195     "#deflate: no Huffman codes";
6196 const char*
6197     wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state =
6198         "#deflate: internal error: inconsistent Huffman decoder state";
6199 const char* wuffs_deflate__error__internal_error_inconsistent_i_o =
6200     "#deflate: internal error: inconsistent I/O";
6201 const char* wuffs_deflate__error__internal_error_inconsistent_distance =
6202     "#deflate: internal error: inconsistent distance";
6203 const char* wuffs_deflate__error__internal_error_inconsistent_n_bits =
6204     "#deflate: internal error: inconsistent n_bits";
6205 
6206 // ---------------- Private Consts
6207 
6208 static const uint8_t               //
6209     wuffs_deflate__code_order[19]  //
6210     WUFFS_BASE__POTENTIALLY_UNUSED = {
6211         16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
6212 };
6213 
6214 static const uint8_t              //
6215     wuffs_deflate__reverse8[256]  //
6216     WUFFS_BASE__POTENTIALLY_UNUSED = {
6217         0,   128, 64,  192, 32,  160, 96,  224, 16,  144, 80,  208, 48,  176,
6218         112, 240, 8,   136, 72,  200, 40,  168, 104, 232, 24,  152, 88,  216,
6219         56,  184, 120, 248, 4,   132, 68,  196, 36,  164, 100, 228, 20,  148,
6220         84,  212, 52,  180, 116, 244, 12,  140, 76,  204, 44,  172, 108, 236,
6221         28,  156, 92,  220, 60,  188, 124, 252, 2,   130, 66,  194, 34,  162,
6222         98,  226, 18,  146, 82,  210, 50,  178, 114, 242, 10,  138, 74,  202,
6223         42,  170, 106, 234, 26,  154, 90,  218, 58,  186, 122, 250, 6,   134,
6224         70,  198, 38,  166, 102, 230, 22,  150, 86,  214, 54,  182, 118, 246,
6225         14,  142, 78,  206, 46,  174, 110, 238, 30,  158, 94,  222, 62,  190,
6226         126, 254, 1,   129, 65,  193, 33,  161, 97,  225, 17,  145, 81,  209,
6227         49,  177, 113, 241, 9,   137, 73,  201, 41,  169, 105, 233, 25,  153,
6228         89,  217, 57,  185, 121, 249, 5,   133, 69,  197, 37,  165, 101, 229,
6229         21,  149, 85,  213, 53,  181, 117, 245, 13,  141, 77,  205, 45,  173,
6230         109, 237, 29,  157, 93,  221, 61,  189, 125, 253, 3,   131, 67,  195,
6231         35,  163, 99,  227, 19,  147, 83,  211, 51,  179, 115, 243, 11,  139,
6232         75,  203, 43,  171, 107, 235, 27,  155, 91,  219, 59,  187, 123, 251,
6233         7,   135, 71,  199, 39,  167, 103, 231, 23,  151, 87,  215, 55,  183,
6234         119, 247, 15,  143, 79,  207, 47,  175, 111, 239, 31,  159, 95,  223,
6235         63,  191, 127, 255,
6236 };
6237 
6238 static const uint32_t                       //
6239     wuffs_deflate__lcode_magic_numbers[32]  //
6240     WUFFS_BASE__POTENTIALLY_UNUSED = {
6241         1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104,
6242         1073743360, 1073743616, 1073743888, 1073744400, 1073744912, 1073745424,
6243         1073745952, 1073746976, 1073748000, 1073749024, 1073750064, 1073752112,
6244         1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560,
6245         1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728,
6246         134217728,  134217728,
6247 };
6248 
6249 static const uint32_t                       //
6250     wuffs_deflate__dcode_magic_numbers[32]  //
6251     WUFFS_BASE__POTENTIALLY_UNUSED = {
6252         1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376,
6253         1073743904, 1073744928, 1073745968, 1073748016, 1073750080, 1073754176,
6254         1073758288, 1073766480, 1073774688, 1073791072, 1073807472, 1073840240,
6255         1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416,
6256         1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488,
6257         134217728,  134217728,
6258 };
6259 
6260 static const uint32_t                //
6261     wuffs_deflate__huffs_table_size  //
6262         WUFFS_BASE__POTENTIALLY_UNUSED = 1024;
6263 
6264 static const uint32_t                //
6265     wuffs_deflate__huffs_table_mask  //
6266         WUFFS_BASE__POTENTIALLY_UNUSED = 1023;
6267 
6268 // ---------------- Private Initializer Prototypes
6269 
6270 // ---------------- Private Function Prototypes
6271 
6272 static wuffs_base__status  //
6273 wuffs_deflate__decoder__decode_blocks(wuffs_deflate__decoder* self,
6274                                       wuffs_base__io_buffer* a_dst,
6275                                       wuffs_base__io_buffer* a_src);
6276 
6277 static wuffs_base__status  //
6278 wuffs_deflate__decoder__decode_uncompressed(wuffs_deflate__decoder* self,
6279                                             wuffs_base__io_buffer* a_dst,
6280                                             wuffs_base__io_buffer* a_src);
6281 
6282 static wuffs_base__status  //
6283 wuffs_deflate__decoder__init_fixed_huffman(wuffs_deflate__decoder* self);
6284 
6285 static wuffs_base__status  //
6286 wuffs_deflate__decoder__init_dynamic_huffman(wuffs_deflate__decoder* self,
6287                                              wuffs_base__io_buffer* a_src);
6288 
6289 static wuffs_base__status  //
6290 wuffs_deflate__decoder__init_huff(wuffs_deflate__decoder* self,
6291                                   uint32_t a_which,
6292                                   uint32_t a_n_codes0,
6293                                   uint32_t a_n_codes1,
6294                                   uint32_t a_base_symbol);
6295 
6296 static wuffs_base__status  //
6297 wuffs_deflate__decoder__decode_huffman_fast(wuffs_deflate__decoder* self,
6298                                             wuffs_base__io_buffer* a_dst,
6299                                             wuffs_base__io_buffer* a_src);
6300 
6301 static wuffs_base__status  //
6302 wuffs_deflate__decoder__decode_huffman_slow(wuffs_deflate__decoder* self,
6303                                             wuffs_base__io_buffer* a_dst,
6304                                             wuffs_base__io_buffer* a_src);
6305 
6306 // ---------------- Initializer Implementations
6307 
6308 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 initialize_flags)6309 wuffs_deflate__decoder__initialize(wuffs_deflate__decoder* self,
6310                                    size_t sizeof_star_self,
6311                                    uint64_t wuffs_version,
6312                                    uint32_t initialize_flags) {
6313   if (!self) {
6314     return wuffs_base__error__bad_receiver;
6315   }
6316   if (sizeof(*self) != sizeof_star_self) {
6317     return wuffs_base__error__bad_sizeof_receiver;
6318   }
6319   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
6320       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
6321     return wuffs_base__error__bad_wuffs_version;
6322   }
6323 
6324   if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
6325 // The whole point of this if-check is to detect an uninitialized *self.
6326 // We disable the warning on GCC. Clang-5.0 does not have this warning.
6327 #if !defined(__clang__) && defined(__GNUC__)
6328 #pragma GCC diagnostic push
6329 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
6330 #endif
6331     if (self->private_impl.magic != 0) {
6332       return wuffs_base__error__initialize_falsely_claimed_already_zeroed;
6333     }
6334 #if !defined(__clang__) && defined(__GNUC__)
6335 #pragma GCC diagnostic pop
6336 #endif
6337   } else {
6338     void* p = &(self->private_impl);
6339     size_t n = sizeof(self->private_impl);
6340     if ((initialize_flags &
6341          WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
6342       p = self;
6343       n = sizeof(*self);
6344       initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
6345     }
6346     memset(p, 0, n);
6347   }
6348 
6349   self->private_impl.magic = WUFFS_BASE__MAGIC;
6350   return NULL;
6351 }
6352 
6353 size_t  //
sizeof__wuffs_deflate__decoder()6354 sizeof__wuffs_deflate__decoder() {
6355   return sizeof(wuffs_deflate__decoder);
6356 }
6357 
6358 // ---------------- Function Implementations
6359 
6360 // -------- func deflate.decoder.workbuf_len
6361 
6362 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder * self)6363 wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder* self) {
6364   if (!self) {
6365     return wuffs_base__utility__make_range_ii_u64(0, 0);
6366   }
6367   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
6368       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
6369     return wuffs_base__utility__make_range_ii_u64(0, 0);
6370   }
6371 
6372   return wuffs_base__utility__make_range_ii_u64(1, 1);
6373 }
6374 
6375 // -------- func deflate.decoder.decode_io_writer
6376 
6377 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_deflate__decoder__decode_io_writer(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)6378 wuffs_deflate__decoder__decode_io_writer(wuffs_deflate__decoder* self,
6379                                          wuffs_base__io_buffer* a_dst,
6380                                          wuffs_base__io_buffer* a_src,
6381                                          wuffs_base__slice_u8 a_workbuf) {
6382   if (!self) {
6383     return wuffs_base__error__bad_receiver;
6384   }
6385   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
6386     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
6387                ? wuffs_base__error__disabled_by_previous_error
6388                : wuffs_base__error__initialize_not_called;
6389   }
6390   if (!a_dst || !a_src) {
6391     self->private_impl.magic = WUFFS_BASE__DISABLED;
6392     return wuffs_base__error__bad_argument;
6393   }
6394   if ((self->private_impl.active_coroutine != 0) &&
6395       (self->private_impl.active_coroutine != 1)) {
6396     self->private_impl.magic = WUFFS_BASE__DISABLED;
6397     return wuffs_base__error__interleaved_coroutine_calls;
6398   }
6399   self->private_impl.active_coroutine = 0;
6400   wuffs_base__status status = NULL;
6401 
6402   uint64_t v_mark = 0;
6403   wuffs_base__status v_status = NULL;
6404   wuffs_base__slice_u8 v_written = {0};
6405   uint64_t v_n_copied = 0;
6406   uint32_t v_already_full = 0;
6407 
6408   uint8_t* iop_a_dst = NULL;
6409   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6410   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6411   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6412   if (a_dst) {
6413     io0_a_dst = a_dst->data.ptr;
6414     io1_a_dst = io0_a_dst + a_dst->meta.wi;
6415     iop_a_dst = io1_a_dst;
6416     io2_a_dst = io0_a_dst + a_dst->data.len;
6417     if (a_dst->meta.closed) {
6418       io2_a_dst = iop_a_dst;
6419     }
6420   }
6421 
6422   uint32_t coro_susp_point = self->private_impl.p_decode_io_writer[0];
6423   if (coro_susp_point) {
6424   }
6425   switch (coro_susp_point) {
6426     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
6427 
6428     while (true) {
6429       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
6430       {
6431         if (a_dst) {
6432           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
6433         }
6434         wuffs_base__status t_0 =
6435             wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
6436         if (a_dst) {
6437           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
6438         }
6439         v_status = t_0;
6440       }
6441       if (!wuffs_base__status__is_suspension(v_status)) {
6442         status = v_status;
6443         if (wuffs_base__status__is_error(status)) {
6444           goto exit;
6445         } else if (wuffs_base__status__is_suspension(status)) {
6446           status = wuffs_base__error__cannot_return_a_suspension;
6447           goto exit;
6448         }
6449         goto ok;
6450       }
6451       v_written = wuffs_base__io__since(
6452           v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst);
6453       if (((uint64_t)(v_written.len)) >= 32768) {
6454         v_written = wuffs_base__slice_u8__suffix(v_written, 32768);
6455         wuffs_base__slice_u8__copy_from_slice(
6456             wuffs_base__make_slice_u8(self->private_data.f_history, 32768),
6457             v_written);
6458         self->private_impl.f_history_index = 32768;
6459       } else {
6460         v_n_copied = wuffs_base__slice_u8__copy_from_slice(
6461             wuffs_base__slice_u8__subslice_i(
6462                 wuffs_base__make_slice_u8(self->private_data.f_history, 32768),
6463                 (self->private_impl.f_history_index & 32767)),
6464             v_written);
6465         if (v_n_copied < ((uint64_t)(v_written.len))) {
6466           v_written = wuffs_base__slice_u8__subslice_i(v_written, v_n_copied);
6467           v_n_copied = wuffs_base__slice_u8__copy_from_slice(
6468               wuffs_base__make_slice_u8(self->private_data.f_history, 32768),
6469               v_written);
6470           self->private_impl.f_history_index =
6471               (((uint32_t)((v_n_copied & 32767))) + 32768);
6472         } else {
6473           v_already_full = 0;
6474           if (self->private_impl.f_history_index >= 32768) {
6475             v_already_full = 32768;
6476           }
6477           self->private_impl.f_history_index =
6478               ((self->private_impl.f_history_index & 32767) +
6479                ((uint32_t)((v_n_copied & 32767))) + v_already_full);
6480         }
6481       }
6482       status = v_status;
6483       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
6484     }
6485 
6486     goto ok;
6487   ok:
6488     self->private_impl.p_decode_io_writer[0] = 0;
6489     goto exit;
6490   }
6491 
6492   goto suspend;
6493 suspend:
6494   self->private_impl.p_decode_io_writer[0] =
6495       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
6496   self->private_impl.active_coroutine =
6497       wuffs_base__status__is_suspension(status) ? 1 : 0;
6498 
6499   goto exit;
6500 exit:
6501   if (a_dst) {
6502     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
6503   }
6504 
6505   if (wuffs_base__status__is_error(status)) {
6506     self->private_impl.magic = WUFFS_BASE__DISABLED;
6507   }
6508   return status;
6509 }
6510 
6511 // -------- func deflate.decoder.decode_blocks
6512 
6513 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)6514 wuffs_deflate__decoder__decode_blocks(wuffs_deflate__decoder* self,
6515                                       wuffs_base__io_buffer* a_dst,
6516                                       wuffs_base__io_buffer* a_src) {
6517   wuffs_base__status status = NULL;
6518 
6519   uint32_t v_final = 0;
6520   uint32_t v_b0 = 0;
6521   uint32_t v_type = 0;
6522   wuffs_base__status v_status = NULL;
6523 
6524   uint8_t* iop_a_src = NULL;
6525   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6526   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6527   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6528   if (a_src) {
6529     io0_a_src = a_src->data.ptr;
6530     io1_a_src = io0_a_src + a_src->meta.ri;
6531     iop_a_src = io1_a_src;
6532     io2_a_src = io0_a_src + a_src->meta.wi;
6533   }
6534 
6535   uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0];
6536   if (coro_susp_point) {
6537     v_final = self->private_data.s_decode_blocks[0].v_final;
6538   }
6539   switch (coro_susp_point) {
6540     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
6541 
6542   label_0_continue:;
6543     while (v_final == 0) {
6544       while (self->private_impl.f_n_bits < 3) {
6545         {
6546           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
6547           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
6548             status = wuffs_base__suspension__short_read;
6549             goto suspend;
6550           }
6551           uint32_t t_0 = *iop_a_src++;
6552           v_b0 = t_0;
6553         }
6554         self->private_impl.f_bits |= (v_b0 << self->private_impl.f_n_bits);
6555         self->private_impl.f_n_bits += 8;
6556       }
6557       v_final = (self->private_impl.f_bits & 1);
6558       v_type = ((self->private_impl.f_bits >> 1) & 3);
6559       self->private_impl.f_bits >>= 3;
6560       self->private_impl.f_n_bits -= 3;
6561       if (v_type == 0) {
6562         if (a_src) {
6563           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
6564         }
6565         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
6566         status =
6567             wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
6568         if (a_src) {
6569           iop_a_src = a_src->data.ptr + a_src->meta.ri;
6570         }
6571         if (status) {
6572           goto suspend;
6573         }
6574         goto label_0_continue;
6575       } else if (v_type == 1) {
6576         v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
6577         if (!wuffs_base__status__is_ok(v_status)) {
6578           status = v_status;
6579           if (wuffs_base__status__is_error(status)) {
6580             goto exit;
6581           } else if (wuffs_base__status__is_suspension(status)) {
6582             status = wuffs_base__error__cannot_return_a_suspension;
6583             goto exit;
6584           }
6585           goto ok;
6586         }
6587       } else if (v_type == 2) {
6588         if (a_src) {
6589           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
6590         }
6591         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
6592         status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
6593         if (a_src) {
6594           iop_a_src = a_src->data.ptr + a_src->meta.ri;
6595         }
6596         if (status) {
6597           goto suspend;
6598         }
6599       } else {
6600         status = wuffs_deflate__error__bad_block;
6601         goto exit;
6602       }
6603       self->private_impl.f_end_of_block = false;
6604       while (true) {
6605         if (a_src) {
6606           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
6607         }
6608         v_status =
6609             wuffs_deflate__decoder__decode_huffman_fast(self, a_dst, a_src);
6610         if (a_src) {
6611           iop_a_src = a_src->data.ptr + a_src->meta.ri;
6612         }
6613         if (wuffs_base__status__is_error(v_status)) {
6614           status = v_status;
6615           goto exit;
6616         }
6617         if (self->private_impl.f_end_of_block) {
6618           goto label_0_continue;
6619         }
6620         if (a_src) {
6621           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
6622         }
6623         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
6624         status =
6625             wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
6626         if (a_src) {
6627           iop_a_src = a_src->data.ptr + a_src->meta.ri;
6628         }
6629         if (status) {
6630           goto suspend;
6631         }
6632         if (self->private_impl.f_end_of_block) {
6633           goto label_0_continue;
6634         }
6635       }
6636     }
6637 
6638     goto ok;
6639   ok:
6640     self->private_impl.p_decode_blocks[0] = 0;
6641     goto exit;
6642   }
6643 
6644   goto suspend;
6645 suspend:
6646   self->private_impl.p_decode_blocks[0] =
6647       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
6648   self->private_data.s_decode_blocks[0].v_final = v_final;
6649 
6650   goto exit;
6651 exit:
6652   if (a_src) {
6653     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
6654   }
6655 
6656   return status;
6657 }
6658 
6659 // -------- func deflate.decoder.decode_uncompressed
6660 
6661 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)6662 wuffs_deflate__decoder__decode_uncompressed(wuffs_deflate__decoder* self,
6663                                             wuffs_base__io_buffer* a_dst,
6664                                             wuffs_base__io_buffer* a_src) {
6665   wuffs_base__status status = NULL;
6666 
6667   uint32_t v_length = 0;
6668   uint32_t v_n_copied = 0;
6669 
6670   uint8_t* iop_a_dst = NULL;
6671   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6672   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6673   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6674   if (a_dst) {
6675     io0_a_dst = a_dst->data.ptr;
6676     io1_a_dst = io0_a_dst + a_dst->meta.wi;
6677     iop_a_dst = io1_a_dst;
6678     io2_a_dst = io0_a_dst + a_dst->data.len;
6679     if (a_dst->meta.closed) {
6680       io2_a_dst = iop_a_dst;
6681     }
6682   }
6683   uint8_t* iop_a_src = NULL;
6684   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6685   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6686   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6687   if (a_src) {
6688     io0_a_src = a_src->data.ptr;
6689     io1_a_src = io0_a_src + a_src->meta.ri;
6690     iop_a_src = io1_a_src;
6691     io2_a_src = io0_a_src + a_src->meta.wi;
6692   }
6693 
6694   uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0];
6695   if (coro_susp_point) {
6696     v_length = self->private_data.s_decode_uncompressed[0].v_length;
6697   }
6698   switch (coro_susp_point) {
6699     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
6700 
6701     if ((self->private_impl.f_n_bits >= 8) ||
6702         ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) !=
6703          0)) {
6704       status = wuffs_deflate__error__internal_error_inconsistent_n_bits;
6705       goto exit;
6706     }
6707     self->private_impl.f_n_bits = 0;
6708     self->private_impl.f_bits = 0;
6709     {
6710       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
6711       uint32_t t_0;
6712       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
6713         t_0 = wuffs_base__load_u32le(iop_a_src);
6714         iop_a_src += 4;
6715       } else {
6716         self->private_data.s_decode_uncompressed[0].scratch = 0;
6717         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
6718         while (true) {
6719           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
6720             status = wuffs_base__suspension__short_read;
6721             goto suspend;
6722           }
6723           uint64_t* scratch =
6724               &self->private_data.s_decode_uncompressed[0].scratch;
6725           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
6726           *scratch <<= 8;
6727           *scratch >>= 8;
6728           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
6729           if (num_bits_0 == 24) {
6730             t_0 = ((uint32_t)(*scratch));
6731             break;
6732           }
6733           num_bits_0 += 8;
6734           *scratch |= ((uint64_t)(num_bits_0)) << 56;
6735         }
6736       }
6737       v_length = t_0;
6738     }
6739     if ((((v_length)&0xFFFF) + ((v_length) >> (32 - (16)))) != 65535) {
6740       status = wuffs_deflate__error__inconsistent_stored_block_length;
6741       goto exit;
6742     }
6743     v_length = ((v_length)&0xFFFF);
6744     while (true) {
6745       v_n_copied = wuffs_base__io_writer__copy_n_from_reader(
6746           &iop_a_dst, io2_a_dst, v_length, &iop_a_src, io2_a_src);
6747       if (v_length <= v_n_copied) {
6748         status = NULL;
6749         goto ok;
6750       }
6751       v_length -= v_n_copied;
6752       if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0) {
6753         status = wuffs_base__suspension__short_write;
6754         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
6755       } else {
6756         status = wuffs_base__suspension__short_read;
6757         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
6758       }
6759     }
6760 
6761     goto ok;
6762   ok:
6763     self->private_impl.p_decode_uncompressed[0] = 0;
6764     goto exit;
6765   }
6766 
6767   goto suspend;
6768 suspend:
6769   self->private_impl.p_decode_uncompressed[0] =
6770       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
6771   self->private_data.s_decode_uncompressed[0].v_length = v_length;
6772 
6773   goto exit;
6774 exit:
6775   if (a_dst) {
6776     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
6777   }
6778   if (a_src) {
6779     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
6780   }
6781 
6782   return status;
6783 }
6784 
6785 // -------- func deflate.decoder.init_fixed_huffman
6786 
6787 static wuffs_base__status  //
wuffs_deflate__decoder__init_fixed_huffman(wuffs_deflate__decoder * self)6788 wuffs_deflate__decoder__init_fixed_huffman(wuffs_deflate__decoder* self) {
6789   uint32_t v_i = 0;
6790   wuffs_base__status v_status = NULL;
6791 
6792   while (v_i < 144) {
6793     self->private_data.f_code_lengths[v_i] = 8;
6794     v_i += 1;
6795   }
6796   while (v_i < 256) {
6797     self->private_data.f_code_lengths[v_i] = 9;
6798     v_i += 1;
6799   }
6800   while (v_i < 280) {
6801     self->private_data.f_code_lengths[v_i] = 7;
6802     v_i += 1;
6803   }
6804   while (v_i < 288) {
6805     self->private_data.f_code_lengths[v_i] = 8;
6806     v_i += 1;
6807   }
6808   while (v_i < 320) {
6809     self->private_data.f_code_lengths[v_i] = 5;
6810     v_i += 1;
6811   }
6812   v_status = wuffs_deflate__decoder__init_huff(self, 0, 0, 288, 257);
6813   if (wuffs_base__status__is_error(v_status)) {
6814     return v_status;
6815   }
6816   v_status = wuffs_deflate__decoder__init_huff(self, 1, 288, 320, 0);
6817   if (wuffs_base__status__is_error(v_status)) {
6818     return v_status;
6819   }
6820   return NULL;
6821 }
6822 
6823 // -------- func deflate.decoder.init_dynamic_huffman
6824 
6825 static wuffs_base__status  //
wuffs_deflate__decoder__init_dynamic_huffman(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_src)6826 wuffs_deflate__decoder__init_dynamic_huffman(wuffs_deflate__decoder* self,
6827                                              wuffs_base__io_buffer* a_src) {
6828   wuffs_base__status status = NULL;
6829 
6830   uint32_t v_bits = 0;
6831   uint32_t v_n_bits = 0;
6832   uint32_t v_b0 = 0;
6833   uint32_t v_n_lit = 0;
6834   uint32_t v_n_dist = 0;
6835   uint32_t v_n_clen = 0;
6836   uint32_t v_i = 0;
6837   uint32_t v_b1 = 0;
6838   wuffs_base__status v_status = NULL;
6839   uint32_t v_mask = 0;
6840   uint32_t v_table_entry = 0;
6841   uint32_t v_table_entry_n_bits = 0;
6842   uint32_t v_b2 = 0;
6843   uint32_t v_n_extra_bits = 0;
6844   uint8_t v_rep_symbol = 0;
6845   uint32_t v_rep_count = 0;
6846   uint32_t v_b3 = 0;
6847 
6848   uint8_t* iop_a_src = NULL;
6849   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6850   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6851   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
6852   if (a_src) {
6853     io0_a_src = a_src->data.ptr;
6854     io1_a_src = io0_a_src + a_src->meta.ri;
6855     iop_a_src = io1_a_src;
6856     io2_a_src = io0_a_src + a_src->meta.wi;
6857   }
6858 
6859   uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0];
6860   if (coro_susp_point) {
6861     v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits;
6862     v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits;
6863     v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit;
6864     v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist;
6865     v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen;
6866     v_i = self->private_data.s_init_dynamic_huffman[0].v_i;
6867     v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask;
6868     v_table_entry = self->private_data.s_init_dynamic_huffman[0].v_table_entry;
6869     v_n_extra_bits =
6870         self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits;
6871     v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol;
6872     v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count;
6873   }
6874   switch (coro_susp_point) {
6875     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
6876 
6877     v_bits = self->private_impl.f_bits;
6878     v_n_bits = self->private_impl.f_n_bits;
6879     while (v_n_bits < 14) {
6880       {
6881         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
6882         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
6883           status = wuffs_base__suspension__short_read;
6884           goto suspend;
6885         }
6886         uint32_t t_0 = *iop_a_src++;
6887         v_b0 = t_0;
6888       }
6889       v_bits |= (v_b0 << v_n_bits);
6890       v_n_bits += 8;
6891     }
6892     v_n_lit = (((v_bits)&0x1F) + 257);
6893     if (v_n_lit > 286) {
6894       status = wuffs_deflate__error__bad_literal_length_code_count;
6895       goto exit;
6896     }
6897     v_bits >>= 5;
6898     v_n_dist = (((v_bits)&0x1F) + 1);
6899     if (v_n_dist > 30) {
6900       status = wuffs_deflate__error__bad_distance_code_count;
6901       goto exit;
6902     }
6903     v_bits >>= 5;
6904     v_n_clen = (((v_bits)&0xF) + 4);
6905     v_bits >>= 4;
6906     v_n_bits -= 14;
6907     v_i = 0;
6908     while (v_i < v_n_clen) {
6909       while (v_n_bits < 3) {
6910         {
6911           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
6912           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
6913             status = wuffs_base__suspension__short_read;
6914             goto suspend;
6915           }
6916           uint32_t t_1 = *iop_a_src++;
6917           v_b1 = t_1;
6918         }
6919         v_bits |= (v_b1 << v_n_bits);
6920         v_n_bits += 8;
6921       }
6922       self->private_data.f_code_lengths[wuffs_deflate__code_order[v_i]] =
6923           ((uint8_t)((v_bits & 7)));
6924       v_bits >>= 3;
6925       v_n_bits -= 3;
6926       v_i += 1;
6927     }
6928     while (v_i < 19) {
6929       self->private_data.f_code_lengths[wuffs_deflate__code_order[v_i]] = 0;
6930       v_i += 1;
6931     }
6932     v_status = wuffs_deflate__decoder__init_huff(self, 0, 0, 19, 4095);
6933     if (wuffs_base__status__is_error(v_status)) {
6934       status = v_status;
6935       goto exit;
6936     }
6937     v_mask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
6938     v_i = 0;
6939   label_0_continue:;
6940     while (v_i < (v_n_lit + v_n_dist)) {
6941       while (true) {
6942         v_table_entry = self->private_data.f_huffs[0][(v_bits & v_mask)];
6943         v_table_entry_n_bits = (v_table_entry & 15);
6944         if (v_n_bits >= v_table_entry_n_bits) {
6945           v_bits >>= v_table_entry_n_bits;
6946           v_n_bits -= v_table_entry_n_bits;
6947           goto label_1_break;
6948         }
6949         {
6950           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
6951           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
6952             status = wuffs_base__suspension__short_read;
6953             goto suspend;
6954           }
6955           uint32_t t_2 = *iop_a_src++;
6956           v_b2 = t_2;
6957         }
6958         v_bits |= (v_b2 << v_n_bits);
6959         v_n_bits += 8;
6960       }
6961     label_1_break:;
6962       if ((v_table_entry >> 24) != 128) {
6963         status =
6964             wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
6965         goto exit;
6966       }
6967       v_table_entry = ((v_table_entry >> 8) & 255);
6968       if (v_table_entry < 16) {
6969         self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
6970         v_i += 1;
6971         goto label_0_continue;
6972       }
6973       v_n_extra_bits = 0;
6974       v_rep_symbol = 0;
6975       v_rep_count = 0;
6976       if (v_table_entry == 16) {
6977         v_n_extra_bits = 2;
6978         if (v_i <= 0) {
6979           status = wuffs_deflate__error__bad_huffman_code_length_repetition;
6980           goto exit;
6981         }
6982         v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1)] & 15);
6983         v_rep_count = 3;
6984       } else if (v_table_entry == 17) {
6985         v_n_extra_bits = 3;
6986         v_rep_symbol = 0;
6987         v_rep_count = 3;
6988       } else if (v_table_entry == 18) {
6989         v_n_extra_bits = 7;
6990         v_rep_symbol = 0;
6991         v_rep_count = 11;
6992       } else {
6993         status =
6994             wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
6995         goto exit;
6996       }
6997       while (v_n_bits < v_n_extra_bits) {
6998         {
6999           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
7000           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
7001             status = wuffs_base__suspension__short_read;
7002             goto suspend;
7003           }
7004           uint32_t t_3 = *iop_a_src++;
7005           v_b3 = t_3;
7006         }
7007         v_bits |= (v_b3 << v_n_bits);
7008         v_n_bits += 8;
7009       }
7010       v_rep_count += ((v_bits)&WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits));
7011       v_bits >>= v_n_extra_bits;
7012       v_n_bits -= v_n_extra_bits;
7013       while (v_rep_count > 0) {
7014         if (v_i >= (v_n_lit + v_n_dist)) {
7015           status = wuffs_deflate__error__bad_huffman_code_length_count;
7016           goto exit;
7017         }
7018         self->private_data.f_code_lengths[v_i] = v_rep_symbol;
7019         v_i += 1;
7020         v_rep_count -= 1;
7021       }
7022     }
7023     if (v_i != (v_n_lit + v_n_dist)) {
7024       status = wuffs_deflate__error__bad_huffman_code_length_count;
7025       goto exit;
7026     }
7027     if (self->private_data.f_code_lengths[256] == 0) {
7028       status = wuffs_deflate__error__missing_end_of_block_code;
7029       goto exit;
7030     }
7031     v_status = wuffs_deflate__decoder__init_huff(self, 0, 0, v_n_lit, 257);
7032     if (wuffs_base__status__is_error(v_status)) {
7033       status = v_status;
7034       goto exit;
7035     }
7036     v_status = wuffs_deflate__decoder__init_huff(self, 1, v_n_lit,
7037                                                  (v_n_lit + v_n_dist), 0);
7038     if (wuffs_base__status__is_error(v_status)) {
7039       status = v_status;
7040       goto exit;
7041     }
7042     self->private_impl.f_bits = v_bits;
7043     self->private_impl.f_n_bits = v_n_bits;
7044 
7045     goto ok;
7046   ok:
7047     self->private_impl.p_init_dynamic_huffman[0] = 0;
7048     goto exit;
7049   }
7050 
7051   goto suspend;
7052 suspend:
7053   self->private_impl.p_init_dynamic_huffman[0] =
7054       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
7055   self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits;
7056   self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits;
7057   self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit;
7058   self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist;
7059   self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen;
7060   self->private_data.s_init_dynamic_huffman[0].v_i = v_i;
7061   self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask;
7062   self->private_data.s_init_dynamic_huffman[0].v_table_entry = v_table_entry;
7063   self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits;
7064   self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol;
7065   self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count;
7066 
7067   goto exit;
7068 exit:
7069   if (a_src) {
7070     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
7071   }
7072 
7073   return status;
7074 }
7075 
7076 // -------- func deflate.decoder.init_huff
7077 
7078 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)7079 wuffs_deflate__decoder__init_huff(wuffs_deflate__decoder* self,
7080                                   uint32_t a_which,
7081                                   uint32_t a_n_codes0,
7082                                   uint32_t a_n_codes1,
7083                                   uint32_t a_base_symbol) {
7084   uint16_t v_counts[16] = {0};
7085   uint32_t v_i = 0;
7086   uint32_t v_remaining = 0;
7087   uint16_t v_offsets[16] = {0};
7088   uint32_t v_n_symbols = 0;
7089   uint32_t v_count = 0;
7090   uint16_t v_symbols[320] = {0};
7091   uint32_t v_min_cl = 0;
7092   uint32_t v_max_cl = 0;
7093   uint32_t v_initial_high_bits = 0;
7094   uint32_t v_prev_cl = 0;
7095   uint32_t v_prev_redirect_key = 0;
7096   uint32_t v_top = 0;
7097   uint32_t v_next_top = 0;
7098   uint32_t v_code = 0;
7099   uint32_t v_key = 0;
7100   uint32_t v_value = 0;
7101   uint32_t v_cl = 0;
7102   uint32_t v_redirect_key = 0;
7103   uint32_t v_j = 0;
7104   uint32_t v_reversed_key = 0;
7105   uint32_t v_symbol = 0;
7106   uint32_t v_high_bits = 0;
7107   uint32_t v_delta = 0;
7108 
7109   v_i = a_n_codes0;
7110   while (v_i < a_n_codes1) {
7111     if (v_counts[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
7112       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7113     }
7114 #if defined(__GNUC__)
7115 #pragma GCC diagnostic push
7116 #pragma GCC diagnostic ignored "-Wconversion"
7117 #endif
7118     v_counts[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
7119 #if defined(__GNUC__)
7120 #pragma GCC diagnostic pop
7121 #endif
7122     v_i += 1;
7123   }
7124   if ((((uint32_t)(v_counts[0])) + a_n_codes0) == a_n_codes1) {
7125     return wuffs_deflate__error__no_huffman_codes;
7126   }
7127   v_remaining = 1;
7128   v_i = 1;
7129   while (v_i <= 15) {
7130     if (v_remaining > 1073741824) {
7131       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7132     }
7133     v_remaining <<= 1;
7134     if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
7135       return wuffs_deflate__error__bad_huffman_code_over_subscribed;
7136     }
7137     v_remaining -= ((uint32_t)(v_counts[v_i]));
7138     v_i += 1;
7139   }
7140   if (v_remaining != 0) {
7141     return wuffs_deflate__error__bad_huffman_code_under_subscribed;
7142   }
7143   v_i = 1;
7144   while (v_i <= 15) {
7145     v_offsets[v_i] = ((uint16_t)(v_n_symbols));
7146     v_count = ((uint32_t)(v_counts[v_i]));
7147     if (v_n_symbols > (320 - v_count)) {
7148       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7149     }
7150     v_n_symbols = (v_n_symbols + v_count);
7151     v_i += 1;
7152   }
7153   if (v_n_symbols > 288) {
7154     return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7155   }
7156   v_i = a_n_codes0;
7157   while (v_i < a_n_codes1) {
7158     if (v_i < a_n_codes0) {
7159       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7160     }
7161     if (self->private_data.f_code_lengths[v_i] != 0) {
7162       if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
7163         return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7164       }
7165       v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15)]] =
7166           ((uint16_t)((v_i - a_n_codes0)));
7167 #if defined(__GNUC__)
7168 #pragma GCC diagnostic push
7169 #pragma GCC diagnostic ignored "-Wconversion"
7170 #endif
7171       v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
7172 #if defined(__GNUC__)
7173 #pragma GCC diagnostic pop
7174 #endif
7175     }
7176     v_i += 1;
7177   }
7178   v_min_cl = 1;
7179   while (true) {
7180     if (v_counts[v_min_cl] != 0) {
7181       goto label_0_break;
7182     }
7183     if (v_min_cl >= 9) {
7184       return wuffs_deflate__error__bad_huffman_minimum_code_length;
7185     }
7186     v_min_cl += 1;
7187   }
7188 label_0_break:;
7189   v_max_cl = 15;
7190   while (true) {
7191     if (v_counts[v_max_cl] != 0) {
7192       goto label_1_break;
7193     }
7194     if (v_max_cl <= 1) {
7195       return wuffs_deflate__error__no_huffman_codes;
7196     }
7197     v_max_cl -= 1;
7198   }
7199 label_1_break:;
7200   if (v_max_cl <= 9) {
7201     self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
7202   } else {
7203     self->private_impl.f_n_huffs_bits[a_which] = 9;
7204   }
7205   v_i = 0;
7206   if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) ||
7207       (v_n_symbols != ((uint32_t)(v_offsets[15])))) {
7208     return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7209   }
7210   if ((a_n_codes0 + ((uint32_t)(v_symbols[0]))) >= 320) {
7211     return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7212   }
7213   v_initial_high_bits = 512;
7214   if (v_max_cl < 9) {
7215     v_initial_high_bits = (((uint32_t)(1)) << v_max_cl);
7216   }
7217   v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(
7218                                a_n_codes0 + ((uint32_t)(v_symbols[0])))] &
7219                            15)));
7220   v_prev_redirect_key = 4294967295;
7221   v_top = 0;
7222   v_next_top = 512;
7223   v_code = 0;
7224   v_key = 0;
7225   v_value = 0;
7226   while (true) {
7227     if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320) {
7228       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7229     }
7230     v_cl = ((uint32_t)((self->private_data.f_code_lengths[(
7231                             a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] &
7232                         15)));
7233     if (v_cl > v_prev_cl) {
7234       v_code <<= (v_cl - v_prev_cl);
7235       if (v_code >= 32768) {
7236         return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7237       }
7238     }
7239     v_prev_cl = v_cl;
7240     v_key = v_code;
7241     if (v_cl > 9) {
7242       v_cl -= 9;
7243       v_redirect_key = ((v_key >> v_cl) & 511);
7244       v_key = ((v_key)&WUFFS_BASE__LOW_BITS_MASK__U32(v_cl));
7245       if (v_prev_redirect_key != v_redirect_key) {
7246         v_prev_redirect_key = v_redirect_key;
7247         v_remaining = (((uint32_t)(1)) << v_cl);
7248         v_j = v_prev_cl;
7249         while (v_j <= 15) {
7250           if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
7251             goto label_2_break;
7252           }
7253           v_remaining -= ((uint32_t)(v_counts[v_j]));
7254           if (v_remaining > 1073741824) {
7255             return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7256           }
7257           v_remaining <<= 1;
7258           v_j += 1;
7259         }
7260       label_2_break:;
7261         if ((v_j <= 9) || (15 < v_j)) {
7262           return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7263         }
7264         v_j -= 9;
7265         v_initial_high_bits = (((uint32_t)(1)) << v_j);
7266         v_top = v_next_top;
7267         if ((v_top + (((uint32_t)(1)) << v_j)) > 1024) {
7268           return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7269         }
7270         v_next_top = (v_top + (((uint32_t)(1)) << v_j));
7271         v_redirect_key =
7272             (((uint32_t)(wuffs_deflate__reverse8[(v_redirect_key >> 1)])) |
7273              ((v_redirect_key & 1) << 8));
7274         self->private_data.f_huffs[a_which][v_redirect_key] =
7275             (268435465 | (v_top << 8) | (v_j << 4));
7276       }
7277     }
7278     if ((v_key >= 512) || (v_counts[v_prev_cl] <= 0)) {
7279       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7280     }
7281 #if defined(__GNUC__)
7282 #pragma GCC diagnostic push
7283 #pragma GCC diagnostic ignored "-Wconversion"
7284 #endif
7285     v_counts[v_prev_cl] -= 1;
7286 #if defined(__GNUC__)
7287 #pragma GCC diagnostic pop
7288 #endif
7289     v_reversed_key = (((uint32_t)(wuffs_deflate__reverse8[(v_key >> 1)])) |
7290                       ((v_key & 1) << 8));
7291     v_reversed_key >>= (9 - v_cl);
7292     v_symbol = ((uint32_t)(v_symbols[v_i]));
7293     if (v_symbol == 256) {
7294       v_value = (536870912 | v_cl);
7295     } else if ((v_symbol < 256) && (a_which == 0)) {
7296       v_value = (2147483648 | (v_symbol << 8) | v_cl);
7297     } else if (v_symbol >= a_base_symbol) {
7298       v_symbol -= a_base_symbol;
7299       if (a_which == 0) {
7300         v_value = (wuffs_deflate__lcode_magic_numbers[(v_symbol & 31)] | v_cl);
7301       } else {
7302         v_value = (wuffs_deflate__dcode_magic_numbers[(v_symbol & 31)] | v_cl);
7303       }
7304     } else {
7305       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7306     }
7307     v_high_bits = v_initial_high_bits;
7308     v_delta = (((uint32_t)(1)) << v_cl);
7309     while (v_high_bits >= v_delta) {
7310       v_high_bits -= v_delta;
7311       if ((v_top + ((v_high_bits | v_reversed_key) & 511)) >= 1024) {
7312         return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7313       }
7314       self->private_data
7315           .f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511))] =
7316           v_value;
7317     }
7318     v_i += 1;
7319     if (v_i >= v_n_symbols) {
7320       goto label_3_break;
7321     }
7322     v_code += 1;
7323     if (v_code >= 32768) {
7324       return wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7325     }
7326   }
7327 label_3_break:;
7328   return NULL;
7329 }
7330 
7331 // -------- func deflate.decoder.decode_huffman_fast
7332 
7333 static wuffs_base__status  //
wuffs_deflate__decoder__decode_huffman_fast(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)7334 wuffs_deflate__decoder__decode_huffman_fast(wuffs_deflate__decoder* self,
7335                                             wuffs_base__io_buffer* a_dst,
7336                                             wuffs_base__io_buffer* a_src) {
7337   wuffs_base__status status = NULL;
7338 
7339   uint32_t v_bits = 0;
7340   uint32_t v_n_bits = 0;
7341   uint32_t v_table_entry = 0;
7342   uint32_t v_table_entry_n_bits = 0;
7343   uint32_t v_lmask = 0;
7344   uint32_t v_dmask = 0;
7345   uint32_t v_redir_top = 0;
7346   uint32_t v_redir_mask = 0;
7347   uint32_t v_length = 0;
7348   uint32_t v_dist_minus_1 = 0;
7349   uint32_t v_n_copied = 0;
7350   uint32_t v_hlen = 0;
7351   uint32_t v_hdist = 0;
7352 
7353   uint8_t* iop_a_dst = NULL;
7354   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7355   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7356   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7357   if (a_dst) {
7358     io0_a_dst = a_dst->data.ptr;
7359     io1_a_dst = io0_a_dst + a_dst->meta.wi;
7360     iop_a_dst = io1_a_dst;
7361     io2_a_dst = io0_a_dst + a_dst->data.len;
7362     if (a_dst->meta.closed) {
7363       io2_a_dst = iop_a_dst;
7364     }
7365   }
7366   uint8_t* iop_a_src = NULL;
7367   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7368   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7369   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7370   if (a_src) {
7371     io0_a_src = a_src->data.ptr;
7372     io1_a_src = io0_a_src + a_src->meta.ri;
7373     iop_a_src = io1_a_src;
7374     io2_a_src = io0_a_src + a_src->meta.wi;
7375   }
7376 
7377   if ((self->private_impl.f_n_bits >= 8) ||
7378       ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
7379     status = wuffs_deflate__error__internal_error_inconsistent_n_bits;
7380     goto exit;
7381   }
7382   v_bits = self->private_impl.f_bits;
7383   v_n_bits = self->private_impl.f_n_bits;
7384   v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
7385   v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
7386 label_0_continue:;
7387   while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 258) &&
7388          (((uint64_t)(io2_a_src - iop_a_src)) >= 12)) {
7389     if (v_n_bits < 15) {
7390       v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7391       (iop_a_src += 1, wuffs_base__make_empty_struct());
7392       v_n_bits += 8;
7393       v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7394       (iop_a_src += 1, wuffs_base__make_empty_struct());
7395       v_n_bits += 8;
7396     } else {
7397     }
7398     v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
7399     v_table_entry_n_bits = (v_table_entry & 15);
7400     v_bits >>= v_table_entry_n_bits;
7401     v_n_bits -= v_table_entry_n_bits;
7402     if ((v_table_entry >> 31) != 0) {
7403       (wuffs_base__store_u8be(iop_a_dst,
7404                               ((uint8_t)(((v_table_entry >> 8) & 255)))),
7405        iop_a_dst += 1, wuffs_base__make_empty_struct());
7406       goto label_0_continue;
7407     } else if ((v_table_entry >> 30) != 0) {
7408     } else if ((v_table_entry >> 29) != 0) {
7409       self->private_impl.f_end_of_block = true;
7410       goto label_0_break;
7411     } else if ((v_table_entry >> 28) != 0) {
7412       if (v_n_bits < 15) {
7413         v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7414         (iop_a_src += 1, wuffs_base__make_empty_struct());
7415         v_n_bits += 8;
7416         v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7417         (iop_a_src += 1, wuffs_base__make_empty_struct());
7418         v_n_bits += 8;
7419       } else {
7420       }
7421       v_redir_top = ((v_table_entry >> 8) & 65535);
7422       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
7423       v_table_entry =
7424           self->private_data
7425               .f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
7426       v_table_entry_n_bits = (v_table_entry & 15);
7427       v_bits >>= v_table_entry_n_bits;
7428       v_n_bits -= v_table_entry_n_bits;
7429       if ((v_table_entry >> 31) != 0) {
7430         (wuffs_base__store_u8be(iop_a_dst,
7431                                 ((uint8_t)(((v_table_entry >> 8) & 255)))),
7432          iop_a_dst += 1, wuffs_base__make_empty_struct());
7433         goto label_0_continue;
7434       } else if ((v_table_entry >> 30) != 0) {
7435       } else if ((v_table_entry >> 29) != 0) {
7436         self->private_impl.f_end_of_block = true;
7437         goto label_0_break;
7438       } else if ((v_table_entry >> 28) != 0) {
7439         status =
7440             wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7441         goto exit;
7442       } else if ((v_table_entry >> 27) != 0) {
7443         status = wuffs_deflate__error__bad_huffman_code;
7444         goto exit;
7445       } else {
7446         status =
7447             wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7448         goto exit;
7449       }
7450     } else if ((v_table_entry >> 27) != 0) {
7451       status = wuffs_deflate__error__bad_huffman_code;
7452       goto exit;
7453     } else {
7454       status =
7455           wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7456       goto exit;
7457     }
7458     v_length = (((v_table_entry >> 8) & 255) + 3);
7459     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
7460     if (v_table_entry_n_bits > 0) {
7461       if (v_n_bits < 15) {
7462         v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7463         (iop_a_src += 1, wuffs_base__make_empty_struct());
7464         v_n_bits += 8;
7465         v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7466         (iop_a_src += 1, wuffs_base__make_empty_struct());
7467         v_n_bits += 8;
7468       } else {
7469       }
7470       v_length =
7471           (((v_length + 253 +
7472              ((v_bits)&WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) &
7473             255) +
7474            3);
7475       v_bits >>= v_table_entry_n_bits;
7476       v_n_bits -= v_table_entry_n_bits;
7477     } else {
7478     }
7479     if (v_n_bits < 15) {
7480       v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7481       (iop_a_src += 1, wuffs_base__make_empty_struct());
7482       v_n_bits += 8;
7483       v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7484       (iop_a_src += 1, wuffs_base__make_empty_struct());
7485       v_n_bits += 8;
7486     } else {
7487     }
7488     v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
7489     v_table_entry_n_bits = (v_table_entry & 15);
7490     v_bits >>= v_table_entry_n_bits;
7491     v_n_bits -= v_table_entry_n_bits;
7492     if ((v_table_entry >> 28) == 1) {
7493       if (v_n_bits < 15) {
7494         v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7495         (iop_a_src += 1, wuffs_base__make_empty_struct());
7496         v_n_bits += 8;
7497         v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7498         (iop_a_src += 1, wuffs_base__make_empty_struct());
7499         v_n_bits += 8;
7500       } else {
7501       }
7502       v_redir_top = ((v_table_entry >> 8) & 65535);
7503       v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
7504       v_table_entry =
7505           self->private_data
7506               .f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
7507       v_table_entry_n_bits = (v_table_entry & 15);
7508       v_bits >>= v_table_entry_n_bits;
7509       v_n_bits -= v_table_entry_n_bits;
7510     } else {
7511     }
7512     if ((v_table_entry >> 24) != 64) {
7513       if ((v_table_entry >> 24) == 8) {
7514         status = wuffs_deflate__error__bad_huffman_code;
7515         goto exit;
7516       }
7517       status =
7518           wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7519       goto exit;
7520     }
7521     v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
7522     v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
7523     if (v_n_bits < v_table_entry_n_bits) {
7524       v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7525       (iop_a_src += 1, wuffs_base__make_empty_struct());
7526       v_n_bits += 8;
7527       v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
7528       (iop_a_src += 1, wuffs_base__make_empty_struct());
7529       v_n_bits += 8;
7530     }
7531     v_dist_minus_1 =
7532         ((v_dist_minus_1 +
7533           ((v_bits)&WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) &
7534          32767);
7535     v_bits >>= v_table_entry_n_bits;
7536     v_n_bits -= v_table_entry_n_bits;
7537     v_n_copied = 0;
7538     while (true) {
7539       if (((uint64_t)((v_dist_minus_1 + 1))) >
7540           ((uint64_t)(iop_a_dst - a_dst->data.ptr))) {
7541         v_hlen = 0;
7542         v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) -
7543                                ((uint64_t)(iop_a_dst - a_dst->data.ptr)))));
7544         if (v_length > v_hdist) {
7545           v_length -= v_hdist;
7546           v_hlen = v_hdist;
7547         } else {
7548           v_hlen = v_length;
7549           v_length = 0;
7550         }
7551         if (self->private_impl.f_history_index < v_hdist) {
7552           status = wuffs_deflate__error__bad_distance;
7553           goto exit;
7554         }
7555         v_hdist = (self->private_impl.f_history_index - v_hdist);
7556         while (true) {
7557           v_n_copied = wuffs_base__io_writer__copy_n_from_slice(
7558               &iop_a_dst, io2_a_dst, v_hlen,
7559               wuffs_base__slice_u8__subslice_i(
7560                   wuffs_base__make_slice_u8(self->private_data.f_history,
7561                                             32768),
7562                   (v_hdist & 32767)));
7563           if (v_hlen <= v_n_copied) {
7564             goto label_1_break;
7565           }
7566           v_hlen -= v_n_copied;
7567           wuffs_base__io_writer__copy_n_from_slice(
7568               &iop_a_dst, io2_a_dst, v_hlen,
7569               wuffs_base__make_slice_u8(self->private_data.f_history, 32768));
7570           goto label_1_break;
7571         }
7572       label_1_break:;
7573         if (v_length == 0) {
7574           goto label_0_continue;
7575         }
7576         if (((uint64_t)((v_dist_minus_1 + 1))) >
7577             ((uint64_t)(iop_a_dst - a_dst->data.ptr))) {
7578           status = wuffs_deflate__error__internal_error_inconsistent_distance;
7579           goto exit;
7580         }
7581       }
7582       wuffs_base__io_writer__copy_n_from_history_fast(
7583           &iop_a_dst, a_dst->data.ptr, io2_a_dst, v_length,
7584           (v_dist_minus_1 + 1));
7585       goto label_2_break;
7586     }
7587   label_2_break:;
7588   }
7589 label_0_break:;
7590   while (v_n_bits >= 8) {
7591     v_n_bits -= 8;
7592     if (iop_a_src > io1_a_src) {
7593       (iop_a_src--, wuffs_base__make_empty_struct());
7594     } else {
7595       status = wuffs_deflate__error__internal_error_inconsistent_i_o;
7596       goto exit;
7597     }
7598   }
7599   self->private_impl.f_bits = (v_bits & ((((uint32_t)(1)) << v_n_bits) - 1));
7600   self->private_impl.f_n_bits = v_n_bits;
7601   if ((self->private_impl.f_n_bits >= 8) ||
7602       ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
7603     status = wuffs_deflate__error__internal_error_inconsistent_n_bits;
7604     goto exit;
7605   }
7606   goto exit;
7607 exit:
7608   if (a_dst) {
7609     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
7610   }
7611   if (a_src) {
7612     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
7613   }
7614 
7615   return status;
7616 }
7617 
7618 // -------- func deflate.decoder.decode_huffman_slow
7619 
7620 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)7621 wuffs_deflate__decoder__decode_huffman_slow(wuffs_deflate__decoder* self,
7622                                             wuffs_base__io_buffer* a_dst,
7623                                             wuffs_base__io_buffer* a_src) {
7624   wuffs_base__status status = NULL;
7625 
7626   uint32_t v_bits = 0;
7627   uint32_t v_n_bits = 0;
7628   uint32_t v_table_entry = 0;
7629   uint32_t v_table_entry_n_bits = 0;
7630   uint32_t v_lmask = 0;
7631   uint32_t v_dmask = 0;
7632   uint32_t v_b0 = 0;
7633   uint32_t v_redir_top = 0;
7634   uint32_t v_redir_mask = 0;
7635   uint32_t v_b1 = 0;
7636   uint32_t v_length = 0;
7637   uint32_t v_b2 = 0;
7638   uint32_t v_b3 = 0;
7639   uint32_t v_b4 = 0;
7640   uint32_t v_dist_minus_1 = 0;
7641   uint32_t v_b5 = 0;
7642   uint32_t v_n_copied = 0;
7643   uint32_t v_hlen = 0;
7644   uint32_t v_hdist = 0;
7645 
7646   uint8_t* iop_a_dst = NULL;
7647   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7648   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7649   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7650   if (a_dst) {
7651     io0_a_dst = a_dst->data.ptr;
7652     io1_a_dst = io0_a_dst + a_dst->meta.wi;
7653     iop_a_dst = io1_a_dst;
7654     io2_a_dst = io0_a_dst + a_dst->data.len;
7655     if (a_dst->meta.closed) {
7656       io2_a_dst = iop_a_dst;
7657     }
7658   }
7659   uint8_t* iop_a_src = NULL;
7660   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7661   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7662   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
7663   if (a_src) {
7664     io0_a_src = a_src->data.ptr;
7665     io1_a_src = io0_a_src + a_src->meta.ri;
7666     iop_a_src = io1_a_src;
7667     io2_a_src = io0_a_src + a_src->meta.wi;
7668   }
7669 
7670   uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
7671   if (coro_susp_point) {
7672     v_bits = self->private_data.s_decode_huffman_slow[0].v_bits;
7673     v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits;
7674     v_table_entry = self->private_data.s_decode_huffman_slow[0].v_table_entry;
7675     v_table_entry_n_bits =
7676         self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits;
7677     v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask;
7678     v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask;
7679     v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top;
7680     v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask;
7681     v_length = self->private_data.s_decode_huffman_slow[0].v_length;
7682     v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1;
7683     v_hlen = self->private_data.s_decode_huffman_slow[0].v_hlen;
7684     v_hdist = self->private_data.s_decode_huffman_slow[0].v_hdist;
7685   }
7686   switch (coro_susp_point) {
7687     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
7688 
7689     if ((self->private_impl.f_n_bits >= 8) ||
7690         ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) !=
7691          0)) {
7692       status = wuffs_deflate__error__internal_error_inconsistent_n_bits;
7693       goto exit;
7694     }
7695     v_bits = self->private_impl.f_bits;
7696     v_n_bits = self->private_impl.f_n_bits;
7697     v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
7698     v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
7699   label_0_continue:;
7700     while (!(self->private_impl.p_decode_huffman_slow[0] != 0)) {
7701       while (true) {
7702         v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
7703         v_table_entry_n_bits = (v_table_entry & 15);
7704         if (v_n_bits >= v_table_entry_n_bits) {
7705           v_bits >>= v_table_entry_n_bits;
7706           v_n_bits -= v_table_entry_n_bits;
7707           goto label_1_break;
7708         }
7709         {
7710           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
7711           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
7712             status = wuffs_base__suspension__short_read;
7713             goto suspend;
7714           }
7715           uint32_t t_0 = *iop_a_src++;
7716           v_b0 = t_0;
7717         }
7718         v_bits |= (v_b0 << v_n_bits);
7719         v_n_bits += 8;
7720       }
7721     label_1_break:;
7722       if ((v_table_entry >> 31) != 0) {
7723         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
7724         if (iop_a_dst == io2_a_dst) {
7725           status = wuffs_base__suspension__short_write;
7726           goto suspend;
7727         }
7728         *iop_a_dst++ = ((uint8_t)(((v_table_entry >> 8) & 255)));
7729         goto label_0_continue;
7730       } else if ((v_table_entry >> 30) != 0) {
7731       } else if ((v_table_entry >> 29) != 0) {
7732         self->private_impl.f_end_of_block = true;
7733         goto label_0_break;
7734       } else if ((v_table_entry >> 28) != 0) {
7735         v_redir_top = ((v_table_entry >> 8) & 65535);
7736         v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
7737         while (true) {
7738           v_table_entry =
7739               self->private_data
7740                   .f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
7741           v_table_entry_n_bits = (v_table_entry & 15);
7742           if (v_n_bits >= v_table_entry_n_bits) {
7743             v_bits >>= v_table_entry_n_bits;
7744             v_n_bits -= v_table_entry_n_bits;
7745             goto label_2_break;
7746           }
7747           {
7748             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
7749             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
7750               status = wuffs_base__suspension__short_read;
7751               goto suspend;
7752             }
7753             uint32_t t_1 = *iop_a_src++;
7754             v_b1 = t_1;
7755           }
7756           v_bits |= (v_b1 << v_n_bits);
7757           v_n_bits += 8;
7758         }
7759       label_2_break:;
7760         if ((v_table_entry >> 31) != 0) {
7761           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
7762           if (iop_a_dst == io2_a_dst) {
7763             status = wuffs_base__suspension__short_write;
7764             goto suspend;
7765           }
7766           *iop_a_dst++ = ((uint8_t)(((v_table_entry >> 8) & 255)));
7767           goto label_0_continue;
7768         } else if ((v_table_entry >> 30) != 0) {
7769         } else if ((v_table_entry >> 29) != 0) {
7770           self->private_impl.f_end_of_block = true;
7771           goto label_0_break;
7772         } else if ((v_table_entry >> 28) != 0) {
7773           status =
7774               wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7775           goto exit;
7776         } else if ((v_table_entry >> 27) != 0) {
7777           status = wuffs_deflate__error__bad_huffman_code;
7778           goto exit;
7779         } else {
7780           status =
7781               wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7782           goto exit;
7783         }
7784       } else if ((v_table_entry >> 27) != 0) {
7785         status = wuffs_deflate__error__bad_huffman_code;
7786         goto exit;
7787       } else {
7788         status =
7789             wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7790         goto exit;
7791       }
7792       v_length = (((v_table_entry >> 8) & 255) + 3);
7793       v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
7794       if (v_table_entry_n_bits > 0) {
7795         while (v_n_bits < v_table_entry_n_bits) {
7796           {
7797             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
7798             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
7799               status = wuffs_base__suspension__short_read;
7800               goto suspend;
7801             }
7802             uint32_t t_2 = *iop_a_src++;
7803             v_b2 = t_2;
7804           }
7805           v_bits |= (v_b2 << v_n_bits);
7806           v_n_bits += 8;
7807         }
7808         v_length = (((v_length + 253 +
7809                       ((v_bits)&WUFFS_BASE__LOW_BITS_MASK__U32(
7810                           v_table_entry_n_bits))) &
7811                      255) +
7812                     3);
7813         v_bits >>= v_table_entry_n_bits;
7814         v_n_bits -= v_table_entry_n_bits;
7815       }
7816       while (true) {
7817         v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
7818         v_table_entry_n_bits = (v_table_entry & 15);
7819         if (v_n_bits >= v_table_entry_n_bits) {
7820           v_bits >>= v_table_entry_n_bits;
7821           v_n_bits -= v_table_entry_n_bits;
7822           goto label_3_break;
7823         }
7824         {
7825           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
7826           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
7827             status = wuffs_base__suspension__short_read;
7828             goto suspend;
7829           }
7830           uint32_t t_3 = *iop_a_src++;
7831           v_b3 = t_3;
7832         }
7833         v_bits |= (v_b3 << v_n_bits);
7834         v_n_bits += 8;
7835       }
7836     label_3_break:;
7837       if ((v_table_entry >> 28) == 1) {
7838         v_redir_top = ((v_table_entry >> 8) & 65535);
7839         v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
7840         while (true) {
7841           v_table_entry =
7842               self->private_data
7843                   .f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
7844           v_table_entry_n_bits = (v_table_entry & 15);
7845           if (v_n_bits >= v_table_entry_n_bits) {
7846             v_bits >>= v_table_entry_n_bits;
7847             v_n_bits -= v_table_entry_n_bits;
7848             goto label_4_break;
7849           }
7850           {
7851             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
7852             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
7853               status = wuffs_base__suspension__short_read;
7854               goto suspend;
7855             }
7856             uint32_t t_4 = *iop_a_src++;
7857             v_b4 = t_4;
7858           }
7859           v_bits |= (v_b4 << v_n_bits);
7860           v_n_bits += 8;
7861         }
7862       label_4_break:;
7863       }
7864       if ((v_table_entry >> 24) != 64) {
7865         if ((v_table_entry >> 24) == 8) {
7866           status = wuffs_deflate__error__bad_huffman_code;
7867           goto exit;
7868         }
7869         status =
7870             wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state;
7871         goto exit;
7872       }
7873       v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
7874       v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
7875       if (v_table_entry_n_bits > 0) {
7876         while (v_n_bits < v_table_entry_n_bits) {
7877           {
7878             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
7879             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
7880               status = wuffs_base__suspension__short_read;
7881               goto suspend;
7882             }
7883             uint32_t t_5 = *iop_a_src++;
7884             v_b5 = t_5;
7885           }
7886           v_bits |= (v_b5 << v_n_bits);
7887           v_n_bits += 8;
7888         }
7889         v_dist_minus_1 =
7890             ((v_dist_minus_1 +
7891               ((v_bits)&WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) &
7892              32767);
7893         v_bits >>= v_table_entry_n_bits;
7894         v_n_bits -= v_table_entry_n_bits;
7895       }
7896       while (true) {
7897         if (((uint64_t)((v_dist_minus_1 + 1))) >
7898             ((uint64_t)(iop_a_dst - a_dst->data.ptr))) {
7899           v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) -
7900                                  ((uint64_t)(iop_a_dst - a_dst->data.ptr)))));
7901           if (v_length > v_hdist) {
7902             v_length -= v_hdist;
7903             v_hlen = v_hdist;
7904           } else {
7905             v_hlen = v_length;
7906             v_length = 0;
7907           }
7908           if (self->private_impl.f_history_index < v_hdist) {
7909             status = wuffs_deflate__error__bad_distance;
7910             goto exit;
7911           }
7912           v_hdist = (self->private_impl.f_history_index - v_hdist);
7913           while (true) {
7914             v_n_copied = wuffs_base__io_writer__copy_n_from_slice(
7915                 &iop_a_dst, io2_a_dst, v_hlen,
7916                 wuffs_base__slice_u8__subslice_i(
7917                     wuffs_base__make_slice_u8(self->private_data.f_history,
7918                                               32768),
7919                     (v_hdist & 32767)));
7920             if (v_hlen <= v_n_copied) {
7921               v_hlen = 0;
7922               goto label_5_break;
7923             }
7924             if (v_n_copied > 0) {
7925               v_hlen -= v_n_copied;
7926               v_hdist = ((v_hdist + v_n_copied) & 32767);
7927               if (v_hdist == 0) {
7928                 goto label_5_break;
7929               }
7930             }
7931             status = wuffs_base__suspension__short_write;
7932             WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
7933           }
7934         label_5_break:;
7935           if (v_hlen > 0) {
7936             while (true) {
7937               v_n_copied = wuffs_base__io_writer__copy_n_from_slice(
7938                   &iop_a_dst, io2_a_dst, v_hlen,
7939                   wuffs_base__slice_u8__subslice_i(
7940                       wuffs_base__make_slice_u8(self->private_data.f_history,
7941                                                 32768),
7942                       (v_hdist & 32767)));
7943               if (v_hlen <= v_n_copied) {
7944                 v_hlen = 0;
7945                 goto label_6_break;
7946               }
7947               v_hlen -= v_n_copied;
7948               v_hdist += v_n_copied;
7949               status = wuffs_base__suspension__short_write;
7950               WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
7951             }
7952           label_6_break:;
7953           }
7954           if (v_length == 0) {
7955             goto label_0_continue;
7956           }
7957         }
7958         v_n_copied = wuffs_base__io_writer__copy_n_from_history(
7959             &iop_a_dst, a_dst->data.ptr, io2_a_dst, v_length,
7960             (v_dist_minus_1 + 1));
7961         if (v_length <= v_n_copied) {
7962           v_length = 0;
7963           goto label_7_break;
7964         }
7965         v_length -= v_n_copied;
7966         status = wuffs_base__suspension__short_write;
7967         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
7968       }
7969     label_7_break:;
7970     }
7971   label_0_break:;
7972     self->private_impl.f_bits = v_bits;
7973     self->private_impl.f_n_bits = v_n_bits;
7974     if ((self->private_impl.f_n_bits >= 8) ||
7975         ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) !=
7976          0)) {
7977       status = wuffs_deflate__error__internal_error_inconsistent_n_bits;
7978       goto exit;
7979     }
7980 
7981     goto ok;
7982   ok:
7983     self->private_impl.p_decode_huffman_slow[0] = 0;
7984     goto exit;
7985   }
7986 
7987   goto suspend;
7988 suspend:
7989   self->private_impl.p_decode_huffman_slow[0] =
7990       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
7991   self->private_data.s_decode_huffman_slow[0].v_bits = v_bits;
7992   self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits;
7993   self->private_data.s_decode_huffman_slow[0].v_table_entry = v_table_entry;
7994   self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits =
7995       v_table_entry_n_bits;
7996   self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask;
7997   self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask;
7998   self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top;
7999   self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask;
8000   self->private_data.s_decode_huffman_slow[0].v_length = v_length;
8001   self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1;
8002   self->private_data.s_decode_huffman_slow[0].v_hlen = v_hlen;
8003   self->private_data.s_decode_huffman_slow[0].v_hdist = v_hdist;
8004 
8005   goto exit;
8006 exit:
8007   if (a_dst) {
8008     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
8009   }
8010   if (a_src) {
8011     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
8012   }
8013 
8014   return status;
8015 }
8016 
8017 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
8018         // defined(WUFFS_CONFIG__MODULE__DEFLATE)
8019 
8020 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
8021 
8022 // ---------------- Status Codes Implementations
8023 
8024 const char* wuffs_lzw__error__bad_code = "#lzw: bad code";
8025 const char* wuffs_lzw__error__internal_error_inconsistent_i_o =
8026     "#lzw: internal error: inconsistent I/O";
8027 
8028 // ---------------- Private Consts
8029 
8030 // ---------------- Private Initializer Prototypes
8031 
8032 // ---------------- Private Function Prototypes
8033 
8034 static wuffs_base__empty_struct  //
8035 wuffs_lzw__decoder__read_from(wuffs_lzw__decoder* self,
8036                               wuffs_base__io_buffer* a_src);
8037 
8038 static wuffs_base__status  //
8039 wuffs_lzw__decoder__write_to(wuffs_lzw__decoder* self,
8040                              wuffs_base__io_buffer* a_dst);
8041 
8042 // ---------------- Initializer Implementations
8043 
8044 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 initialize_flags)8045 wuffs_lzw__decoder__initialize(wuffs_lzw__decoder* self,
8046                                size_t sizeof_star_self,
8047                                uint64_t wuffs_version,
8048                                uint32_t initialize_flags) {
8049   if (!self) {
8050     return wuffs_base__error__bad_receiver;
8051   }
8052   if (sizeof(*self) != sizeof_star_self) {
8053     return wuffs_base__error__bad_sizeof_receiver;
8054   }
8055   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
8056       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
8057     return wuffs_base__error__bad_wuffs_version;
8058   }
8059 
8060   if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
8061 // The whole point of this if-check is to detect an uninitialized *self.
8062 // We disable the warning on GCC. Clang-5.0 does not have this warning.
8063 #if !defined(__clang__) && defined(__GNUC__)
8064 #pragma GCC diagnostic push
8065 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
8066 #endif
8067     if (self->private_impl.magic != 0) {
8068       return wuffs_base__error__initialize_falsely_claimed_already_zeroed;
8069     }
8070 #if !defined(__clang__) && defined(__GNUC__)
8071 #pragma GCC diagnostic pop
8072 #endif
8073   } else {
8074     void* p = &(self->private_impl);
8075     size_t n = sizeof(self->private_impl);
8076     if ((initialize_flags &
8077          WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
8078       p = self;
8079       n = sizeof(*self);
8080       initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
8081     }
8082     memset(p, 0, n);
8083   }
8084 
8085   self->private_impl.magic = WUFFS_BASE__MAGIC;
8086   return NULL;
8087 }
8088 
8089 size_t  //
sizeof__wuffs_lzw__decoder()8090 sizeof__wuffs_lzw__decoder() {
8091   return sizeof(wuffs_lzw__decoder);
8092 }
8093 
8094 // ---------------- Function Implementations
8095 
8096 // -------- func lzw.decoder.set_literal_width
8097 
8098 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
wuffs_lzw__decoder__set_literal_width(wuffs_lzw__decoder * self,uint32_t a_lw)8099 wuffs_lzw__decoder__set_literal_width(wuffs_lzw__decoder* self, uint32_t a_lw) {
8100   if (!self) {
8101     return wuffs_base__make_empty_struct();
8102   }
8103   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8104     return wuffs_base__make_empty_struct();
8105   }
8106   if (a_lw > 8) {
8107     self->private_impl.magic = WUFFS_BASE__DISABLED;
8108     return wuffs_base__make_empty_struct();
8109   }
8110 
8111   self->private_impl.f_set_literal_width_arg = (a_lw + 1);
8112   return wuffs_base__make_empty_struct();
8113 }
8114 
8115 // -------- func lzw.decoder.workbuf_len
8116 
8117 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder * self)8118 wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder* self) {
8119   if (!self) {
8120     return wuffs_base__utility__make_range_ii_u64(0, 0);
8121   }
8122   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
8123       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
8124     return wuffs_base__utility__make_range_ii_u64(0, 0);
8125   }
8126 
8127   return wuffs_base__utility__make_range_ii_u64(0, 0);
8128 }
8129 
8130 // -------- func lzw.decoder.decode_io_writer
8131 
8132 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_lzw__decoder__decode_io_writer(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)8133 wuffs_lzw__decoder__decode_io_writer(wuffs_lzw__decoder* self,
8134                                      wuffs_base__io_buffer* a_dst,
8135                                      wuffs_base__io_buffer* a_src,
8136                                      wuffs_base__slice_u8 a_workbuf) {
8137   if (!self) {
8138     return wuffs_base__error__bad_receiver;
8139   }
8140   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8141     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
8142                ? wuffs_base__error__disabled_by_previous_error
8143                : wuffs_base__error__initialize_not_called;
8144   }
8145   if (!a_dst || !a_src) {
8146     self->private_impl.magic = WUFFS_BASE__DISABLED;
8147     return wuffs_base__error__bad_argument;
8148   }
8149   if ((self->private_impl.active_coroutine != 0) &&
8150       (self->private_impl.active_coroutine != 1)) {
8151     self->private_impl.magic = WUFFS_BASE__DISABLED;
8152     return wuffs_base__error__interleaved_coroutine_calls;
8153   }
8154   self->private_impl.active_coroutine = 0;
8155   wuffs_base__status status = NULL;
8156 
8157   uint32_t v_i = 0;
8158 
8159   uint32_t coro_susp_point = self->private_impl.p_decode_io_writer[0];
8160   if (coro_susp_point) {
8161   }
8162   switch (coro_susp_point) {
8163     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
8164 
8165     self->private_impl.f_literal_width = 8;
8166     if (self->private_impl.f_set_literal_width_arg > 0) {
8167       self->private_impl.f_literal_width =
8168           (self->private_impl.f_set_literal_width_arg - 1);
8169     }
8170     self->private_impl.f_clear_code =
8171         (((uint32_t)(1)) << self->private_impl.f_literal_width);
8172     self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1);
8173     self->private_impl.f_save_code = self->private_impl.f_end_code;
8174     self->private_impl.f_prev_code = self->private_impl.f_end_code;
8175     self->private_impl.f_width = (self->private_impl.f_literal_width + 1);
8176     self->private_impl.f_bits = 0;
8177     self->private_impl.f_n_bits = 0;
8178     self->private_impl.f_output_ri = 0;
8179     self->private_impl.f_output_wi = 0;
8180     v_i = 0;
8181     while (v_i < self->private_impl.f_clear_code) {
8182       self->private_data.f_lm1s[v_i] = 0;
8183       self->private_data.f_suffixes[v_i][0] = ((uint8_t)(v_i));
8184       v_i += 1;
8185     }
8186   label_0_continue:;
8187     while (true) {
8188       wuffs_lzw__decoder__read_from(self, a_src);
8189       if (self->private_impl.f_output_wi > 0) {
8190         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
8191         status = wuffs_lzw__decoder__write_to(self, a_dst);
8192         if (status) {
8193           goto suspend;
8194         }
8195       }
8196       if (self->private_impl.f_read_from_return_value == 0) {
8197         goto label_0_break;
8198       } else if (self->private_impl.f_read_from_return_value == 1) {
8199         goto label_0_continue;
8200       } else if (self->private_impl.f_read_from_return_value == 2) {
8201         status = wuffs_base__suspension__short_read;
8202         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
8203       } else if (self->private_impl.f_read_from_return_value == 3) {
8204         status = wuffs_lzw__error__bad_code;
8205         goto exit;
8206       } else {
8207         status = wuffs_lzw__error__internal_error_inconsistent_i_o;
8208         goto exit;
8209       }
8210     }
8211   label_0_break:;
8212 
8213     goto ok;
8214   ok:
8215     self->private_impl.p_decode_io_writer[0] = 0;
8216     goto exit;
8217   }
8218 
8219   goto suspend;
8220 suspend:
8221   self->private_impl.p_decode_io_writer[0] =
8222       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
8223   self->private_impl.active_coroutine =
8224       wuffs_base__status__is_suspension(status) ? 1 : 0;
8225 
8226   goto exit;
8227 exit:
8228   if (wuffs_base__status__is_error(status)) {
8229     self->private_impl.magic = WUFFS_BASE__DISABLED;
8230   }
8231   return status;
8232 }
8233 
8234 // -------- func lzw.decoder.read_from
8235 
8236 static wuffs_base__empty_struct  //
wuffs_lzw__decoder__read_from(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_src)8237 wuffs_lzw__decoder__read_from(wuffs_lzw__decoder* self,
8238                               wuffs_base__io_buffer* a_src) {
8239   uint32_t v_clear_code = 0;
8240   uint32_t v_end_code = 0;
8241   uint32_t v_save_code = 0;
8242   uint32_t v_prev_code = 0;
8243   uint32_t v_width = 0;
8244   uint32_t v_bits = 0;
8245   uint32_t v_n_bits = 0;
8246   uint32_t v_output_wi = 0;
8247   uint32_t v_code = 0;
8248   uint32_t v_c = 0;
8249   uint32_t v_o = 0;
8250   uint32_t v_steps = 0;
8251   uint8_t v_first_byte = 0;
8252   uint16_t v_lm1_b = 0;
8253   uint16_t v_lm1_a = 0;
8254 
8255   uint8_t* iop_a_src = NULL;
8256   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8257   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8258   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8259   if (a_src) {
8260     io0_a_src = a_src->data.ptr;
8261     io1_a_src = io0_a_src + a_src->meta.ri;
8262     iop_a_src = io1_a_src;
8263     io2_a_src = io0_a_src + a_src->meta.wi;
8264   }
8265 
8266   v_clear_code = self->private_impl.f_clear_code;
8267   v_end_code = self->private_impl.f_end_code;
8268   v_save_code = self->private_impl.f_save_code;
8269   v_prev_code = self->private_impl.f_prev_code;
8270   v_width = self->private_impl.f_width;
8271   v_bits = self->private_impl.f_bits;
8272   v_n_bits = self->private_impl.f_n_bits;
8273   v_output_wi = self->private_impl.f_output_wi;
8274   while (true) {
8275     if (v_n_bits < v_width) {
8276       if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
8277         v_bits |= (wuffs_base__load_u32le(iop_a_src) << v_n_bits);
8278         (iop_a_src += ((31 - v_n_bits) >> 3), wuffs_base__make_empty_struct());
8279         v_n_bits |= 24;
8280       } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
8281         self->private_impl.f_read_from_return_value = 2;
8282         goto label_0_break;
8283       } else {
8284         v_bits |= (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
8285         (iop_a_src += 1, wuffs_base__make_empty_struct());
8286         v_n_bits += 8;
8287         if (v_n_bits >= v_width) {
8288         } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
8289           self->private_impl.f_read_from_return_value = 2;
8290           goto label_0_break;
8291         } else {
8292           v_bits |=
8293               (((uint32_t)(wuffs_base__load_u8be(iop_a_src))) << v_n_bits);
8294           (iop_a_src += 1, wuffs_base__make_empty_struct());
8295           v_n_bits += 8;
8296           if (v_n_bits < v_width) {
8297             self->private_impl.f_read_from_return_value = 4;
8298             goto label_0_break;
8299           }
8300         }
8301       }
8302     }
8303     v_code = ((v_bits)&WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
8304     v_bits >>= v_width;
8305     v_n_bits -= v_width;
8306     if (v_code < v_clear_code) {
8307       self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
8308       v_output_wi = ((v_output_wi + 1) & 8191);
8309       if (v_save_code <= 4095) {
8310         v_lm1_a = ((self->private_data.f_lm1s[v_prev_code] + 1) & 4095);
8311         self->private_data.f_lm1s[v_save_code] = v_lm1_a;
8312         if ((v_lm1_a % 8) != 0) {
8313           self->private_impl.f_prefixes[v_save_code] =
8314               self->private_impl.f_prefixes[v_prev_code];
8315           memcpy(self->private_data.f_suffixes[v_save_code],
8316                  self->private_data.f_suffixes[v_prev_code],
8317                  sizeof(self->private_data.f_suffixes[v_save_code]));
8318           self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8)] =
8319               ((uint8_t)(v_code));
8320         } else {
8321           self->private_impl.f_prefixes[v_save_code] =
8322               ((uint16_t)(v_prev_code));
8323           self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_code));
8324         }
8325         v_save_code += 1;
8326         if (v_width < 12) {
8327           v_width += (1 & (v_save_code >> v_width));
8328         }
8329         v_prev_code = v_code;
8330       }
8331     } else if (v_code <= v_end_code) {
8332       if (v_code == v_end_code) {
8333         self->private_impl.f_read_from_return_value = 0;
8334         goto label_0_break;
8335       }
8336       v_save_code = v_end_code;
8337       v_prev_code = v_end_code;
8338       v_width = (self->private_impl.f_literal_width + 1);
8339     } else if (v_code <= v_save_code) {
8340       v_c = v_code;
8341       if (v_code == v_save_code) {
8342         v_c = v_prev_code;
8343       }
8344       v_o = ((v_output_wi +
8345               (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288)) &
8346              8191);
8347       v_output_wi =
8348           ((v_output_wi + 1 + ((uint32_t)(self->private_data.f_lm1s[v_c]))) &
8349            8191);
8350       v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3);
8351       while (true) {
8352         memcpy((self->private_data.f_output) + (v_o),
8353                (self->private_data.f_suffixes[v_c]), 8);
8354         if (v_steps <= 0) {
8355           goto label_1_break;
8356         }
8357         v_steps -= 1;
8358         v_o = ((v_o - 8) & 8191);
8359         v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
8360       }
8361     label_1_break:;
8362       v_first_byte = self->private_data.f_suffixes[v_c][0];
8363       if (v_code == v_save_code) {
8364         self->private_data.f_output[v_output_wi] = v_first_byte;
8365         v_output_wi = ((v_output_wi + 1) & 8191);
8366       }
8367       if (v_save_code <= 4095) {
8368         v_lm1_b = ((self->private_data.f_lm1s[v_prev_code] + 1) & 4095);
8369         self->private_data.f_lm1s[v_save_code] = v_lm1_b;
8370         if ((v_lm1_b % 8) != 0) {
8371           self->private_impl.f_prefixes[v_save_code] =
8372               self->private_impl.f_prefixes[v_prev_code];
8373           memcpy(self->private_data.f_suffixes[v_save_code],
8374                  self->private_data.f_suffixes[v_prev_code],
8375                  sizeof(self->private_data.f_suffixes[v_save_code]));
8376           self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8)] =
8377               v_first_byte;
8378         } else {
8379           self->private_impl.f_prefixes[v_save_code] =
8380               ((uint16_t)(v_prev_code));
8381           self->private_data.f_suffixes[v_save_code][0] =
8382               ((uint8_t)(v_first_byte));
8383         }
8384         v_save_code += 1;
8385         if (v_width < 12) {
8386           v_width += (1 & (v_save_code >> v_width));
8387         }
8388         v_prev_code = v_code;
8389       }
8390     } else {
8391       self->private_impl.f_read_from_return_value = 3;
8392       goto label_0_break;
8393     }
8394     if (v_output_wi > 4095) {
8395       self->private_impl.f_read_from_return_value = 1;
8396       goto label_0_break;
8397     }
8398   }
8399 label_0_break:;
8400   if (self->private_impl.f_read_from_return_value != 2) {
8401     while (v_n_bits >= 8) {
8402       v_n_bits -= 8;
8403       if (iop_a_src > io1_a_src) {
8404         (iop_a_src--, wuffs_base__make_empty_struct());
8405       } else {
8406         self->private_impl.f_read_from_return_value = 4;
8407         goto label_2_break;
8408       }
8409     }
8410   label_2_break:;
8411   }
8412   self->private_impl.f_save_code = v_save_code;
8413   self->private_impl.f_prev_code = v_prev_code;
8414   self->private_impl.f_width = v_width;
8415   self->private_impl.f_bits = v_bits;
8416   self->private_impl.f_n_bits = v_n_bits;
8417   self->private_impl.f_output_wi = v_output_wi;
8418   if (a_src) {
8419     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
8420   }
8421 
8422   return wuffs_base__make_empty_struct();
8423 }
8424 
8425 // -------- func lzw.decoder.write_to
8426 
8427 static wuffs_base__status  //
wuffs_lzw__decoder__write_to(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst)8428 wuffs_lzw__decoder__write_to(wuffs_lzw__decoder* self,
8429                              wuffs_base__io_buffer* a_dst) {
8430   wuffs_base__status status = NULL;
8431 
8432   wuffs_base__slice_u8 v_s = {0};
8433   uint64_t v_n = 0;
8434 
8435   uint8_t* iop_a_dst = NULL;
8436   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8437   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8438   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8439   if (a_dst) {
8440     io0_a_dst = a_dst->data.ptr;
8441     io1_a_dst = io0_a_dst + a_dst->meta.wi;
8442     iop_a_dst = io1_a_dst;
8443     io2_a_dst = io0_a_dst + a_dst->data.len;
8444     if (a_dst->meta.closed) {
8445       io2_a_dst = iop_a_dst;
8446     }
8447   }
8448 
8449   uint32_t coro_susp_point = self->private_impl.p_write_to[0];
8450   if (coro_susp_point) {
8451   }
8452   switch (coro_susp_point) {
8453     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
8454 
8455     while (self->private_impl.f_output_wi > 0) {
8456       if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
8457         status = wuffs_lzw__error__internal_error_inconsistent_i_o;
8458         goto exit;
8459       }
8460       v_s = wuffs_base__slice_u8__subslice_ij(
8461           wuffs_base__make_slice_u8(self->private_data.f_output, 8199),
8462           self->private_impl.f_output_ri, self->private_impl.f_output_wi);
8463       v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst, v_s);
8464       if (v_n == ((uint64_t)(v_s.len))) {
8465         self->private_impl.f_output_ri = 0;
8466         self->private_impl.f_output_wi = 0;
8467         status = NULL;
8468         goto ok;
8469       }
8470       self->private_impl.f_output_ri =
8471           ((self->private_impl.f_output_ri + ((uint32_t)((v_n & 4294967295)))) &
8472            8191);
8473       status = wuffs_base__suspension__short_write;
8474       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
8475     }
8476 
8477     goto ok;
8478   ok:
8479     self->private_impl.p_write_to[0] = 0;
8480     goto exit;
8481   }
8482 
8483   goto suspend;
8484 suspend:
8485   self->private_impl.p_write_to[0] =
8486       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
8487 
8488   goto exit;
8489 exit:
8490   if (a_dst) {
8491     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
8492   }
8493 
8494   return status;
8495 }
8496 
8497 // -------- func lzw.decoder.flush
8498 
8499 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8  //
wuffs_lzw__decoder__flush(wuffs_lzw__decoder * self)8500 wuffs_lzw__decoder__flush(wuffs_lzw__decoder* self) {
8501   if (!self) {
8502     return wuffs_base__make_slice_u8(NULL, 0);
8503   }
8504   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8505     return wuffs_base__make_slice_u8(NULL, 0);
8506   }
8507 
8508   wuffs_base__slice_u8 v_s = {0};
8509 
8510   if (self->private_impl.f_output_ri <= self->private_impl.f_output_wi) {
8511     v_s = wuffs_base__slice_u8__subslice_ij(
8512         wuffs_base__make_slice_u8(self->private_data.f_output, 8199),
8513         self->private_impl.f_output_ri, self->private_impl.f_output_wi);
8514   }
8515   self->private_impl.f_output_ri = 0;
8516   self->private_impl.f_output_wi = 0;
8517   return v_s;
8518 }
8519 
8520 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
8521 
8522 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
8523 
8524 // ---------------- Status Codes Implementations
8525 
8526 const char* wuffs_gif__error__bad_block = "#gif: bad block";
8527 const char* wuffs_gif__error__bad_extension_label = "#gif: bad extension label";
8528 const char* wuffs_gif__error__bad_frame_size = "#gif: bad frame size";
8529 const char* wuffs_gif__error__bad_graphic_control = "#gif: bad graphic control";
8530 const char* wuffs_gif__error__bad_header = "#gif: bad header";
8531 const char* wuffs_gif__error__bad_literal_width = "#gif: bad literal width";
8532 const char* wuffs_gif__error__bad_palette = "#gif: bad palette";
8533 const char* wuffs_gif__error__internal_error_inconsistent_ri_wi =
8534     "#gif: internal error: inconsistent ri/wi";
8535 
8536 // ---------------- Private Consts
8537 
8538 static const uint32_t              //
8539     wuffs_gif__interlace_start[5]  //
8540     WUFFS_BASE__POTENTIALLY_UNUSED = {
8541         4294967295, 1, 2, 4, 0,
8542 };
8543 
8544 static const uint8_t               //
8545     wuffs_gif__interlace_delta[5]  //
8546     WUFFS_BASE__POTENTIALLY_UNUSED = {
8547         1, 2, 4, 8, 8,
8548 };
8549 
8550 static const uint8_t              //
8551     wuffs_gif__animexts1dot0[11]  //
8552     WUFFS_BASE__POTENTIALLY_UNUSED = {
8553         65, 78, 73, 77, 69, 88, 84, 83, 49, 46, 48,
8554 };
8555 
8556 static const uint8_t              //
8557     wuffs_gif__netscape2dot0[11]  //
8558     WUFFS_BASE__POTENTIALLY_UNUSED = {
8559         78, 69, 84, 83, 67, 65, 80, 69, 50, 46, 48,
8560 };
8561 
8562 static const uint8_t            //
8563     wuffs_gif__iccrgbg1012[11]  //
8564     WUFFS_BASE__POTENTIALLY_UNUSED = {
8565         73, 67, 67, 82, 71, 66, 71, 49, 48, 49, 50,
8566 };
8567 
8568 static const uint8_t           //
8569     wuffs_gif__xmpdataxmp[11]  //
8570     WUFFS_BASE__POTENTIALLY_UNUSED = {
8571         88, 77, 80, 32, 68, 97, 116, 97, 88, 77, 80,
8572 };
8573 
8574 // ---------------- Private Initializer Prototypes
8575 
8576 // ---------------- Private Function Prototypes
8577 
8578 static wuffs_base__status  //
8579 wuffs_gif__decoder__skip_frame(wuffs_gif__decoder* self,
8580                                wuffs_base__io_buffer* a_src);
8581 
8582 static wuffs_base__empty_struct  //
8583 wuffs_gif__decoder__reset_gc(wuffs_gif__decoder* self);
8584 
8585 static wuffs_base__status  //
8586 wuffs_gif__decoder__decode_up_to_id_part1(wuffs_gif__decoder* self,
8587                                           wuffs_base__io_buffer* a_src);
8588 
8589 static wuffs_base__status  //
8590 wuffs_gif__decoder__decode_header(wuffs_gif__decoder* self,
8591                                   wuffs_base__io_buffer* a_src);
8592 
8593 static wuffs_base__status  //
8594 wuffs_gif__decoder__decode_lsd(wuffs_gif__decoder* self,
8595                                wuffs_base__io_buffer* a_src);
8596 
8597 static wuffs_base__status  //
8598 wuffs_gif__decoder__decode_extension(wuffs_gif__decoder* self,
8599                                      wuffs_base__io_buffer* a_src);
8600 
8601 static wuffs_base__status  //
8602 wuffs_gif__decoder__skip_blocks(wuffs_gif__decoder* self,
8603                                 wuffs_base__io_buffer* a_src);
8604 
8605 static wuffs_base__status  //
8606 wuffs_gif__decoder__decode_ae(wuffs_gif__decoder* self,
8607                               wuffs_base__io_buffer* a_src);
8608 
8609 static wuffs_base__status  //
8610 wuffs_gif__decoder__decode_gc(wuffs_gif__decoder* self,
8611                               wuffs_base__io_buffer* a_src);
8612 
8613 static wuffs_base__status  //
8614 wuffs_gif__decoder__decode_id_part0(wuffs_gif__decoder* self,
8615                                     wuffs_base__io_buffer* a_src);
8616 
8617 static wuffs_base__status  //
8618 wuffs_gif__decoder__decode_id_part1(wuffs_gif__decoder* self,
8619                                     wuffs_base__pixel_buffer* a_dst,
8620                                     wuffs_base__io_buffer* a_src);
8621 
8622 static wuffs_base__status  //
8623 wuffs_gif__decoder__decode_id_part2(wuffs_gif__decoder* self,
8624                                     wuffs_base__pixel_buffer* a_dst,
8625                                     wuffs_base__io_buffer* a_src,
8626                                     wuffs_base__slice_u8 a_workbuf);
8627 
8628 static wuffs_base__status  //
8629 wuffs_gif__decoder__copy_to_image_buffer(wuffs_gif__decoder* self,
8630                                          wuffs_base__pixel_buffer* a_pb,
8631                                          wuffs_base__slice_u8 a_src);
8632 
8633 // ---------------- Initializer Implementations
8634 
8635 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 initialize_flags)8636 wuffs_gif__decoder__initialize(wuffs_gif__decoder* self,
8637                                size_t sizeof_star_self,
8638                                uint64_t wuffs_version,
8639                                uint32_t initialize_flags) {
8640   if (!self) {
8641     return wuffs_base__error__bad_receiver;
8642   }
8643   if (sizeof(*self) != sizeof_star_self) {
8644     return wuffs_base__error__bad_sizeof_receiver;
8645   }
8646   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
8647       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
8648     return wuffs_base__error__bad_wuffs_version;
8649   }
8650 
8651   if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
8652 // The whole point of this if-check is to detect an uninitialized *self.
8653 // We disable the warning on GCC. Clang-5.0 does not have this warning.
8654 #if !defined(__clang__) && defined(__GNUC__)
8655 #pragma GCC diagnostic push
8656 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
8657 #endif
8658     if (self->private_impl.magic != 0) {
8659       return wuffs_base__error__initialize_falsely_claimed_already_zeroed;
8660     }
8661 #if !defined(__clang__) && defined(__GNUC__)
8662 #pragma GCC diagnostic pop
8663 #endif
8664   } else {
8665     void* p = &(self->private_impl);
8666     size_t n = sizeof(self->private_impl);
8667     if ((initialize_flags &
8668          WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
8669       p = self;
8670       n = sizeof(*self);
8671       initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
8672     }
8673     memset(p, 0, n);
8674   }
8675 
8676   {
8677     wuffs_base__status z = wuffs_lzw__decoder__initialize(
8678         &self->private_data.f_lzw, sizeof(self->private_data.f_lzw),
8679         WUFFS_VERSION, initialize_flags);
8680     if (z) {
8681       return z;
8682     }
8683   }
8684   self->private_impl.magic = WUFFS_BASE__MAGIC;
8685   return NULL;
8686 }
8687 
8688 size_t  //
sizeof__wuffs_gif__decoder()8689 sizeof__wuffs_gif__decoder() {
8690   return sizeof(wuffs_gif__decoder);
8691 }
8692 
8693 // ---------------- Function Implementations
8694 
8695 // -------- func gif.decoder.set_quirk_enabled
8696 
8697 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)8698 wuffs_gif__decoder__set_quirk_enabled(wuffs_gif__decoder* self,
8699                                       uint32_t a_quirk,
8700                                       bool a_enabled) {
8701   if (!self) {
8702     return wuffs_base__make_empty_struct();
8703   }
8704   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8705     return wuffs_base__make_empty_struct();
8706   }
8707 
8708   if (self->private_impl.f_call_sequence == 0) {
8709     if (a_quirk == 1041635328) {
8710       self->private_impl.f_quirk_enabled_delay_num_decoded_frames = a_enabled;
8711     } else if (a_quirk == 1041635329) {
8712       self->private_impl
8713           .f_quirk_enabled_first_frame_local_palette_means_black_background =
8714           a_enabled;
8715     } else if (a_quirk == 1041635330) {
8716       self->private_impl.f_quirk_enabled_honor_background_color = a_enabled;
8717     } else if (a_quirk == 1041635331) {
8718       self->private_impl.f_quirk_enabled_ignore_too_much_pixel_data = a_enabled;
8719     } else if (a_quirk == 1041635332) {
8720       self->private_impl.f_quirk_enabled_image_bounds_are_strict = a_enabled;
8721     } else if (a_quirk == 1041635333) {
8722       self->private_impl.f_quirk_enabled_reject_empty_frame = a_enabled;
8723     } else if (a_quirk == 1041635334) {
8724       self->private_impl.f_quirk_enabled_reject_empty_palette = a_enabled;
8725     }
8726   }
8727   return wuffs_base__make_empty_struct();
8728 }
8729 
8730 // -------- func gif.decoder.decode_image_config
8731 
8732 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)8733 wuffs_gif__decoder__decode_image_config(wuffs_gif__decoder* self,
8734                                         wuffs_base__image_config* a_dst,
8735                                         wuffs_base__io_buffer* a_src) {
8736   if (!self) {
8737     return wuffs_base__error__bad_receiver;
8738   }
8739   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8740     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
8741                ? wuffs_base__error__disabled_by_previous_error
8742                : wuffs_base__error__initialize_not_called;
8743   }
8744   if (!a_src) {
8745     self->private_impl.magic = WUFFS_BASE__DISABLED;
8746     return wuffs_base__error__bad_argument;
8747   }
8748   if ((self->private_impl.active_coroutine != 0) &&
8749       (self->private_impl.active_coroutine != 1)) {
8750     self->private_impl.magic = WUFFS_BASE__DISABLED;
8751     return wuffs_base__error__interleaved_coroutine_calls;
8752   }
8753   self->private_impl.active_coroutine = 0;
8754   wuffs_base__status status = NULL;
8755 
8756   bool v_ffio = false;
8757 
8758   uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
8759   if (coro_susp_point) {
8760   }
8761   switch (coro_susp_point) {
8762     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
8763 
8764     if (self->private_impl.f_call_sequence == 0) {
8765       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
8766       status = wuffs_gif__decoder__decode_header(self, a_src);
8767       if (status) {
8768         goto suspend;
8769       }
8770       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
8771       status = wuffs_gif__decoder__decode_lsd(self, a_src);
8772       if (status) {
8773         goto suspend;
8774       }
8775     } else if (self->private_impl.f_call_sequence != 2) {
8776       status = wuffs_base__error__bad_call_sequence;
8777       goto exit;
8778     }
8779     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
8780     status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
8781     if (status) {
8782       goto suspend;
8783     }
8784     v_ffio = !self->private_impl.f_gc_has_transparent_index;
8785     if (!self->private_impl.f_quirk_enabled_honor_background_color) {
8786       v_ffio =
8787           (v_ffio && (self->private_impl.f_frame_rect_x0 == 0) &&
8788            (self->private_impl.f_frame_rect_y0 == 0) &&
8789            (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
8790            (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
8791     } else if (v_ffio) {
8792       self->private_impl.f_black_color_u32_argb_premul = 4278190080;
8793     }
8794     if (self->private_impl.f_background_color_u32_argb_premul == 77) {
8795       self->private_impl.f_background_color_u32_argb_premul =
8796           self->private_impl.f_black_color_u32_argb_premul;
8797     }
8798     if (a_dst != NULL) {
8799       wuffs_base__image_config__set(
8800           a_dst, 1191444488, 0, self->private_impl.f_width,
8801           self->private_impl.f_height,
8802           self->private_impl.f_frame_config_io_position, v_ffio);
8803     }
8804     self->private_impl.f_call_sequence = 3;
8805 
8806     goto ok;
8807   ok:
8808     self->private_impl.p_decode_image_config[0] = 0;
8809     goto exit;
8810   }
8811 
8812   goto suspend;
8813 suspend:
8814   self->private_impl.p_decode_image_config[0] =
8815       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
8816   self->private_impl.active_coroutine =
8817       wuffs_base__status__is_suspension(status) ? 1 : 0;
8818 
8819   goto exit;
8820 exit:
8821   if (wuffs_base__status__is_error(status)) {
8822     self->private_impl.magic = WUFFS_BASE__DISABLED;
8823   }
8824   return status;
8825 }
8826 
8827 // -------- func gif.decoder.set_report_metadata
8828 
8829 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)8830 wuffs_gif__decoder__set_report_metadata(wuffs_gif__decoder* self,
8831                                         uint32_t a_fourcc,
8832                                         bool a_report) {
8833   if (!self) {
8834     return wuffs_base__make_empty_struct();
8835   }
8836   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8837     return wuffs_base__make_empty_struct();
8838   }
8839 
8840   if (a_fourcc == 1229144912) {
8841     self->private_impl.f_report_metadata_iccp = a_report;
8842   } else if (a_fourcc == 1481461792) {
8843     self->private_impl.f_report_metadata_xmp = a_report;
8844   }
8845   return wuffs_base__make_empty_struct();
8846 }
8847 
8848 // -------- func gif.decoder.ack_metadata_chunk
8849 
8850 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_gif__decoder__ack_metadata_chunk(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)8851 wuffs_gif__decoder__ack_metadata_chunk(wuffs_gif__decoder* self,
8852                                        wuffs_base__io_buffer* a_src) {
8853   if (!self) {
8854     return wuffs_base__error__bad_receiver;
8855   }
8856   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8857     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
8858                ? wuffs_base__error__disabled_by_previous_error
8859                : wuffs_base__error__initialize_not_called;
8860   }
8861   if (!a_src) {
8862     self->private_impl.magic = WUFFS_BASE__DISABLED;
8863     return wuffs_base__error__bad_argument;
8864   }
8865   if ((self->private_impl.active_coroutine != 0) &&
8866       (self->private_impl.active_coroutine != 2)) {
8867     self->private_impl.magic = WUFFS_BASE__DISABLED;
8868     return wuffs_base__error__interleaved_coroutine_calls;
8869   }
8870   self->private_impl.active_coroutine = 0;
8871   wuffs_base__status status = NULL;
8872 
8873   uint8_t* iop_a_src = NULL;
8874   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8875   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8876   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
8877   if (a_src) {
8878     io0_a_src = a_src->data.ptr;
8879     io1_a_src = io0_a_src + a_src->meta.ri;
8880     iop_a_src = io1_a_src;
8881     io2_a_src = io0_a_src + a_src->meta.wi;
8882   }
8883 
8884   uint32_t coro_susp_point = self->private_impl.p_ack_metadata_chunk[0];
8885   if (coro_susp_point) {
8886   }
8887   switch (coro_susp_point) {
8888     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
8889 
8890     if (self->private_impl.f_call_sequence != 1) {
8891       status = wuffs_base__error__bad_call_sequence;
8892       goto exit;
8893     }
8894     if ((a_src ? wuffs_base__u64__sat_add(
8895                      a_src->meta.pos, ((uint64_t)(iop_a_src - a_src->data.ptr)))
8896                : 0) != self->private_impl.f_metadata_io_position) {
8897       status = wuffs_base__error__bad_i_o_position;
8898       goto exit;
8899     }
8900     while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
8901       status = wuffs_base__suspension__short_read;
8902       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
8903     }
8904     if (self->private_impl.f_metadata_fourcc_value == 1481461792) {
8905       self->private_impl.f_metadata_chunk_length_value =
8906           (((uint64_t)(wuffs_base__load_u8be(iop_a_src))) + 1);
8907       if (self->private_impl.f_metadata_chunk_length_value > 1) {
8908         self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(
8909             (a_src ? wuffs_base__u64__sat_add(
8910                          a_src->meta.pos,
8911                          ((uint64_t)(iop_a_src - a_src->data.ptr)))
8912                    : 0),
8913             self->private_impl.f_metadata_chunk_length_value);
8914         status = wuffs_base__warning__metadata_reported;
8915         goto ok;
8916       }
8917     } else {
8918       self->private_impl.f_metadata_chunk_length_value =
8919           ((uint64_t)(wuffs_base__load_u8be(iop_a_src)));
8920       if (self->private_impl.f_metadata_chunk_length_value > 0) {
8921         (iop_a_src += 1, wuffs_base__make_empty_struct());
8922         self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(
8923             (a_src ? wuffs_base__u64__sat_add(
8924                          a_src->meta.pos,
8925                          ((uint64_t)(iop_a_src - a_src->data.ptr)))
8926                    : 0),
8927             self->private_impl.f_metadata_chunk_length_value);
8928         status = wuffs_base__warning__metadata_reported;
8929         goto ok;
8930       }
8931     }
8932     (iop_a_src += 1, wuffs_base__make_empty_struct());
8933     self->private_impl.f_call_sequence = 2;
8934     self->private_impl.f_metadata_fourcc_value = 0;
8935     self->private_impl.f_metadata_io_position = 0;
8936     status = NULL;
8937     goto ok;
8938     goto ok;
8939   ok:
8940     self->private_impl.p_ack_metadata_chunk[0] = 0;
8941     goto exit;
8942   }
8943 
8944   goto suspend;
8945 suspend:
8946   self->private_impl.p_ack_metadata_chunk[0] =
8947       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
8948   self->private_impl.active_coroutine =
8949       wuffs_base__status__is_suspension(status) ? 2 : 0;
8950 
8951   goto exit;
8952 exit:
8953   if (a_src) {
8954     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
8955   }
8956 
8957   if (wuffs_base__status__is_error(status)) {
8958     self->private_impl.magic = WUFFS_BASE__DISABLED;
8959   }
8960   return status;
8961 }
8962 
8963 // -------- func gif.decoder.metadata_fourcc
8964 
8965 WUFFS_BASE__MAYBE_STATIC uint32_t  //
wuffs_gif__decoder__metadata_fourcc(const wuffs_gif__decoder * self)8966 wuffs_gif__decoder__metadata_fourcc(const wuffs_gif__decoder* self) {
8967   if (!self) {
8968     return 0;
8969   }
8970   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
8971       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
8972     return 0;
8973   }
8974 
8975   return self->private_impl.f_metadata_fourcc_value;
8976 }
8977 
8978 // -------- func gif.decoder.metadata_chunk_length
8979 
8980 WUFFS_BASE__MAYBE_STATIC uint64_t  //
wuffs_gif__decoder__metadata_chunk_length(const wuffs_gif__decoder * self)8981 wuffs_gif__decoder__metadata_chunk_length(const wuffs_gif__decoder* self) {
8982   if (!self) {
8983     return 0;
8984   }
8985   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
8986       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
8987     return 0;
8988   }
8989 
8990   return self->private_impl.f_metadata_chunk_length_value;
8991 }
8992 
8993 // -------- func gif.decoder.num_animation_loops
8994 
8995 WUFFS_BASE__MAYBE_STATIC uint32_t  //
wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder * self)8996 wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder* self) {
8997   if (!self) {
8998     return 0;
8999   }
9000   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9001       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9002     return 0;
9003   }
9004 
9005   if (self->private_impl.f_seen_num_loops) {
9006     return self->private_impl.f_num_loops;
9007   }
9008   return 1;
9009 }
9010 
9011 // -------- func gif.decoder.num_decoded_frame_configs
9012 
9013 WUFFS_BASE__MAYBE_STATIC uint64_t  //
wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder * self)9014 wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder* self) {
9015   if (!self) {
9016     return 0;
9017   }
9018   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9019       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9020     return 0;
9021   }
9022 
9023   return self->private_impl.f_num_decoded_frame_configs_value;
9024 }
9025 
9026 // -------- func gif.decoder.num_decoded_frames
9027 
9028 WUFFS_BASE__MAYBE_STATIC uint64_t  //
wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder * self)9029 wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder* self) {
9030   if (!self) {
9031     return 0;
9032   }
9033   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9034       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9035     return 0;
9036   }
9037 
9038   return self->private_impl.f_num_decoded_frames_value;
9039 }
9040 
9041 // -------- func gif.decoder.frame_dirty_rect
9042 
9043 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32  //
wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder * self)9044 wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder* self) {
9045   if (!self) {
9046     return wuffs_base__utility__make_rect_ie_u32(0, 0, 0, 0);
9047   }
9048   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9049       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9050     return wuffs_base__utility__make_rect_ie_u32(0, 0, 0, 0);
9051   }
9052 
9053   return wuffs_base__utility__make_rect_ie_u32(
9054       wuffs_base__u32__min(self->private_impl.f_frame_rect_x0,
9055                            self->private_impl.f_width),
9056       wuffs_base__range_ie_u32__get_min_incl(&self->private_impl.f_dirty_y),
9057       wuffs_base__u32__min(self->private_impl.f_frame_rect_x1,
9058                            self->private_impl.f_width),
9059       wuffs_base__range_ie_u32__get_max_excl(&self->private_impl.f_dirty_y));
9060 }
9061 
9062 // -------- func gif.decoder.workbuf_len
9063 
9064 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder * self)9065 wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder* self) {
9066   if (!self) {
9067     return wuffs_base__utility__make_range_ii_u64(0, 0);
9068   }
9069   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9070       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9071     return wuffs_base__utility__make_range_ii_u64(0, 0);
9072   }
9073 
9074   return wuffs_base__utility__make_range_ii_u64(1, 1);
9075 }
9076 
9077 // -------- func gif.decoder.restart_frame
9078 
9079 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)9080 wuffs_gif__decoder__restart_frame(wuffs_gif__decoder* self,
9081                                   uint64_t a_index,
9082                                   uint64_t a_io_position) {
9083   if (!self) {
9084     return wuffs_base__error__bad_receiver;
9085   }
9086   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9087     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
9088                ? wuffs_base__error__disabled_by_previous_error
9089                : wuffs_base__error__initialize_not_called;
9090   }
9091 
9092   if (self->private_impl.f_call_sequence == 0) {
9093     return wuffs_base__error__bad_call_sequence;
9094   }
9095   self->private_impl.f_delayed_num_decoded_frames = false;
9096   self->private_impl.f_end_of_data = false;
9097   self->private_impl.f_restarted = true;
9098   self->private_impl.f_frame_config_io_position = a_io_position;
9099   self->private_impl.f_num_decoded_frame_configs_value = a_index;
9100   self->private_impl.f_num_decoded_frames_value = a_index;
9101   wuffs_gif__decoder__reset_gc(self);
9102   return NULL;
9103 }
9104 
9105 // -------- func gif.decoder.decode_frame_config
9106 
9107 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)9108 wuffs_gif__decoder__decode_frame_config(wuffs_gif__decoder* self,
9109                                         wuffs_base__frame_config* a_dst,
9110                                         wuffs_base__io_buffer* a_src) {
9111   if (!self) {
9112     return wuffs_base__error__bad_receiver;
9113   }
9114   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9115     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
9116                ? wuffs_base__error__disabled_by_previous_error
9117                : wuffs_base__error__initialize_not_called;
9118   }
9119   if (!a_src) {
9120     self->private_impl.magic = WUFFS_BASE__DISABLED;
9121     return wuffs_base__error__bad_argument;
9122   }
9123   if ((self->private_impl.active_coroutine != 0) &&
9124       (self->private_impl.active_coroutine != 3)) {
9125     self->private_impl.magic = WUFFS_BASE__DISABLED;
9126     return wuffs_base__error__interleaved_coroutine_calls;
9127   }
9128   self->private_impl.active_coroutine = 0;
9129   wuffs_base__status status = NULL;
9130 
9131   uint8_t v_blend = 0;
9132   uint32_t v_background_color = 0;
9133   uint8_t v_flags = 0;
9134 
9135   uint8_t* iop_a_src = NULL;
9136   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9137   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9138   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9139   if (a_src) {
9140     io0_a_src = a_src->data.ptr;
9141     io1_a_src = io0_a_src + a_src->meta.ri;
9142     iop_a_src = io1_a_src;
9143     io2_a_src = io0_a_src + a_src->meta.wi;
9144   }
9145 
9146   uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
9147   if (coro_susp_point) {
9148     v_blend = self->private_data.s_decode_frame_config[0].v_blend;
9149     v_background_color =
9150         self->private_data.s_decode_frame_config[0].v_background_color;
9151   }
9152   switch (coro_susp_point) {
9153     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9154 
9155     self->private_impl.f_ignore_metadata = true;
9156     (memset(&self->private_impl.f_dirty_y, 0, sizeof(wuffs_base__range_ie_u32)),
9157      wuffs_base__make_empty_struct());
9158     if (!self->private_impl.f_end_of_data) {
9159       if (self->private_impl.f_call_sequence == 0) {
9160         if (a_src) {
9161           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9162         }
9163         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9164         status = wuffs_gif__decoder__decode_image_config(self, NULL, a_src);
9165         if (a_src) {
9166           iop_a_src = a_src->data.ptr + a_src->meta.ri;
9167         }
9168         if (status) {
9169           goto suspend;
9170         }
9171       } else if (self->private_impl.f_call_sequence != 3) {
9172         if (self->private_impl.f_call_sequence == 4) {
9173           if (a_src) {
9174             a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9175           }
9176           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
9177           status = wuffs_gif__decoder__skip_frame(self, a_src);
9178           if (a_src) {
9179             iop_a_src = a_src->data.ptr + a_src->meta.ri;
9180           }
9181           if (status) {
9182             goto suspend;
9183           }
9184         }
9185         if (a_src) {
9186           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9187         }
9188         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
9189         status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
9190         if (a_src) {
9191           iop_a_src = a_src->data.ptr + a_src->meta.ri;
9192         }
9193         if (status) {
9194           goto suspend;
9195         }
9196       }
9197     }
9198     if (self->private_impl.f_end_of_data) {
9199       status = wuffs_base__warning__end_of_data;
9200       goto ok;
9201     }
9202     v_blend = 0;
9203     v_background_color = self->private_impl.f_black_color_u32_argb_premul;
9204     if (!self->private_impl.f_gc_has_transparent_index) {
9205       v_blend = 2;
9206       v_background_color =
9207           self->private_impl.f_background_color_u32_argb_premul;
9208       if (self->private_impl
9209               .f_quirk_enabled_first_frame_local_palette_means_black_background &&
9210           (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
9211         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
9212           status = wuffs_base__suspension__short_read;
9213           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
9214         }
9215         v_flags = wuffs_base__load_u8be(iop_a_src);
9216         if ((v_flags & 128) != 0) {
9217           v_background_color = self->private_impl.f_black_color_u32_argb_premul;
9218         }
9219       }
9220     }
9221     if (a_dst != NULL) {
9222       wuffs_base__frame_config__update(
9223           a_dst,
9224           wuffs_base__utility__make_rect_ie_u32(
9225               wuffs_base__u32__min(self->private_impl.f_frame_rect_x0,
9226                                    self->private_impl.f_width),
9227               wuffs_base__u32__min(self->private_impl.f_frame_rect_y0,
9228                                    self->private_impl.f_height),
9229               wuffs_base__u32__min(self->private_impl.f_frame_rect_x1,
9230                                    self->private_impl.f_width),
9231               wuffs_base__u32__min(self->private_impl.f_frame_rect_y1,
9232                                    self->private_impl.f_height)),
9233           ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
9234           self->private_impl.f_num_decoded_frame_configs_value,
9235           self->private_impl.f_frame_config_io_position, v_blend,
9236           self->private_impl.f_gc_disposal, v_background_color);
9237     }
9238     wuffs_base__u64__sat_add_indirect(
9239         &self->private_impl.f_num_decoded_frame_configs_value, 1);
9240     self->private_impl.f_call_sequence = 4;
9241 
9242     goto ok;
9243   ok:
9244     self->private_impl.p_decode_frame_config[0] = 0;
9245     goto exit;
9246   }
9247 
9248   goto suspend;
9249 suspend:
9250   self->private_impl.p_decode_frame_config[0] =
9251       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
9252   self->private_impl.active_coroutine =
9253       wuffs_base__status__is_suspension(status) ? 3 : 0;
9254   self->private_data.s_decode_frame_config[0].v_blend = v_blend;
9255   self->private_data.s_decode_frame_config[0].v_background_color =
9256       v_background_color;
9257 
9258   goto exit;
9259 exit:
9260   if (a_src) {
9261     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9262   }
9263 
9264   if (wuffs_base__status__is_error(status)) {
9265     self->private_impl.magic = WUFFS_BASE__DISABLED;
9266   }
9267   return status;
9268 }
9269 
9270 // -------- func gif.decoder.skip_frame
9271 
9272 static wuffs_base__status  //
wuffs_gif__decoder__skip_frame(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)9273 wuffs_gif__decoder__skip_frame(wuffs_gif__decoder* self,
9274                                wuffs_base__io_buffer* a_src) {
9275   wuffs_base__status status = NULL;
9276 
9277   uint8_t v_flags = 0;
9278   uint8_t v_lw = 0;
9279 
9280   uint8_t* iop_a_src = NULL;
9281   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9282   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9283   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9284   if (a_src) {
9285     io0_a_src = a_src->data.ptr;
9286     io1_a_src = io0_a_src + a_src->meta.ri;
9287     iop_a_src = io1_a_src;
9288     io2_a_src = io0_a_src + a_src->meta.wi;
9289   }
9290 
9291   uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
9292   if (coro_susp_point) {
9293   }
9294   switch (coro_susp_point) {
9295     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9296 
9297     {
9298       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9299       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9300         status = wuffs_base__suspension__short_read;
9301         goto suspend;
9302       }
9303       uint8_t t_0 = *iop_a_src++;
9304       v_flags = t_0;
9305     }
9306     if ((v_flags & 128) != 0) {
9307       self->private_data.s_skip_frame[0].scratch =
9308           (((uint32_t)(3)) << (1 + (v_flags & 7)));
9309       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
9310       if (self->private_data.s_skip_frame[0].scratch >
9311           ((uint64_t)(io2_a_src - iop_a_src))) {
9312         self->private_data.s_skip_frame[0].scratch -=
9313             ((uint64_t)(io2_a_src - iop_a_src));
9314         iop_a_src = io2_a_src;
9315         status = wuffs_base__suspension__short_read;
9316         goto suspend;
9317       }
9318       iop_a_src += self->private_data.s_skip_frame[0].scratch;
9319     }
9320     {
9321       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
9322       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9323         status = wuffs_base__suspension__short_read;
9324         goto suspend;
9325       }
9326       uint8_t t_1 = *iop_a_src++;
9327       v_lw = t_1;
9328     }
9329     if (v_lw > 8) {
9330       status = wuffs_gif__error__bad_literal_width;
9331       goto exit;
9332     }
9333     if (a_src) {
9334       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9335     }
9336     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
9337     status = wuffs_gif__decoder__skip_blocks(self, a_src);
9338     if (a_src) {
9339       iop_a_src = a_src->data.ptr + a_src->meta.ri;
9340     }
9341     if (status) {
9342       goto suspend;
9343     }
9344     if (self->private_impl.f_quirk_enabled_delay_num_decoded_frames) {
9345       self->private_impl.f_delayed_num_decoded_frames = true;
9346     } else {
9347       wuffs_base__u64__sat_add_indirect(
9348           &self->private_impl.f_num_decoded_frames_value, 1);
9349     }
9350     wuffs_gif__decoder__reset_gc(self);
9351 
9352     goto ok;
9353   ok:
9354     self->private_impl.p_skip_frame[0] = 0;
9355     goto exit;
9356   }
9357 
9358   goto suspend;
9359 suspend:
9360   self->private_impl.p_skip_frame[0] =
9361       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
9362 
9363   goto exit;
9364 exit:
9365   if (a_src) {
9366     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9367   }
9368 
9369   return status;
9370 }
9371 
9372 // -------- func gif.decoder.decode_frame
9373 
9374 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__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)9375 wuffs_gif__decoder__decode_frame(wuffs_gif__decoder* self,
9376                                  wuffs_base__pixel_buffer* a_dst,
9377                                  wuffs_base__io_buffer* a_src,
9378                                  wuffs_base__slice_u8 a_workbuf,
9379                                  wuffs_base__decode_frame_options* a_opts) {
9380   if (!self) {
9381     return wuffs_base__error__bad_receiver;
9382   }
9383   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9384     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
9385                ? wuffs_base__error__disabled_by_previous_error
9386                : wuffs_base__error__initialize_not_called;
9387   }
9388   if (!a_dst || !a_src) {
9389     self->private_impl.magic = WUFFS_BASE__DISABLED;
9390     return wuffs_base__error__bad_argument;
9391   }
9392   if ((self->private_impl.active_coroutine != 0) &&
9393       (self->private_impl.active_coroutine != 4)) {
9394     self->private_impl.magic = WUFFS_BASE__DISABLED;
9395     return wuffs_base__error__interleaved_coroutine_calls;
9396   }
9397   self->private_impl.active_coroutine = 0;
9398   wuffs_base__status status = NULL;
9399 
9400   uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
9401   if (coro_susp_point) {
9402   }
9403   switch (coro_susp_point) {
9404     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9405 
9406     self->private_impl.f_ignore_metadata = true;
9407     if (self->private_impl.f_call_sequence != 4) {
9408       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9409       status = wuffs_gif__decoder__decode_frame_config(self, NULL, a_src);
9410       if (status) {
9411         goto suspend;
9412       }
9413     }
9414     if (self->private_impl.f_quirk_enabled_reject_empty_frame &&
9415         ((self->private_impl.f_frame_rect_x0 ==
9416           self->private_impl.f_frame_rect_x1) ||
9417          (self->private_impl.f_frame_rect_y0 ==
9418           self->private_impl.f_frame_rect_y1))) {
9419       status = wuffs_gif__error__bad_frame_size;
9420       goto exit;
9421     }
9422     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
9423     status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src);
9424     if (status) {
9425       goto suspend;
9426     }
9427     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
9428     status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
9429     if (status) {
9430       goto suspend;
9431     }
9432     wuffs_base__u64__sat_add_indirect(
9433         &self->private_impl.f_num_decoded_frames_value, 1);
9434     wuffs_gif__decoder__reset_gc(self);
9435 
9436     goto ok;
9437   ok:
9438     self->private_impl.p_decode_frame[0] = 0;
9439     goto exit;
9440   }
9441 
9442   goto suspend;
9443 suspend:
9444   self->private_impl.p_decode_frame[0] =
9445       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
9446   self->private_impl.active_coroutine =
9447       wuffs_base__status__is_suspension(status) ? 4 : 0;
9448 
9449   goto exit;
9450 exit:
9451   if (wuffs_base__status__is_error(status)) {
9452     self->private_impl.magic = WUFFS_BASE__DISABLED;
9453   }
9454   return status;
9455 }
9456 
9457 // -------- func gif.decoder.reset_gc
9458 
9459 static wuffs_base__empty_struct  //
wuffs_gif__decoder__reset_gc(wuffs_gif__decoder * self)9460 wuffs_gif__decoder__reset_gc(wuffs_gif__decoder* self) {
9461   self->private_impl.f_call_sequence = 5;
9462   self->private_impl.f_gc_has_transparent_index = false;
9463   self->private_impl.f_gc_transparent_index = 0;
9464   self->private_impl.f_gc_disposal = 0;
9465   self->private_impl.f_gc_duration = 0;
9466   return wuffs_base__make_empty_struct();
9467 }
9468 
9469 // -------- func gif.decoder.decode_up_to_id_part1
9470 
9471 static wuffs_base__status  //
wuffs_gif__decoder__decode_up_to_id_part1(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)9472 wuffs_gif__decoder__decode_up_to_id_part1(wuffs_gif__decoder* self,
9473                                           wuffs_base__io_buffer* a_src) {
9474   wuffs_base__status status = NULL;
9475 
9476   uint8_t v_block_type = 0;
9477 
9478   uint8_t* iop_a_src = NULL;
9479   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9480   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9481   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9482   if (a_src) {
9483     io0_a_src = a_src->data.ptr;
9484     io1_a_src = io0_a_src + a_src->meta.ri;
9485     iop_a_src = io1_a_src;
9486     io2_a_src = io0_a_src + a_src->meta.wi;
9487   }
9488 
9489   uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
9490   if (coro_susp_point) {
9491   }
9492   switch (coro_susp_point) {
9493     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9494 
9495     if (!self->private_impl.f_restarted) {
9496       if (self->private_impl.f_call_sequence != 2) {
9497         self->private_impl.f_frame_config_io_position =
9498             (a_src ? wuffs_base__u64__sat_add(
9499                          a_src->meta.pos,
9500                          ((uint64_t)(iop_a_src - a_src->data.ptr)))
9501                    : 0);
9502       }
9503     } else if (self->private_impl.f_frame_config_io_position !=
9504                (a_src ? wuffs_base__u64__sat_add(
9505                             a_src->meta.pos,
9506                             ((uint64_t)(iop_a_src - a_src->data.ptr)))
9507                       : 0)) {
9508       status = wuffs_base__error__bad_restart;
9509       goto exit;
9510     } else {
9511       self->private_impl.f_restarted = false;
9512     }
9513     while (true) {
9514       {
9515         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9516         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9517           status = wuffs_base__suspension__short_read;
9518           goto suspend;
9519         }
9520         uint8_t t_0 = *iop_a_src++;
9521         v_block_type = t_0;
9522       }
9523       if (v_block_type == 33) {
9524         if (a_src) {
9525           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9526         }
9527         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
9528         status = wuffs_gif__decoder__decode_extension(self, a_src);
9529         if (a_src) {
9530           iop_a_src = a_src->data.ptr + a_src->meta.ri;
9531         }
9532         if (status) {
9533           goto suspend;
9534         }
9535       } else if (v_block_type == 44) {
9536         if (self->private_impl.f_delayed_num_decoded_frames) {
9537           self->private_impl.f_delayed_num_decoded_frames = false;
9538           wuffs_base__u64__sat_add_indirect(
9539               &self->private_impl.f_num_decoded_frames_value, 1);
9540         }
9541         if (a_src) {
9542           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9543         }
9544         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
9545         status = wuffs_gif__decoder__decode_id_part0(self, a_src);
9546         if (a_src) {
9547           iop_a_src = a_src->data.ptr + a_src->meta.ri;
9548         }
9549         if (status) {
9550           goto suspend;
9551         }
9552         goto label_0_break;
9553       } else if (v_block_type == 59) {
9554         if (self->private_impl.f_delayed_num_decoded_frames) {
9555           self->private_impl.f_delayed_num_decoded_frames = false;
9556           wuffs_base__u64__sat_add_indirect(
9557               &self->private_impl.f_num_decoded_frames_value, 1);
9558         }
9559         self->private_impl.f_end_of_data = true;
9560         goto label_0_break;
9561       } else {
9562         status = wuffs_gif__error__bad_block;
9563         goto exit;
9564       }
9565     }
9566   label_0_break:;
9567 
9568     goto ok;
9569   ok:
9570     self->private_impl.p_decode_up_to_id_part1[0] = 0;
9571     goto exit;
9572   }
9573 
9574   goto suspend;
9575 suspend:
9576   self->private_impl.p_decode_up_to_id_part1[0] =
9577       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
9578 
9579   goto exit;
9580 exit:
9581   if (a_src) {
9582     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9583   }
9584 
9585   return status;
9586 }
9587 
9588 // -------- func gif.decoder.decode_header
9589 
9590 static wuffs_base__status  //
wuffs_gif__decoder__decode_header(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)9591 wuffs_gif__decoder__decode_header(wuffs_gif__decoder* self,
9592                                   wuffs_base__io_buffer* a_src) {
9593   wuffs_base__status status = NULL;
9594 
9595   uint8_t v_c[6] = {0};
9596   uint32_t v_i = 0;
9597 
9598   uint8_t* iop_a_src = NULL;
9599   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9600   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9601   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9602   if (a_src) {
9603     io0_a_src = a_src->data.ptr;
9604     io1_a_src = io0_a_src + a_src->meta.ri;
9605     iop_a_src = io1_a_src;
9606     io2_a_src = io0_a_src + a_src->meta.wi;
9607   }
9608 
9609   uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
9610   if (coro_susp_point) {
9611     memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
9612     v_i = self->private_data.s_decode_header[0].v_i;
9613   }
9614   switch (coro_susp_point) {
9615     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9616 
9617     while (v_i < 6) {
9618       {
9619         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9620         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9621           status = wuffs_base__suspension__short_read;
9622           goto suspend;
9623         }
9624         uint8_t t_0 = *iop_a_src++;
9625         v_c[v_i] = t_0;
9626       }
9627       v_i += 1;
9628     }
9629     if ((v_c[0] != 71) || (v_c[1] != 73) || (v_c[2] != 70) || (v_c[3] != 56) ||
9630         ((v_c[4] != 55) && (v_c[4] != 57)) || (v_c[5] != 97)) {
9631       status = wuffs_gif__error__bad_header;
9632       goto exit;
9633     }
9634 
9635     goto ok;
9636   ok:
9637     self->private_impl.p_decode_header[0] = 0;
9638     goto exit;
9639   }
9640 
9641   goto suspend;
9642 suspend:
9643   self->private_impl.p_decode_header[0] =
9644       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
9645   memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
9646   self->private_data.s_decode_header[0].v_i = v_i;
9647 
9648   goto exit;
9649 exit:
9650   if (a_src) {
9651     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9652   }
9653 
9654   return status;
9655 }
9656 
9657 // -------- func gif.decoder.decode_lsd
9658 
9659 static wuffs_base__status  //
wuffs_gif__decoder__decode_lsd(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)9660 wuffs_gif__decoder__decode_lsd(wuffs_gif__decoder* self,
9661                                wuffs_base__io_buffer* a_src) {
9662   wuffs_base__status status = NULL;
9663 
9664   uint8_t v_flags = 0;
9665   uint8_t v_background_color_index = 0;
9666   uint32_t v_num_palette_entries = 0;
9667   uint32_t v_i = 0;
9668   uint32_t v_j = 0;
9669   uint32_t v_argb = 0;
9670 
9671   uint8_t* iop_a_src = NULL;
9672   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9673   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9674   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9675   if (a_src) {
9676     io0_a_src = a_src->data.ptr;
9677     io1_a_src = io0_a_src + a_src->meta.ri;
9678     iop_a_src = io1_a_src;
9679     io2_a_src = io0_a_src + a_src->meta.wi;
9680   }
9681 
9682   uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
9683   if (coro_susp_point) {
9684     v_flags = self->private_data.s_decode_lsd[0].v_flags;
9685     v_background_color_index =
9686         self->private_data.s_decode_lsd[0].v_background_color_index;
9687     v_num_palette_entries =
9688         self->private_data.s_decode_lsd[0].v_num_palette_entries;
9689     v_i = self->private_data.s_decode_lsd[0].v_i;
9690   }
9691   switch (coro_susp_point) {
9692     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9693 
9694     {
9695       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9696       uint32_t t_0;
9697       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
9698         t_0 = ((uint32_t)(wuffs_base__load_u16le(iop_a_src)));
9699         iop_a_src += 2;
9700       } else {
9701         self->private_data.s_decode_lsd[0].scratch = 0;
9702         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
9703         while (true) {
9704           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9705             status = wuffs_base__suspension__short_read;
9706             goto suspend;
9707           }
9708           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
9709           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
9710           *scratch <<= 8;
9711           *scratch >>= 8;
9712           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
9713           if (num_bits_0 == 8) {
9714             t_0 = ((uint32_t)(*scratch));
9715             break;
9716           }
9717           num_bits_0 += 8;
9718           *scratch |= ((uint64_t)(num_bits_0)) << 56;
9719         }
9720       }
9721       self->private_impl.f_width = t_0;
9722     }
9723     {
9724       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
9725       uint32_t t_1;
9726       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
9727         t_1 = ((uint32_t)(wuffs_base__load_u16le(iop_a_src)));
9728         iop_a_src += 2;
9729       } else {
9730         self->private_data.s_decode_lsd[0].scratch = 0;
9731         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
9732         while (true) {
9733           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9734             status = wuffs_base__suspension__short_read;
9735             goto suspend;
9736           }
9737           uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
9738           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
9739           *scratch <<= 8;
9740           *scratch >>= 8;
9741           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
9742           if (num_bits_1 == 8) {
9743             t_1 = ((uint32_t)(*scratch));
9744             break;
9745           }
9746           num_bits_1 += 8;
9747           *scratch |= ((uint64_t)(num_bits_1)) << 56;
9748         }
9749       }
9750       self->private_impl.f_height = t_1;
9751     }
9752     {
9753       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
9754       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9755         status = wuffs_base__suspension__short_read;
9756         goto suspend;
9757       }
9758       uint8_t t_2 = *iop_a_src++;
9759       v_flags = t_2;
9760     }
9761     {
9762       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
9763       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9764         status = wuffs_base__suspension__short_read;
9765         goto suspend;
9766       }
9767       uint8_t t_3 = *iop_a_src++;
9768       v_background_color_index = t_3;
9769     }
9770     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
9771     if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9772       status = wuffs_base__suspension__short_read;
9773       goto suspend;
9774     }
9775     iop_a_src++;
9776     v_i = 0;
9777     self->private_impl.f_has_global_palette = ((v_flags & 128) != 0);
9778     if (self->private_impl.f_has_global_palette) {
9779       v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
9780       while (v_i < v_num_palette_entries) {
9781         {
9782           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
9783           uint32_t t_4;
9784           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
9785             t_4 = ((uint32_t)(wuffs_base__load_u24be(iop_a_src)));
9786             iop_a_src += 3;
9787           } else {
9788             self->private_data.s_decode_lsd[0].scratch = 0;
9789             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
9790             while (true) {
9791               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9792                 status = wuffs_base__suspension__short_read;
9793                 goto suspend;
9794               }
9795               uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
9796               uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
9797               *scratch >>= 8;
9798               *scratch <<= 8;
9799               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
9800               if (num_bits_4 == 16) {
9801                 t_4 = ((uint32_t)(*scratch >> 40));
9802                 break;
9803               }
9804               num_bits_4 += 8;
9805               *scratch |= ((uint64_t)(num_bits_4));
9806             }
9807           }
9808           v_argb = t_4;
9809         }
9810         v_argb |= 4278190080;
9811         self->private_data.f_palettes[0][((4 * v_i) + 0)] =
9812             ((uint8_t)(((v_argb >> 0) & 255)));
9813         self->private_data.f_palettes[0][((4 * v_i) + 1)] =
9814             ((uint8_t)(((v_argb >> 8) & 255)));
9815         self->private_data.f_palettes[0][((4 * v_i) + 2)] =
9816             ((uint8_t)(((v_argb >> 16) & 255)));
9817         self->private_data.f_palettes[0][((4 * v_i) + 3)] =
9818             ((uint8_t)(((v_argb >> 24) & 255)));
9819         v_i += 1;
9820       }
9821       if (self->private_impl.f_quirk_enabled_honor_background_color) {
9822         if ((v_background_color_index != 0) &&
9823             (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
9824           v_j = (4 * ((uint32_t)(v_background_color_index)));
9825           self->private_impl.f_background_color_u32_argb_premul =
9826               ((((uint32_t)(self->private_data.f_palettes[0][(v_j + 0)]))
9827                 << 0) |
9828                (((uint32_t)(self->private_data.f_palettes[0][(v_j + 1)]))
9829                 << 8) |
9830                (((uint32_t)(self->private_data.f_palettes[0][(v_j + 2)]))
9831                 << 16) |
9832                (((uint32_t)(self->private_data.f_palettes[0][(v_j + 3)]))
9833                 << 24));
9834         } else {
9835           self->private_impl.f_background_color_u32_argb_premul = 77;
9836         }
9837       }
9838     }
9839     while (v_i < 256) {
9840       self->private_data.f_palettes[0][((4 * v_i) + 0)] = 0;
9841       self->private_data.f_palettes[0][((4 * v_i) + 1)] = 0;
9842       self->private_data.f_palettes[0][((4 * v_i) + 2)] = 0;
9843       self->private_data.f_palettes[0][((4 * v_i) + 3)] = 255;
9844       v_i += 1;
9845     }
9846 
9847     goto ok;
9848   ok:
9849     self->private_impl.p_decode_lsd[0] = 0;
9850     goto exit;
9851   }
9852 
9853   goto suspend;
9854 suspend:
9855   self->private_impl.p_decode_lsd[0] =
9856       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
9857   self->private_data.s_decode_lsd[0].v_flags = v_flags;
9858   self->private_data.s_decode_lsd[0].v_background_color_index =
9859       v_background_color_index;
9860   self->private_data.s_decode_lsd[0].v_num_palette_entries =
9861       v_num_palette_entries;
9862   self->private_data.s_decode_lsd[0].v_i = v_i;
9863 
9864   goto exit;
9865 exit:
9866   if (a_src) {
9867     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9868   }
9869 
9870   return status;
9871 }
9872 
9873 // -------- func gif.decoder.decode_extension
9874 
9875 static wuffs_base__status  //
wuffs_gif__decoder__decode_extension(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)9876 wuffs_gif__decoder__decode_extension(wuffs_gif__decoder* self,
9877                                      wuffs_base__io_buffer* a_src) {
9878   wuffs_base__status status = NULL;
9879 
9880   uint8_t v_label = 0;
9881 
9882   uint8_t* iop_a_src = NULL;
9883   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9884   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9885   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9886   if (a_src) {
9887     io0_a_src = a_src->data.ptr;
9888     io1_a_src = io0_a_src + a_src->meta.ri;
9889     iop_a_src = io1_a_src;
9890     io2_a_src = io0_a_src + a_src->meta.wi;
9891   }
9892 
9893   uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
9894   if (coro_susp_point) {
9895   }
9896   switch (coro_susp_point) {
9897     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9898 
9899     {
9900       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9901       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9902         status = wuffs_base__suspension__short_read;
9903         goto suspend;
9904       }
9905       uint8_t t_0 = *iop_a_src++;
9906       v_label = t_0;
9907     }
9908     if (v_label == 249) {
9909       if (a_src) {
9910         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9911       }
9912       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
9913       status = wuffs_gif__decoder__decode_gc(self, a_src);
9914       if (a_src) {
9915         iop_a_src = a_src->data.ptr + a_src->meta.ri;
9916       }
9917       if (status) {
9918         goto suspend;
9919       }
9920       status = NULL;
9921       goto ok;
9922     } else if (v_label == 255) {
9923       if (a_src) {
9924         a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9925       }
9926       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
9927       status = wuffs_gif__decoder__decode_ae(self, a_src);
9928       if (a_src) {
9929         iop_a_src = a_src->data.ptr + a_src->meta.ri;
9930       }
9931       if (status) {
9932         goto suspend;
9933       }
9934       status = NULL;
9935       goto ok;
9936     }
9937     if (a_src) {
9938       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9939     }
9940     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
9941     status = wuffs_gif__decoder__skip_blocks(self, a_src);
9942     if (a_src) {
9943       iop_a_src = a_src->data.ptr + a_src->meta.ri;
9944     }
9945     if (status) {
9946       goto suspend;
9947     }
9948 
9949     goto ok;
9950   ok:
9951     self->private_impl.p_decode_extension[0] = 0;
9952     goto exit;
9953   }
9954 
9955   goto suspend;
9956 suspend:
9957   self->private_impl.p_decode_extension[0] =
9958       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
9959 
9960   goto exit;
9961 exit:
9962   if (a_src) {
9963     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
9964   }
9965 
9966   return status;
9967 }
9968 
9969 // -------- func gif.decoder.skip_blocks
9970 
9971 static wuffs_base__status  //
wuffs_gif__decoder__skip_blocks(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)9972 wuffs_gif__decoder__skip_blocks(wuffs_gif__decoder* self,
9973                                 wuffs_base__io_buffer* a_src) {
9974   wuffs_base__status status = NULL;
9975 
9976   uint8_t v_block_size = 0;
9977 
9978   uint8_t* iop_a_src = NULL;
9979   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9980   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9981   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
9982   if (a_src) {
9983     io0_a_src = a_src->data.ptr;
9984     io1_a_src = io0_a_src + a_src->meta.ri;
9985     iop_a_src = io1_a_src;
9986     io2_a_src = io0_a_src + a_src->meta.wi;
9987   }
9988 
9989   uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
9990   if (coro_susp_point) {
9991   }
9992   switch (coro_susp_point) {
9993     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
9994 
9995     while (true) {
9996       {
9997         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
9998         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
9999           status = wuffs_base__suspension__short_read;
10000           goto suspend;
10001         }
10002         uint8_t t_0 = *iop_a_src++;
10003         v_block_size = t_0;
10004       }
10005       if (v_block_size == 0) {
10006         status = NULL;
10007         goto ok;
10008       }
10009       self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
10010       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
10011       if (self->private_data.s_skip_blocks[0].scratch >
10012           ((uint64_t)(io2_a_src - iop_a_src))) {
10013         self->private_data.s_skip_blocks[0].scratch -=
10014             ((uint64_t)(io2_a_src - iop_a_src));
10015         iop_a_src = io2_a_src;
10016         status = wuffs_base__suspension__short_read;
10017         goto suspend;
10018       }
10019       iop_a_src += self->private_data.s_skip_blocks[0].scratch;
10020     }
10021 
10022     goto ok;
10023   ok:
10024     self->private_impl.p_skip_blocks[0] = 0;
10025     goto exit;
10026   }
10027 
10028   goto suspend;
10029 suspend:
10030   self->private_impl.p_skip_blocks[0] =
10031       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
10032 
10033   goto exit;
10034 exit:
10035   if (a_src) {
10036     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
10037   }
10038 
10039   return status;
10040 }
10041 
10042 // -------- func gif.decoder.decode_ae
10043 
10044 static wuffs_base__status  //
wuffs_gif__decoder__decode_ae(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)10045 wuffs_gif__decoder__decode_ae(wuffs_gif__decoder* self,
10046                               wuffs_base__io_buffer* a_src) {
10047   wuffs_base__status status = NULL;
10048 
10049   uint8_t v_c = 0;
10050   uint8_t v_block_size = 0;
10051   bool v_is_animexts = false;
10052   bool v_is_netscape = false;
10053   bool v_is_iccp = false;
10054   bool v_is_xmp = false;
10055 
10056   uint8_t* iop_a_src = NULL;
10057   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10058   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10059   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10060   if (a_src) {
10061     io0_a_src = a_src->data.ptr;
10062     io1_a_src = io0_a_src + a_src->meta.ri;
10063     iop_a_src = io1_a_src;
10064     io2_a_src = io0_a_src + a_src->meta.wi;
10065   }
10066 
10067   uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
10068   if (coro_susp_point) {
10069     v_block_size = self->private_data.s_decode_ae[0].v_block_size;
10070     v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
10071     v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
10072     v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
10073     v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
10074   }
10075   switch (coro_susp_point) {
10076     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
10077 
10078     while (true) {
10079       {
10080         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
10081         if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10082           status = wuffs_base__suspension__short_read;
10083           goto suspend;
10084         }
10085         uint8_t t_0 = *iop_a_src++;
10086         v_block_size = t_0;
10087       }
10088       if (v_block_size == 0) {
10089         status = NULL;
10090         goto ok;
10091       }
10092       if (v_block_size != 11) {
10093         self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
10094         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
10095         if (self->private_data.s_decode_ae[0].scratch >
10096             ((uint64_t)(io2_a_src - iop_a_src))) {
10097           self->private_data.s_decode_ae[0].scratch -=
10098               ((uint64_t)(io2_a_src - iop_a_src));
10099           iop_a_src = io2_a_src;
10100           status = wuffs_base__suspension__short_read;
10101           goto suspend;
10102         }
10103         iop_a_src += self->private_data.s_decode_ae[0].scratch;
10104         goto label_0_break;
10105       }
10106       v_is_animexts = true;
10107       v_is_netscape = true;
10108       v_is_iccp = true;
10109       v_is_xmp = true;
10110       v_block_size = 0;
10111       while (v_block_size < 11) {
10112         {
10113           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
10114           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10115             status = wuffs_base__suspension__short_read;
10116             goto suspend;
10117           }
10118           uint8_t t_1 = *iop_a_src++;
10119           v_c = t_1;
10120         }
10121         v_is_animexts =
10122             (v_is_animexts && (v_c == wuffs_gif__animexts1dot0[v_block_size]));
10123         v_is_netscape =
10124             (v_is_netscape && (v_c == wuffs_gif__netscape2dot0[v_block_size]));
10125         v_is_iccp =
10126             (v_is_iccp && (v_c == wuffs_gif__iccrgbg1012[v_block_size]));
10127         v_is_xmp = (v_is_xmp && (v_c == wuffs_gif__xmpdataxmp[v_block_size]));
10128 #if defined(__GNUC__)
10129 #pragma GCC diagnostic push
10130 #pragma GCC diagnostic ignored "-Wconversion"
10131 #endif
10132         v_block_size += 1;
10133 #if defined(__GNUC__)
10134 #pragma GCC diagnostic pop
10135 #endif
10136       }
10137       if (v_is_animexts || v_is_netscape) {
10138         {
10139           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
10140           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10141             status = wuffs_base__suspension__short_read;
10142             goto suspend;
10143           }
10144           uint8_t t_2 = *iop_a_src++;
10145           v_block_size = t_2;
10146         }
10147         if (v_block_size != 3) {
10148           self->private_data.s_decode_ae[0].scratch =
10149               ((uint32_t)(v_block_size));
10150           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
10151           if (self->private_data.s_decode_ae[0].scratch >
10152               ((uint64_t)(io2_a_src - iop_a_src))) {
10153             self->private_data.s_decode_ae[0].scratch -=
10154                 ((uint64_t)(io2_a_src - iop_a_src));
10155             iop_a_src = io2_a_src;
10156             status = wuffs_base__suspension__short_read;
10157             goto suspend;
10158           }
10159           iop_a_src += self->private_data.s_decode_ae[0].scratch;
10160           goto label_0_break;
10161         }
10162         {
10163           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
10164           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10165             status = wuffs_base__suspension__short_read;
10166             goto suspend;
10167           }
10168           uint8_t t_3 = *iop_a_src++;
10169           v_c = t_3;
10170         }
10171         if (v_c != 1) {
10172           self->private_data.s_decode_ae[0].scratch = 2;
10173           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
10174           if (self->private_data.s_decode_ae[0].scratch >
10175               ((uint64_t)(io2_a_src - iop_a_src))) {
10176             self->private_data.s_decode_ae[0].scratch -=
10177                 ((uint64_t)(io2_a_src - iop_a_src));
10178             iop_a_src = io2_a_src;
10179             status = wuffs_base__suspension__short_read;
10180             goto suspend;
10181           }
10182           iop_a_src += self->private_data.s_decode_ae[0].scratch;
10183           goto label_0_break;
10184         }
10185         {
10186           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
10187           uint32_t t_4;
10188           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
10189             t_4 = ((uint32_t)(wuffs_base__load_u16le(iop_a_src)));
10190             iop_a_src += 2;
10191           } else {
10192             self->private_data.s_decode_ae[0].scratch = 0;
10193             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
10194             while (true) {
10195               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10196                 status = wuffs_base__suspension__short_read;
10197                 goto suspend;
10198               }
10199               uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
10200               uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
10201               *scratch <<= 8;
10202               *scratch >>= 8;
10203               *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
10204               if (num_bits_4 == 8) {
10205                 t_4 = ((uint32_t)(*scratch));
10206                 break;
10207               }
10208               num_bits_4 += 8;
10209               *scratch |= ((uint64_t)(num_bits_4)) << 56;
10210             }
10211           }
10212           self->private_impl.f_num_loops = t_4;
10213         }
10214         self->private_impl.f_seen_num_loops = true;
10215         if ((0 < self->private_impl.f_num_loops) &&
10216             (self->private_impl.f_num_loops <= 65535)) {
10217           self->private_impl.f_num_loops += 1;
10218         }
10219       } else if (self->private_impl.f_ignore_metadata) {
10220       } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
10221         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
10222           status = wuffs_base__suspension__short_read;
10223           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
10224         }
10225         self->private_impl.f_metadata_chunk_length_value =
10226             ((uint64_t)(wuffs_base__load_u8be(iop_a_src)));
10227         (iop_a_src += 1, wuffs_base__make_empty_struct());
10228         self->private_impl.f_metadata_fourcc_value = 1229144912;
10229         self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(
10230             (a_src ? wuffs_base__u64__sat_add(
10231                          a_src->meta.pos,
10232                          ((uint64_t)(iop_a_src - a_src->data.ptr)))
10233                    : 0),
10234             self->private_impl.f_metadata_chunk_length_value);
10235         self->private_impl.f_call_sequence = 1;
10236         status = wuffs_base__warning__metadata_reported;
10237         goto ok;
10238       } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
10239         while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
10240           status = wuffs_base__suspension__short_read;
10241           WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
10242         }
10243         self->private_impl.f_metadata_chunk_length_value =
10244             (((uint64_t)(wuffs_base__load_u8be(iop_a_src))) + 1);
10245         self->private_impl.f_metadata_fourcc_value = 1481461792;
10246         self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(
10247             (a_src ? wuffs_base__u64__sat_add(
10248                          a_src->meta.pos,
10249                          ((uint64_t)(iop_a_src - a_src->data.ptr)))
10250                    : 0),
10251             self->private_impl.f_metadata_chunk_length_value);
10252         self->private_impl.f_call_sequence = 1;
10253         status = wuffs_base__warning__metadata_reported;
10254         goto ok;
10255       }
10256       goto label_0_break;
10257     }
10258   label_0_break:;
10259     if (a_src) {
10260       a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
10261     }
10262     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
10263     status = wuffs_gif__decoder__skip_blocks(self, a_src);
10264     if (a_src) {
10265       iop_a_src = a_src->data.ptr + a_src->meta.ri;
10266     }
10267     if (status) {
10268       goto suspend;
10269     }
10270 
10271     goto ok;
10272   ok:
10273     self->private_impl.p_decode_ae[0] = 0;
10274     goto exit;
10275   }
10276 
10277   goto suspend;
10278 suspend:
10279   self->private_impl.p_decode_ae[0] =
10280       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
10281   self->private_data.s_decode_ae[0].v_block_size = v_block_size;
10282   self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
10283   self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
10284   self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
10285   self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
10286 
10287   goto exit;
10288 exit:
10289   if (a_src) {
10290     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
10291   }
10292 
10293   return status;
10294 }
10295 
10296 // -------- func gif.decoder.decode_gc
10297 
10298 static wuffs_base__status  //
wuffs_gif__decoder__decode_gc(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)10299 wuffs_gif__decoder__decode_gc(wuffs_gif__decoder* self,
10300                               wuffs_base__io_buffer* a_src) {
10301   wuffs_base__status status = NULL;
10302 
10303   uint8_t v_c = 0;
10304   uint8_t v_flags = 0;
10305   uint16_t v_gc_duration_centiseconds = 0;
10306 
10307   uint8_t* iop_a_src = NULL;
10308   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10309   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10310   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10311   if (a_src) {
10312     io0_a_src = a_src->data.ptr;
10313     io1_a_src = io0_a_src + a_src->meta.ri;
10314     iop_a_src = io1_a_src;
10315     io2_a_src = io0_a_src + a_src->meta.wi;
10316   }
10317 
10318   uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
10319   if (coro_susp_point) {
10320   }
10321   switch (coro_susp_point) {
10322     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
10323 
10324     {
10325       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
10326       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10327         status = wuffs_base__suspension__short_read;
10328         goto suspend;
10329       }
10330       uint8_t t_0 = *iop_a_src++;
10331       v_c = t_0;
10332     }
10333     if (v_c != 4) {
10334       status = wuffs_gif__error__bad_graphic_control;
10335       goto exit;
10336     }
10337     {
10338       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
10339       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10340         status = wuffs_base__suspension__short_read;
10341         goto suspend;
10342       }
10343       uint8_t t_1 = *iop_a_src++;
10344       v_flags = t_1;
10345     }
10346     self->private_impl.f_gc_has_transparent_index = ((v_flags & 1) != 0);
10347     v_flags = ((v_flags >> 2) & 7);
10348     if (v_flags == 2) {
10349       self->private_impl.f_gc_disposal = 1;
10350     } else if ((v_flags == 3) || (v_flags == 4)) {
10351       self->private_impl.f_gc_disposal = 2;
10352     } else {
10353       self->private_impl.f_gc_disposal = 0;
10354     }
10355     {
10356       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
10357       uint16_t t_2;
10358       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
10359         t_2 = wuffs_base__load_u16le(iop_a_src);
10360         iop_a_src += 2;
10361       } else {
10362         self->private_data.s_decode_gc[0].scratch = 0;
10363         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
10364         while (true) {
10365           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10366             status = wuffs_base__suspension__short_read;
10367             goto suspend;
10368           }
10369           uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
10370           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
10371           *scratch <<= 8;
10372           *scratch >>= 8;
10373           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
10374           if (num_bits_2 == 8) {
10375             t_2 = ((uint16_t)(*scratch));
10376             break;
10377           }
10378           num_bits_2 += 8;
10379           *scratch |= ((uint64_t)(num_bits_2)) << 56;
10380         }
10381       }
10382       v_gc_duration_centiseconds = t_2;
10383     }
10384     self->private_impl.f_gc_duration =
10385         (((uint64_t)(v_gc_duration_centiseconds)) * 7056000);
10386     {
10387       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
10388       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10389         status = wuffs_base__suspension__short_read;
10390         goto suspend;
10391       }
10392       uint8_t t_3 = *iop_a_src++;
10393       self->private_impl.f_gc_transparent_index = t_3;
10394     }
10395     {
10396       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
10397       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10398         status = wuffs_base__suspension__short_read;
10399         goto suspend;
10400       }
10401       uint8_t t_4 = *iop_a_src++;
10402       v_c = t_4;
10403     }
10404     if (v_c != 0) {
10405       status = wuffs_gif__error__bad_graphic_control;
10406       goto exit;
10407     }
10408 
10409     goto ok;
10410   ok:
10411     self->private_impl.p_decode_gc[0] = 0;
10412     goto exit;
10413   }
10414 
10415   goto suspend;
10416 suspend:
10417   self->private_impl.p_decode_gc[0] =
10418       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
10419 
10420   goto exit;
10421 exit:
10422   if (a_src) {
10423     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
10424   }
10425 
10426   return status;
10427 }
10428 
10429 // -------- func gif.decoder.decode_id_part0
10430 
10431 static wuffs_base__status  //
wuffs_gif__decoder__decode_id_part0(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)10432 wuffs_gif__decoder__decode_id_part0(wuffs_gif__decoder* self,
10433                                     wuffs_base__io_buffer* a_src) {
10434   wuffs_base__status status = NULL;
10435 
10436   uint8_t* iop_a_src = NULL;
10437   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10438   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10439   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10440   if (a_src) {
10441     io0_a_src = a_src->data.ptr;
10442     io1_a_src = io0_a_src + a_src->meta.ri;
10443     iop_a_src = io1_a_src;
10444     io2_a_src = io0_a_src + a_src->meta.wi;
10445   }
10446 
10447   uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
10448   if (coro_susp_point) {
10449   }
10450   switch (coro_susp_point) {
10451     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
10452 
10453     {
10454       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
10455       uint32_t t_0;
10456       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
10457         t_0 = ((uint32_t)(wuffs_base__load_u16le(iop_a_src)));
10458         iop_a_src += 2;
10459       } else {
10460         self->private_data.s_decode_id_part0[0].scratch = 0;
10461         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
10462         while (true) {
10463           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10464             status = wuffs_base__suspension__short_read;
10465             goto suspend;
10466           }
10467           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
10468           uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
10469           *scratch <<= 8;
10470           *scratch >>= 8;
10471           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
10472           if (num_bits_0 == 8) {
10473             t_0 = ((uint32_t)(*scratch));
10474             break;
10475           }
10476           num_bits_0 += 8;
10477           *scratch |= ((uint64_t)(num_bits_0)) << 56;
10478         }
10479       }
10480       self->private_impl.f_frame_rect_x0 = t_0;
10481     }
10482     {
10483       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
10484       uint32_t t_1;
10485       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
10486         t_1 = ((uint32_t)(wuffs_base__load_u16le(iop_a_src)));
10487         iop_a_src += 2;
10488       } else {
10489         self->private_data.s_decode_id_part0[0].scratch = 0;
10490         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
10491         while (true) {
10492           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10493             status = wuffs_base__suspension__short_read;
10494             goto suspend;
10495           }
10496           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
10497           uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
10498           *scratch <<= 8;
10499           *scratch >>= 8;
10500           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
10501           if (num_bits_1 == 8) {
10502             t_1 = ((uint32_t)(*scratch));
10503             break;
10504           }
10505           num_bits_1 += 8;
10506           *scratch |= ((uint64_t)(num_bits_1)) << 56;
10507         }
10508       }
10509       self->private_impl.f_frame_rect_y0 = t_1;
10510     }
10511     {
10512       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
10513       uint32_t t_2;
10514       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
10515         t_2 = ((uint32_t)(wuffs_base__load_u16le(iop_a_src)));
10516         iop_a_src += 2;
10517       } else {
10518         self->private_data.s_decode_id_part0[0].scratch = 0;
10519         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
10520         while (true) {
10521           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10522             status = wuffs_base__suspension__short_read;
10523             goto suspend;
10524           }
10525           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
10526           uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
10527           *scratch <<= 8;
10528           *scratch >>= 8;
10529           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
10530           if (num_bits_2 == 8) {
10531             t_2 = ((uint32_t)(*scratch));
10532             break;
10533           }
10534           num_bits_2 += 8;
10535           *scratch |= ((uint64_t)(num_bits_2)) << 56;
10536         }
10537       }
10538       self->private_impl.f_frame_rect_x1 = t_2;
10539     }
10540     self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
10541     {
10542       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
10543       uint32_t t_3;
10544       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
10545         t_3 = ((uint32_t)(wuffs_base__load_u16le(iop_a_src)));
10546         iop_a_src += 2;
10547       } else {
10548         self->private_data.s_decode_id_part0[0].scratch = 0;
10549         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
10550         while (true) {
10551           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10552             status = wuffs_base__suspension__short_read;
10553             goto suspend;
10554           }
10555           uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
10556           uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
10557           *scratch <<= 8;
10558           *scratch >>= 8;
10559           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
10560           if (num_bits_3 == 8) {
10561             t_3 = ((uint32_t)(*scratch));
10562             break;
10563           }
10564           num_bits_3 += 8;
10565           *scratch |= ((uint64_t)(num_bits_3)) << 56;
10566         }
10567       }
10568       self->private_impl.f_frame_rect_y1 = t_3;
10569     }
10570     self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
10571     self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
10572     self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
10573     if ((self->private_impl.f_call_sequence == 0) &&
10574         !self->private_impl.f_quirk_enabled_image_bounds_are_strict) {
10575       self->private_impl.f_width = wuffs_base__u32__max(
10576           self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
10577       self->private_impl.f_height = wuffs_base__u32__max(
10578           self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
10579     }
10580 
10581     goto ok;
10582   ok:
10583     self->private_impl.p_decode_id_part0[0] = 0;
10584     goto exit;
10585   }
10586 
10587   goto suspend;
10588 suspend:
10589   self->private_impl.p_decode_id_part0[0] =
10590       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
10591 
10592   goto exit;
10593 exit:
10594   if (a_src) {
10595     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
10596   }
10597 
10598   return status;
10599 }
10600 
10601 // -------- func gif.decoder.decode_id_part1
10602 
10603 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)10604 wuffs_gif__decoder__decode_id_part1(wuffs_gif__decoder* self,
10605                                     wuffs_base__pixel_buffer* a_dst,
10606                                     wuffs_base__io_buffer* a_src) {
10607   wuffs_base__status status = NULL;
10608 
10609   uint8_t v_flags = 0;
10610   uint8_t v_which_palette = 0;
10611   uint32_t v_num_palette_entries = 0;
10612   uint32_t v_i = 0;
10613   uint32_t v_argb = 0;
10614   wuffs_base__slice_u8 v_dst_palette = {0};
10615   wuffs_base__status v_status = NULL;
10616   uint8_t v_lw = 0;
10617 
10618   uint8_t* iop_a_src = NULL;
10619   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10620   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10621   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10622   if (a_src) {
10623     io0_a_src = a_src->data.ptr;
10624     io1_a_src = io0_a_src + a_src->meta.ri;
10625     iop_a_src = io1_a_src;
10626     io2_a_src = io0_a_src + a_src->meta.wi;
10627   }
10628 
10629   uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0];
10630   if (coro_susp_point) {
10631     v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette;
10632     v_num_palette_entries =
10633         self->private_data.s_decode_id_part1[0].v_num_palette_entries;
10634     v_i = self->private_data.s_decode_id_part1[0].v_i;
10635   }
10636   switch (coro_susp_point) {
10637     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
10638 
10639     {
10640       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
10641       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10642         status = wuffs_base__suspension__short_read;
10643         goto suspend;
10644       }
10645       uint8_t t_0 = *iop_a_src++;
10646       v_flags = t_0;
10647     }
10648     if ((v_flags & 64) != 0) {
10649       self->private_impl.f_interlace = 4;
10650     } else {
10651       self->private_impl.f_interlace = 0;
10652     }
10653     v_which_palette = 1;
10654     if ((v_flags & 128) != 0) {
10655       v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
10656       v_i = 0;
10657       while (v_i < v_num_palette_entries) {
10658         {
10659           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
10660           uint32_t t_1;
10661           if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
10662             t_1 = ((uint32_t)(wuffs_base__load_u24be(iop_a_src)));
10663             iop_a_src += 3;
10664           } else {
10665             self->private_data.s_decode_id_part1[0].scratch = 0;
10666             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
10667             while (true) {
10668               if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10669                 status = wuffs_base__suspension__short_read;
10670                 goto suspend;
10671               }
10672               uint64_t* scratch =
10673                   &self->private_data.s_decode_id_part1[0].scratch;
10674               uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
10675               *scratch >>= 8;
10676               *scratch <<= 8;
10677               *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
10678               if (num_bits_1 == 16) {
10679                 t_1 = ((uint32_t)(*scratch >> 40));
10680                 break;
10681               }
10682               num_bits_1 += 8;
10683               *scratch |= ((uint64_t)(num_bits_1));
10684             }
10685           }
10686           v_argb = t_1;
10687         }
10688         v_argb |= 4278190080;
10689         self->private_data.f_palettes[1][((4 * v_i) + 0)] =
10690             ((uint8_t)(((v_argb >> 0) & 255)));
10691         self->private_data.f_palettes[1][((4 * v_i) + 1)] =
10692             ((uint8_t)(((v_argb >> 8) & 255)));
10693         self->private_data.f_palettes[1][((4 * v_i) + 2)] =
10694             ((uint8_t)(((v_argb >> 16) & 255)));
10695         self->private_data.f_palettes[1][((4 * v_i) + 3)] =
10696             ((uint8_t)(((v_argb >> 24) & 255)));
10697         v_i += 1;
10698       }
10699       while (v_i < 256) {
10700         self->private_data.f_palettes[1][((4 * v_i) + 0)] = 0;
10701         self->private_data.f_palettes[1][((4 * v_i) + 1)] = 0;
10702         self->private_data.f_palettes[1][((4 * v_i) + 2)] = 0;
10703         self->private_data.f_palettes[1][((4 * v_i) + 3)] = 255;
10704         v_i += 1;
10705       }
10706     } else if (self->private_impl.f_quirk_enabled_reject_empty_palette &&
10707                !self->private_impl.f_has_global_palette) {
10708       status = wuffs_gif__error__bad_palette;
10709       goto exit;
10710     } else if (self->private_impl.f_gc_has_transparent_index) {
10711       wuffs_base__slice_u8__copy_from_slice(
10712           wuffs_base__make_slice_u8(self->private_data.f_palettes[1], 1024),
10713           wuffs_base__make_slice_u8(self->private_data.f_palettes[0], 1024));
10714     } else {
10715       v_which_palette = 0;
10716     }
10717     if (self->private_impl.f_gc_has_transparent_index) {
10718       self->private_data.f_palettes[1][(
10719           (4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0)] =
10720           0;
10721       self->private_data.f_palettes[1][(
10722           (4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1)] =
10723           0;
10724       self->private_data.f_palettes[1][(
10725           (4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2)] =
10726           0;
10727       self->private_data.f_palettes[1][(
10728           (4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3)] =
10729           0;
10730     }
10731     v_dst_palette = wuffs_base__pixel_buffer__palette(a_dst);
10732     if (((uint64_t)(v_dst_palette.len)) == 0) {
10733       v_dst_palette =
10734           wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024);
10735     }
10736     v_status = wuffs_base__pixel_swizzler__prepare(
10737         &self->private_impl.f_swizzler,
10738         wuffs_base__pixel_buffer__pixel_format(a_dst), v_dst_palette,
10739         1191444488,
10740         wuffs_base__make_slice_u8(
10741             self->private_data.f_palettes[v_which_palette], 1024));
10742     if (!wuffs_base__status__is_ok(v_status)) {
10743       status = v_status;
10744       if (wuffs_base__status__is_error(status)) {
10745         goto exit;
10746       } else if (wuffs_base__status__is_suspension(status)) {
10747         status = wuffs_base__error__cannot_return_a_suspension;
10748         goto exit;
10749       }
10750       goto ok;
10751     }
10752     if (self->private_impl.f_previous_lzw_decode_ended_abruptly) {
10753       wuffs_base__ignore_status(wuffs_lzw__decoder__initialize(
10754           &self->private_data.f_lzw, sizeof(wuffs_lzw__decoder), WUFFS_VERSION,
10755           0));
10756     }
10757     {
10758       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
10759       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10760         status = wuffs_base__suspension__short_read;
10761         goto suspend;
10762       }
10763       uint8_t t_2 = *iop_a_src++;
10764       v_lw = t_2;
10765     }
10766     if (v_lw > 8) {
10767       status = wuffs_gif__error__bad_literal_width;
10768       goto exit;
10769     }
10770     wuffs_lzw__decoder__set_literal_width(&self->private_data.f_lzw,
10771                                           ((uint32_t)(v_lw)));
10772     self->private_impl.f_previous_lzw_decode_ended_abruptly = true;
10773 
10774     goto ok;
10775   ok:
10776     self->private_impl.p_decode_id_part1[0] = 0;
10777     goto exit;
10778   }
10779 
10780   goto suspend;
10781 suspend:
10782   self->private_impl.p_decode_id_part1[0] =
10783       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
10784   self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette;
10785   self->private_data.s_decode_id_part1[0].v_num_palette_entries =
10786       v_num_palette_entries;
10787   self->private_data.s_decode_id_part1[0].v_i = v_i;
10788 
10789   goto exit;
10790 exit:
10791   if (a_src) {
10792     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
10793   }
10794 
10795   return status;
10796 }
10797 
10798 // -------- func gif.decoder.decode_id_part2
10799 
10800 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)10801 wuffs_gif__decoder__decode_id_part2(wuffs_gif__decoder* self,
10802                                     wuffs_base__pixel_buffer* a_dst,
10803                                     wuffs_base__io_buffer* a_src,
10804                                     wuffs_base__slice_u8 a_workbuf) {
10805   wuffs_base__status status = NULL;
10806 
10807   uint64_t v_block_size = 0;
10808   bool v_need_block_size = false;
10809   uint64_t v_n_compressed = 0;
10810   wuffs_base__slice_u8 v_compressed = {0};
10811   wuffs_base__io_buffer u_r = wuffs_base__null_io_buffer();
10812   wuffs_base__io_buffer* v_r = &u_r;
10813   uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10814   uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10815   uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10816   uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10817   uint64_t v_mark = 0;
10818   wuffs_base__status v_lzw_status = NULL;
10819   wuffs_base__status v_copy_status = NULL;
10820   wuffs_base__slice_u8 v_uncompressed = {0};
10821 
10822   uint8_t* iop_a_src = NULL;
10823   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10824   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10825   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
10826   if (a_src) {
10827     io0_a_src = a_src->data.ptr;
10828     io1_a_src = io0_a_src + a_src->meta.ri;
10829     iop_a_src = io1_a_src;
10830     io2_a_src = io0_a_src + a_src->meta.wi;
10831   }
10832 
10833   uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0];
10834   if (coro_susp_point) {
10835     v_block_size = self->private_data.s_decode_id_part2[0].v_block_size;
10836     v_need_block_size =
10837         self->private_data.s_decode_id_part2[0].v_need_block_size;
10838     v_lzw_status = self->private_data.s_decode_id_part2[0].v_lzw_status;
10839   }
10840   switch (coro_susp_point) {
10841     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
10842 
10843     v_need_block_size = true;
10844   label_0_continue:;
10845     while (true) {
10846       if (v_need_block_size) {
10847         v_need_block_size = false;
10848         {
10849           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
10850           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
10851             status = wuffs_base__suspension__short_read;
10852             goto suspend;
10853           }
10854           uint64_t t_0 = *iop_a_src++;
10855           v_block_size = t_0;
10856         }
10857       }
10858       if (v_block_size == 0) {
10859         goto label_0_break;
10860       }
10861       while (((uint64_t)(io2_a_src - iop_a_src)) == 0) {
10862         status = wuffs_base__suspension__short_read;
10863         WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
10864       }
10865       if (self->private_impl.f_compressed_ri ==
10866           self->private_impl.f_compressed_wi) {
10867         self->private_impl.f_compressed_ri = 0;
10868         self->private_impl.f_compressed_wi = 0;
10869       }
10870       while (self->private_impl.f_compressed_wi <= 3841) {
10871         v_n_compressed = wuffs_base__u64__min(
10872             v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
10873         if (v_n_compressed <= 0) {
10874           goto label_1_break;
10875         }
10876         v_compressed =
10877             wuffs_base__io_reader__take(&iop_a_src, io2_a_src, v_n_compressed);
10878         wuffs_base__slice_u8__copy_from_slice(
10879             wuffs_base__slice_u8__subslice_i(
10880                 wuffs_base__make_slice_u8(self->private_data.f_compressed,
10881                                           4096),
10882                 self->private_impl.f_compressed_wi),
10883             v_compressed);
10884         wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi,
10885                                           v_n_compressed);
10886         wuffs_base__u64__sat_sub_indirect(&v_block_size, v_n_compressed);
10887         if (v_block_size > 0) {
10888           goto label_1_break;
10889         }
10890         if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
10891           v_need_block_size = true;
10892           goto label_1_break;
10893         }
10894         v_block_size = ((uint64_t)(wuffs_base__load_u8be(iop_a_src)));
10895         (iop_a_src += 1, wuffs_base__make_empty_struct());
10896       }
10897     label_1_break:;
10898       if (1 > ((uint64_t)(a_workbuf.len))) {
10899         status = wuffs_base__error__bad_workbuf_length;
10900         goto exit;
10901       }
10902     label_2_continue:;
10903       while (true) {
10904         if ((self->private_impl.f_compressed_ri >
10905              self->private_impl.f_compressed_wi) ||
10906             (self->private_impl.f_compressed_wi > 4096)) {
10907           status = wuffs_gif__error__internal_error_inconsistent_ri_wi;
10908           goto exit;
10909         }
10910         {
10911           wuffs_base__io_buffer* o_0_v_r = v_r;
10912           uint8_t* o_0_iop_v_r = iop_v_r;
10913           uint8_t* o_0_io0_v_r = io0_v_r;
10914           uint8_t* o_0_io1_v_r = io1_v_r;
10915           uint8_t* o_0_io2_v_r = io2_v_r;
10916           v_r = wuffs_base__io_reader__set(
10917               &u_r, &iop_v_r, &io0_v_r, &io1_v_r, &io2_v_r,
10918               wuffs_base__slice_u8__subslice_ij(
10919                   wuffs_base__make_slice_u8(self->private_data.f_compressed,
10920                                             4096),
10921                   self->private_impl.f_compressed_ri,
10922                   self->private_impl.f_compressed_wi));
10923           v_mark = ((uint64_t)(iop_v_r - io0_v_r));
10924           {
10925             u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
10926             wuffs_base__status t_1 = wuffs_lzw__decoder__decode_io_writer(
10927                 &self->private_data.f_lzw,
10928                 wuffs_base__utility__null_io_writer(), v_r,
10929                 wuffs_base__utility__null_slice_u8());
10930             iop_v_r = u_r.data.ptr + u_r.meta.ri;
10931             v_lzw_status = t_1;
10932           }
10933           wuffs_base__u64__sat_add_indirect(
10934               &self->private_impl.f_compressed_ri,
10935               wuffs_base__io__count_since(v_mark,
10936                                           ((uint64_t)(iop_v_r - io0_v_r))));
10937           v_r = o_0_v_r;
10938           iop_v_r = o_0_iop_v_r;
10939           io0_v_r = o_0_io0_v_r;
10940           io1_v_r = o_0_io1_v_r;
10941           io2_v_r = o_0_io2_v_r;
10942         }
10943         v_uncompressed = wuffs_lzw__decoder__flush(&self->private_data.f_lzw);
10944         if (((uint64_t)(v_uncompressed.len)) > 0) {
10945           v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(
10946               self, a_dst, v_uncompressed);
10947           if (wuffs_base__status__is_error(v_copy_status)) {
10948             status = v_copy_status;
10949             goto exit;
10950           }
10951         }
10952         if (wuffs_base__status__is_ok(v_lzw_status)) {
10953           self->private_impl.f_previous_lzw_decode_ended_abruptly = false;
10954           if (v_need_block_size || (v_block_size > 0)) {
10955             self->private_data.s_decode_id_part2[0].scratch =
10956                 ((uint32_t)(v_block_size));
10957             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
10958             if (self->private_data.s_decode_id_part2[0].scratch >
10959                 ((uint64_t)(io2_a_src - iop_a_src))) {
10960               self->private_data.s_decode_id_part2[0].scratch -=
10961                   ((uint64_t)(io2_a_src - iop_a_src));
10962               iop_a_src = io2_a_src;
10963               status = wuffs_base__suspension__short_read;
10964               goto suspend;
10965             }
10966             iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
10967             if (a_src) {
10968               a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
10969             }
10970             WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
10971             status = wuffs_gif__decoder__skip_blocks(self, a_src);
10972             if (a_src) {
10973               iop_a_src = a_src->data.ptr + a_src->meta.ri;
10974             }
10975             if (status) {
10976               goto suspend;
10977             }
10978           }
10979           goto label_0_break;
10980         } else if (v_lzw_status == wuffs_base__suspension__short_read) {
10981           goto label_0_continue;
10982         } else if (v_lzw_status == wuffs_base__suspension__short_write) {
10983           goto label_2_continue;
10984         }
10985         status = v_lzw_status;
10986         if (wuffs_base__status__is_error(status)) {
10987           goto exit;
10988         } else if (wuffs_base__status__is_suspension(status)) {
10989           status = wuffs_base__error__cannot_return_a_suspension;
10990           goto exit;
10991         }
10992         goto ok;
10993       }
10994     }
10995   label_0_break:;
10996     self->private_impl.f_compressed_ri = 0;
10997     self->private_impl.f_compressed_wi = 0;
10998     if ((self->private_impl.f_dst_y < self->private_impl.f_frame_rect_y1) &&
10999         (self->private_impl.f_frame_rect_x0 !=
11000          self->private_impl.f_frame_rect_x1) &&
11001         (self->private_impl.f_frame_rect_y0 !=
11002          self->private_impl.f_frame_rect_y1)) {
11003       status = wuffs_base__error__not_enough_data;
11004       goto exit;
11005     }
11006 
11007     goto ok;
11008   ok:
11009     self->private_impl.p_decode_id_part2[0] = 0;
11010     goto exit;
11011   }
11012 
11013   goto suspend;
11014 suspend:
11015   self->private_impl.p_decode_id_part2[0] =
11016       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
11017   self->private_data.s_decode_id_part2[0].v_block_size = v_block_size;
11018   self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size;
11019   self->private_data.s_decode_id_part2[0].v_lzw_status = v_lzw_status;
11020 
11021   goto exit;
11022 exit:
11023   if (a_src) {
11024     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
11025   }
11026 
11027   return status;
11028 }
11029 
11030 // -------- func gif.decoder.copy_to_image_buffer
11031 
11032 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)11033 wuffs_gif__decoder__copy_to_image_buffer(wuffs_gif__decoder* self,
11034                                          wuffs_base__pixel_buffer* a_pb,
11035                                          wuffs_base__slice_u8 a_src) {
11036   wuffs_base__slice_u8 v_dst = {0};
11037   wuffs_base__slice_u8 v_src = {0};
11038   uint64_t v_n = 0;
11039   uint64_t v_src_ri = 0;
11040   uint32_t v_bytes_per_pixel = 0;
11041   uint32_t v_pixfmt_channels = 0;
11042   wuffs_base__table_u8 v_tab = {0};
11043   uint64_t v_i = 0;
11044   uint64_t v_j = 0;
11045 
11046   v_pixfmt_channels = (wuffs_base__pixel_buffer__pixel_format(a_pb) & 65535);
11047   if (v_pixfmt_channels == 34952) {
11048     v_bytes_per_pixel = 4;
11049   } else if (v_pixfmt_channels == 2184) {
11050     v_bytes_per_pixel = 3;
11051   } else if (v_pixfmt_channels == 8) {
11052     v_bytes_per_pixel = 1;
11053   } else {
11054     return wuffs_base__error__unsupported_option;
11055   }
11056   v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0);
11057 label_0_continue:;
11058   while (v_src_ri < ((uint64_t)(a_src.len))) {
11059     v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
11060     if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
11061       if (self->private_impl.f_quirk_enabled_ignore_too_much_pixel_data) {
11062         return NULL;
11063       }
11064       return wuffs_base__error__too_much_data;
11065     }
11066     v_dst = wuffs_base__table_u8__row(v_tab, self->private_impl.f_dst_y);
11067     v_i = (((uint64_t)(self->private_impl.f_dst_x)) *
11068            ((uint64_t)(v_bytes_per_pixel)));
11069     if (v_i < ((uint64_t)(v_dst.len))) {
11070       v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) *
11071              ((uint64_t)(v_bytes_per_pixel)));
11072       if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
11073         v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
11074       } else {
11075         v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
11076       }
11077       v_n = wuffs_base__pixel_swizzler__swizzle_interleaved(
11078           &self->private_impl.f_swizzler, v_dst,
11079           wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024),
11080           v_src);
11081       wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
11082       wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x,
11083                                         ((uint32_t)((v_n & 4294967295))));
11084       self->private_impl.f_dirty_y = wuffs_base__range_ie_u32__unite(
11085           &self->private_impl.f_dirty_y,
11086           wuffs_base__utility__make_range_ie_u32(
11087               self->private_impl.f_dst_y,
11088               wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1)));
11089     }
11090     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
11091       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
11092       wuffs_base__u32__sat_add_indirect(
11093           &self->private_impl.f_dst_y,
11094           ((uint32_t)(
11095               wuffs_gif__interlace_delta[self->private_impl.f_interlace])));
11096       while (
11097           (self->private_impl.f_interlace > 0) &&
11098           (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
11099 #if defined(__GNUC__)
11100 #pragma GCC diagnostic push
11101 #pragma GCC diagnostic ignored "-Wconversion"
11102 #endif
11103         self->private_impl.f_interlace -= 1;
11104 #if defined(__GNUC__)
11105 #pragma GCC diagnostic pop
11106 #endif
11107         self->private_impl.f_dst_y = wuffs_base__u32__sat_add(
11108             self->private_impl.f_frame_rect_y0,
11109             wuffs_gif__interlace_start[self->private_impl.f_interlace]);
11110       }
11111       goto label_0_continue;
11112     }
11113     if (((uint64_t)(a_src.len)) == v_src_ri) {
11114       goto label_0_break;
11115     } else if (((uint64_t)(a_src.len)) < v_src_ri) {
11116       return wuffs_gif__error__internal_error_inconsistent_ri_wi;
11117     }
11118     v_n = ((uint64_t)(
11119         (self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
11120     v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
11121     wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
11122     wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x,
11123                                       ((uint32_t)((v_n & 4294967295))));
11124     if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
11125       self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
11126       wuffs_base__u32__sat_add_indirect(
11127           &self->private_impl.f_dst_y,
11128           ((uint32_t)(
11129               wuffs_gif__interlace_delta[self->private_impl.f_interlace])));
11130       while (
11131           (self->private_impl.f_interlace > 0) &&
11132           (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
11133 #if defined(__GNUC__)
11134 #pragma GCC diagnostic push
11135 #pragma GCC diagnostic ignored "-Wconversion"
11136 #endif
11137         self->private_impl.f_interlace -= 1;
11138 #if defined(__GNUC__)
11139 #pragma GCC diagnostic pop
11140 #endif
11141         self->private_impl.f_dst_y = wuffs_base__u32__sat_add(
11142             self->private_impl.f_frame_rect_y0,
11143             wuffs_gif__interlace_start[self->private_impl.f_interlace]);
11144       }
11145       goto label_0_continue;
11146     }
11147     if (v_src_ri != ((uint64_t)(a_src.len))) {
11148       return wuffs_gif__error__internal_error_inconsistent_ri_wi;
11149     }
11150     goto label_0_break;
11151   }
11152 label_0_break:;
11153   return NULL;
11154 }
11155 
11156 #endif  // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
11157 
11158 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
11159 
11160 // ---------------- Status Codes Implementations
11161 
11162 const char* wuffs_gzip__error__bad_checksum = "#gzip: bad checksum";
11163 const char* wuffs_gzip__error__bad_compression_method =
11164     "#gzip: bad compression method";
11165 const char* wuffs_gzip__error__bad_encoding_flags = "#gzip: bad encoding flags";
11166 const char* wuffs_gzip__error__bad_header = "#gzip: bad header";
11167 
11168 // ---------------- Private Consts
11169 
11170 // ---------------- Private Initializer Prototypes
11171 
11172 // ---------------- Private Function Prototypes
11173 
11174 // ---------------- Initializer Implementations
11175 
11176 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 initialize_flags)11177 wuffs_gzip__decoder__initialize(wuffs_gzip__decoder* self,
11178                                 size_t sizeof_star_self,
11179                                 uint64_t wuffs_version,
11180                                 uint32_t initialize_flags) {
11181   if (!self) {
11182     return wuffs_base__error__bad_receiver;
11183   }
11184   if (sizeof(*self) != sizeof_star_self) {
11185     return wuffs_base__error__bad_sizeof_receiver;
11186   }
11187   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
11188       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
11189     return wuffs_base__error__bad_wuffs_version;
11190   }
11191 
11192   if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
11193 // The whole point of this if-check is to detect an uninitialized *self.
11194 // We disable the warning on GCC. Clang-5.0 does not have this warning.
11195 #if !defined(__clang__) && defined(__GNUC__)
11196 #pragma GCC diagnostic push
11197 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
11198 #endif
11199     if (self->private_impl.magic != 0) {
11200       return wuffs_base__error__initialize_falsely_claimed_already_zeroed;
11201     }
11202 #if !defined(__clang__) && defined(__GNUC__)
11203 #pragma GCC diagnostic pop
11204 #endif
11205   } else {
11206     void* p = &(self->private_impl);
11207     size_t n = sizeof(self->private_impl);
11208     if ((initialize_flags &
11209          WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
11210       p = self;
11211       n = sizeof(*self);
11212       initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
11213     }
11214     memset(p, 0, n);
11215   }
11216 
11217   {
11218     wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
11219         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum),
11220         WUFFS_VERSION, initialize_flags);
11221     if (z) {
11222       return z;
11223     }
11224   }
11225   {
11226     wuffs_base__status z = wuffs_deflate__decoder__initialize(
11227         &self->private_data.f_flate, sizeof(self->private_data.f_flate),
11228         WUFFS_VERSION, initialize_flags);
11229     if (z) {
11230       return z;
11231     }
11232   }
11233   self->private_impl.magic = WUFFS_BASE__MAGIC;
11234   return NULL;
11235 }
11236 
11237 size_t  //
sizeof__wuffs_gzip__decoder()11238 sizeof__wuffs_gzip__decoder() {
11239   return sizeof(wuffs_gzip__decoder);
11240 }
11241 
11242 // ---------------- Function Implementations
11243 
11244 // -------- func gzip.decoder.set_ignore_checksum
11245 
11246 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
wuffs_gzip__decoder__set_ignore_checksum(wuffs_gzip__decoder * self,bool a_ic)11247 wuffs_gzip__decoder__set_ignore_checksum(wuffs_gzip__decoder* self, bool a_ic) {
11248   if (!self) {
11249     return wuffs_base__make_empty_struct();
11250   }
11251   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11252     return wuffs_base__make_empty_struct();
11253   }
11254 
11255   self->private_impl.f_ignore_checksum = a_ic;
11256   return wuffs_base__make_empty_struct();
11257 }
11258 
11259 // -------- func gzip.decoder.workbuf_len
11260 
11261 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
wuffs_gzip__decoder__workbuf_len(const wuffs_gzip__decoder * self)11262 wuffs_gzip__decoder__workbuf_len(const wuffs_gzip__decoder* self) {
11263   if (!self) {
11264     return wuffs_base__utility__make_range_ii_u64(0, 0);
11265   }
11266   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11267       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11268     return wuffs_base__utility__make_range_ii_u64(0, 0);
11269   }
11270 
11271   return wuffs_base__utility__make_range_ii_u64(1, 1);
11272 }
11273 
11274 // -------- func gzip.decoder.decode_io_writer
11275 
11276 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_gzip__decoder__decode_io_writer(wuffs_gzip__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)11277 wuffs_gzip__decoder__decode_io_writer(wuffs_gzip__decoder* self,
11278                                       wuffs_base__io_buffer* a_dst,
11279                                       wuffs_base__io_buffer* a_src,
11280                                       wuffs_base__slice_u8 a_workbuf) {
11281   if (!self) {
11282     return wuffs_base__error__bad_receiver;
11283   }
11284   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11285     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
11286                ? wuffs_base__error__disabled_by_previous_error
11287                : wuffs_base__error__initialize_not_called;
11288   }
11289   if (!a_dst || !a_src) {
11290     self->private_impl.magic = WUFFS_BASE__DISABLED;
11291     return wuffs_base__error__bad_argument;
11292   }
11293   if ((self->private_impl.active_coroutine != 0) &&
11294       (self->private_impl.active_coroutine != 1)) {
11295     self->private_impl.magic = WUFFS_BASE__DISABLED;
11296     return wuffs_base__error__interleaved_coroutine_calls;
11297   }
11298   self->private_impl.active_coroutine = 0;
11299   wuffs_base__status status = NULL;
11300 
11301   uint8_t v_c = 0;
11302   uint8_t v_flags = 0;
11303   uint16_t v_xlen = 0;
11304   uint64_t v_mark = 0;
11305   uint32_t v_checksum_got = 0;
11306   uint32_t v_decoded_length_got = 0;
11307   wuffs_base__status v_status = NULL;
11308   uint32_t v_checksum_want = 0;
11309   uint32_t v_decoded_length_want = 0;
11310 
11311   uint8_t* iop_a_dst = NULL;
11312   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11313   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11314   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11315   if (a_dst) {
11316     io0_a_dst = a_dst->data.ptr;
11317     io1_a_dst = io0_a_dst + a_dst->meta.wi;
11318     iop_a_dst = io1_a_dst;
11319     io2_a_dst = io0_a_dst + a_dst->data.len;
11320     if (a_dst->meta.closed) {
11321       io2_a_dst = iop_a_dst;
11322     }
11323   }
11324   uint8_t* iop_a_src = NULL;
11325   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11326   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11327   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11328   if (a_src) {
11329     io0_a_src = a_src->data.ptr;
11330     io1_a_src = io0_a_src + a_src->meta.ri;
11331     iop_a_src = io1_a_src;
11332     io2_a_src = io0_a_src + a_src->meta.wi;
11333   }
11334 
11335   uint32_t coro_susp_point = self->private_impl.p_decode_io_writer[0];
11336   if (coro_susp_point) {
11337     v_flags = self->private_data.s_decode_io_writer[0].v_flags;
11338     v_checksum_got = self->private_data.s_decode_io_writer[0].v_checksum_got;
11339     v_decoded_length_got =
11340         self->private_data.s_decode_io_writer[0].v_decoded_length_got;
11341     v_checksum_want = self->private_data.s_decode_io_writer[0].v_checksum_want;
11342   }
11343   switch (coro_susp_point) {
11344     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
11345 
11346     {
11347       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
11348       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11349         status = wuffs_base__suspension__short_read;
11350         goto suspend;
11351       }
11352       uint8_t t_0 = *iop_a_src++;
11353       v_c = t_0;
11354     }
11355     if (v_c != 31) {
11356       status = wuffs_gzip__error__bad_header;
11357       goto exit;
11358     }
11359     {
11360       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
11361       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11362         status = wuffs_base__suspension__short_read;
11363         goto suspend;
11364       }
11365       uint8_t t_1 = *iop_a_src++;
11366       v_c = t_1;
11367     }
11368     if (v_c != 139) {
11369       status = wuffs_gzip__error__bad_header;
11370       goto exit;
11371     }
11372     {
11373       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
11374       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11375         status = wuffs_base__suspension__short_read;
11376         goto suspend;
11377       }
11378       uint8_t t_2 = *iop_a_src++;
11379       v_c = t_2;
11380     }
11381     if (v_c != 8) {
11382       status = wuffs_gzip__error__bad_compression_method;
11383       goto exit;
11384     }
11385     {
11386       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
11387       if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11388         status = wuffs_base__suspension__short_read;
11389         goto suspend;
11390       }
11391       uint8_t t_3 = *iop_a_src++;
11392       v_flags = t_3;
11393     }
11394     self->private_data.s_decode_io_writer[0].scratch = 6;
11395     WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
11396     if (self->private_data.s_decode_io_writer[0].scratch >
11397         ((uint64_t)(io2_a_src - iop_a_src))) {
11398       self->private_data.s_decode_io_writer[0].scratch -=
11399           ((uint64_t)(io2_a_src - iop_a_src));
11400       iop_a_src = io2_a_src;
11401       status = wuffs_base__suspension__short_read;
11402       goto suspend;
11403     }
11404     iop_a_src += self->private_data.s_decode_io_writer[0].scratch;
11405     if ((v_flags & 4) != 0) {
11406       {
11407         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
11408         uint16_t t_4;
11409         if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
11410           t_4 = wuffs_base__load_u16le(iop_a_src);
11411           iop_a_src += 2;
11412         } else {
11413           self->private_data.s_decode_io_writer[0].scratch = 0;
11414           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
11415           while (true) {
11416             if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11417               status = wuffs_base__suspension__short_read;
11418               goto suspend;
11419             }
11420             uint64_t* scratch =
11421                 &self->private_data.s_decode_io_writer[0].scratch;
11422             uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
11423             *scratch <<= 8;
11424             *scratch >>= 8;
11425             *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
11426             if (num_bits_4 == 8) {
11427               t_4 = ((uint16_t)(*scratch));
11428               break;
11429             }
11430             num_bits_4 += 8;
11431             *scratch |= ((uint64_t)(num_bits_4)) << 56;
11432           }
11433         }
11434         v_xlen = t_4;
11435       }
11436       self->private_data.s_decode_io_writer[0].scratch = ((uint32_t)(v_xlen));
11437       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
11438       if (self->private_data.s_decode_io_writer[0].scratch >
11439           ((uint64_t)(io2_a_src - iop_a_src))) {
11440         self->private_data.s_decode_io_writer[0].scratch -=
11441             ((uint64_t)(io2_a_src - iop_a_src));
11442         iop_a_src = io2_a_src;
11443         status = wuffs_base__suspension__short_read;
11444         goto suspend;
11445       }
11446       iop_a_src += self->private_data.s_decode_io_writer[0].scratch;
11447     }
11448     if ((v_flags & 8) != 0) {
11449       while (true) {
11450         {
11451           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
11452           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11453             status = wuffs_base__suspension__short_read;
11454             goto suspend;
11455           }
11456           uint8_t t_5 = *iop_a_src++;
11457           v_c = t_5;
11458         }
11459         if (v_c == 0) {
11460           goto label_0_break;
11461         }
11462       }
11463     label_0_break:;
11464     }
11465     if ((v_flags & 16) != 0) {
11466       while (true) {
11467         {
11468           WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
11469           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11470             status = wuffs_base__suspension__short_read;
11471             goto suspend;
11472           }
11473           uint8_t t_6 = *iop_a_src++;
11474           v_c = t_6;
11475         }
11476         if (v_c == 0) {
11477           goto label_1_break;
11478         }
11479       }
11480     label_1_break:;
11481     }
11482     if ((v_flags & 2) != 0) {
11483       self->private_data.s_decode_io_writer[0].scratch = 2;
11484       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
11485       if (self->private_data.s_decode_io_writer[0].scratch >
11486           ((uint64_t)(io2_a_src - iop_a_src))) {
11487         self->private_data.s_decode_io_writer[0].scratch -=
11488             ((uint64_t)(io2_a_src - iop_a_src));
11489         iop_a_src = io2_a_src;
11490         status = wuffs_base__suspension__short_read;
11491         goto suspend;
11492       }
11493       iop_a_src += self->private_data.s_decode_io_writer[0].scratch;
11494     }
11495     if ((v_flags & 224) != 0) {
11496       status = wuffs_gzip__error__bad_encoding_flags;
11497       goto exit;
11498     }
11499     while (true) {
11500       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
11501       {
11502         if (a_dst) {
11503           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
11504         }
11505         if (a_src) {
11506           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
11507         }
11508         wuffs_base__status t_7 = wuffs_deflate__decoder__decode_io_writer(
11509             &self->private_data.f_flate, a_dst, a_src, a_workbuf);
11510         if (a_dst) {
11511           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
11512         }
11513         if (a_src) {
11514           iop_a_src = a_src->data.ptr + a_src->meta.ri;
11515         }
11516         v_status = t_7;
11517       }
11518       if (!self->private_impl.f_ignore_checksum) {
11519         v_checksum_got = wuffs_crc32__ieee_hasher__update(
11520             &self->private_data.f_checksum,
11521             wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)),
11522                                   io0_a_dst));
11523         v_decoded_length_got +=
11524             ((uint32_t)((wuffs_base__io__count_since(
11525                              v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))) &
11526                          4294967295)));
11527       }
11528       if (wuffs_base__status__is_ok(v_status)) {
11529         goto label_2_break;
11530       }
11531       status = v_status;
11532       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
11533     }
11534   label_2_break:;
11535     {
11536       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
11537       uint32_t t_8;
11538       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
11539         t_8 = wuffs_base__load_u32le(iop_a_src);
11540         iop_a_src += 4;
11541       } else {
11542         self->private_data.s_decode_io_writer[0].scratch = 0;
11543         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
11544         while (true) {
11545           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11546             status = wuffs_base__suspension__short_read;
11547             goto suspend;
11548           }
11549           uint64_t* scratch = &self->private_data.s_decode_io_writer[0].scratch;
11550           uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
11551           *scratch <<= 8;
11552           *scratch >>= 8;
11553           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
11554           if (num_bits_8 == 24) {
11555             t_8 = ((uint32_t)(*scratch));
11556             break;
11557           }
11558           num_bits_8 += 8;
11559           *scratch |= ((uint64_t)(num_bits_8)) << 56;
11560         }
11561       }
11562       v_checksum_want = t_8;
11563     }
11564     {
11565       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
11566       uint32_t t_9;
11567       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
11568         t_9 = wuffs_base__load_u32le(iop_a_src);
11569         iop_a_src += 4;
11570       } else {
11571         self->private_data.s_decode_io_writer[0].scratch = 0;
11572         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
11573         while (true) {
11574           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11575             status = wuffs_base__suspension__short_read;
11576             goto suspend;
11577           }
11578           uint64_t* scratch = &self->private_data.s_decode_io_writer[0].scratch;
11579           uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
11580           *scratch <<= 8;
11581           *scratch >>= 8;
11582           *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
11583           if (num_bits_9 == 24) {
11584             t_9 = ((uint32_t)(*scratch));
11585             break;
11586           }
11587           num_bits_9 += 8;
11588           *scratch |= ((uint64_t)(num_bits_9)) << 56;
11589         }
11590       }
11591       v_decoded_length_want = t_9;
11592     }
11593     if (!self->private_impl.f_ignore_checksum &&
11594         ((v_checksum_got != v_checksum_want) ||
11595          (v_decoded_length_got != v_decoded_length_want))) {
11596       status = wuffs_gzip__error__bad_checksum;
11597       goto exit;
11598     }
11599 
11600     goto ok;
11601   ok:
11602     self->private_impl.p_decode_io_writer[0] = 0;
11603     goto exit;
11604   }
11605 
11606   goto suspend;
11607 suspend:
11608   self->private_impl.p_decode_io_writer[0] =
11609       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
11610   self->private_impl.active_coroutine =
11611       wuffs_base__status__is_suspension(status) ? 1 : 0;
11612   self->private_data.s_decode_io_writer[0].v_flags = v_flags;
11613   self->private_data.s_decode_io_writer[0].v_checksum_got = v_checksum_got;
11614   self->private_data.s_decode_io_writer[0].v_decoded_length_got =
11615       v_decoded_length_got;
11616   self->private_data.s_decode_io_writer[0].v_checksum_want = v_checksum_want;
11617 
11618   goto exit;
11619 exit:
11620   if (a_dst) {
11621     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
11622   }
11623   if (a_src) {
11624     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
11625   }
11626 
11627   if (wuffs_base__status__is_error(status)) {
11628     self->private_impl.magic = WUFFS_BASE__DISABLED;
11629   }
11630   return status;
11631 }
11632 
11633 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
11634         // defined(WUFFS_CONFIG__MODULE__GZIP)
11635 
11636 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
11637 
11638 // ---------------- Status Codes Implementations
11639 
11640 const char* wuffs_zlib__error__bad_checksum = "#zlib: bad checksum";
11641 const char* wuffs_zlib__error__bad_compression_method =
11642     "#zlib: bad compression method";
11643 const char* wuffs_zlib__error__bad_compression_window_size =
11644     "#zlib: bad compression window size";
11645 const char* wuffs_zlib__error__bad_parity_check = "#zlib: bad parity check";
11646 const char* wuffs_zlib__error__todo_unsupported_preset_dictionary =
11647     "#zlib: TODO: unsupported preset dictionary";
11648 
11649 // ---------------- Private Consts
11650 
11651 // ---------------- Private Initializer Prototypes
11652 
11653 // ---------------- Private Function Prototypes
11654 
11655 // ---------------- Initializer Implementations
11656 
11657 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 initialize_flags)11658 wuffs_zlib__decoder__initialize(wuffs_zlib__decoder* self,
11659                                 size_t sizeof_star_self,
11660                                 uint64_t wuffs_version,
11661                                 uint32_t initialize_flags) {
11662   if (!self) {
11663     return wuffs_base__error__bad_receiver;
11664   }
11665   if (sizeof(*self) != sizeof_star_self) {
11666     return wuffs_base__error__bad_sizeof_receiver;
11667   }
11668   if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
11669       (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
11670     return wuffs_base__error__bad_wuffs_version;
11671   }
11672 
11673   if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
11674 // The whole point of this if-check is to detect an uninitialized *self.
11675 // We disable the warning on GCC. Clang-5.0 does not have this warning.
11676 #if !defined(__clang__) && defined(__GNUC__)
11677 #pragma GCC diagnostic push
11678 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
11679 #endif
11680     if (self->private_impl.magic != 0) {
11681       return wuffs_base__error__initialize_falsely_claimed_already_zeroed;
11682     }
11683 #if !defined(__clang__) && defined(__GNUC__)
11684 #pragma GCC diagnostic pop
11685 #endif
11686   } else {
11687     void* p = &(self->private_impl);
11688     size_t n = sizeof(self->private_impl);
11689     if ((initialize_flags &
11690          WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
11691       p = self;
11692       n = sizeof(*self);
11693       initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
11694     }
11695     memset(p, 0, n);
11696   }
11697 
11698   {
11699     wuffs_base__status z = wuffs_adler32__hasher__initialize(
11700         &self->private_data.f_checksum, sizeof(self->private_data.f_checksum),
11701         WUFFS_VERSION, initialize_flags);
11702     if (z) {
11703       return z;
11704     }
11705   }
11706   {
11707     wuffs_base__status z = wuffs_deflate__decoder__initialize(
11708         &self->private_data.f_flate, sizeof(self->private_data.f_flate),
11709         WUFFS_VERSION, initialize_flags);
11710     if (z) {
11711       return z;
11712     }
11713   }
11714   self->private_impl.magic = WUFFS_BASE__MAGIC;
11715   return NULL;
11716 }
11717 
11718 size_t  //
sizeof__wuffs_zlib__decoder()11719 sizeof__wuffs_zlib__decoder() {
11720   return sizeof(wuffs_zlib__decoder);
11721 }
11722 
11723 // ---------------- Function Implementations
11724 
11725 // -------- func zlib.decoder.set_ignore_checksum
11726 
11727 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct  //
wuffs_zlib__decoder__set_ignore_checksum(wuffs_zlib__decoder * self,bool a_ic)11728 wuffs_zlib__decoder__set_ignore_checksum(wuffs_zlib__decoder* self, bool a_ic) {
11729   if (!self) {
11730     return wuffs_base__make_empty_struct();
11731   }
11732   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11733     return wuffs_base__make_empty_struct();
11734   }
11735 
11736   self->private_impl.f_ignore_checksum = a_ic;
11737   return wuffs_base__make_empty_struct();
11738 }
11739 
11740 // -------- func zlib.decoder.workbuf_len
11741 
11742 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64  //
wuffs_zlib__decoder__workbuf_len(const wuffs_zlib__decoder * self)11743 wuffs_zlib__decoder__workbuf_len(const wuffs_zlib__decoder* self) {
11744   if (!self) {
11745     return wuffs_base__utility__make_range_ii_u64(0, 0);
11746   }
11747   if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11748       (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11749     return wuffs_base__utility__make_range_ii_u64(0, 0);
11750   }
11751 
11752   return wuffs_base__utility__make_range_ii_u64(1, 1);
11753 }
11754 
11755 // -------- func zlib.decoder.decode_io_writer
11756 
11757 WUFFS_BASE__MAYBE_STATIC wuffs_base__status  //
wuffs_zlib__decoder__decode_io_writer(wuffs_zlib__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)11758 wuffs_zlib__decoder__decode_io_writer(wuffs_zlib__decoder* self,
11759                                       wuffs_base__io_buffer* a_dst,
11760                                       wuffs_base__io_buffer* a_src,
11761                                       wuffs_base__slice_u8 a_workbuf) {
11762   if (!self) {
11763     return wuffs_base__error__bad_receiver;
11764   }
11765   if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11766     return (self->private_impl.magic == WUFFS_BASE__DISABLED)
11767                ? wuffs_base__error__disabled_by_previous_error
11768                : wuffs_base__error__initialize_not_called;
11769   }
11770   if (!a_dst || !a_src) {
11771     self->private_impl.magic = WUFFS_BASE__DISABLED;
11772     return wuffs_base__error__bad_argument;
11773   }
11774   if ((self->private_impl.active_coroutine != 0) &&
11775       (self->private_impl.active_coroutine != 1)) {
11776     self->private_impl.magic = WUFFS_BASE__DISABLED;
11777     return wuffs_base__error__interleaved_coroutine_calls;
11778   }
11779   self->private_impl.active_coroutine = 0;
11780   wuffs_base__status status = NULL;
11781 
11782   uint16_t v_x = 0;
11783   uint32_t v_checksum_got = 0;
11784   wuffs_base__status v_status = NULL;
11785   uint32_t v_checksum_want = 0;
11786   uint64_t v_mark = 0;
11787 
11788   uint8_t* iop_a_dst = NULL;
11789   uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11790   uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11791   uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11792   if (a_dst) {
11793     io0_a_dst = a_dst->data.ptr;
11794     io1_a_dst = io0_a_dst + a_dst->meta.wi;
11795     iop_a_dst = io1_a_dst;
11796     io2_a_dst = io0_a_dst + a_dst->data.len;
11797     if (a_dst->meta.closed) {
11798       io2_a_dst = iop_a_dst;
11799     }
11800   }
11801   uint8_t* iop_a_src = NULL;
11802   uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11803   uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11804   uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
11805   if (a_src) {
11806     io0_a_src = a_src->data.ptr;
11807     io1_a_src = io0_a_src + a_src->meta.ri;
11808     iop_a_src = io1_a_src;
11809     io2_a_src = io0_a_src + a_src->meta.wi;
11810   }
11811 
11812   uint32_t coro_susp_point = self->private_impl.p_decode_io_writer[0];
11813   if (coro_susp_point) {
11814     v_checksum_got = self->private_data.s_decode_io_writer[0].v_checksum_got;
11815   }
11816   switch (coro_susp_point) {
11817     WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
11818 
11819     {
11820       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
11821       uint16_t t_0;
11822       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
11823         t_0 = wuffs_base__load_u16be(iop_a_src);
11824         iop_a_src += 2;
11825       } else {
11826         self->private_data.s_decode_io_writer[0].scratch = 0;
11827         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
11828         while (true) {
11829           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11830             status = wuffs_base__suspension__short_read;
11831             goto suspend;
11832           }
11833           uint64_t* scratch = &self->private_data.s_decode_io_writer[0].scratch;
11834           uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
11835           *scratch >>= 8;
11836           *scratch <<= 8;
11837           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
11838           if (num_bits_0 == 8) {
11839             t_0 = ((uint16_t)(*scratch >> 48));
11840             break;
11841           }
11842           num_bits_0 += 8;
11843           *scratch |= ((uint64_t)(num_bits_0));
11844         }
11845       }
11846       v_x = t_0;
11847     }
11848     if (((v_x >> 8) & 15) != 8) {
11849       status = wuffs_zlib__error__bad_compression_method;
11850       goto exit;
11851     }
11852     if ((v_x >> 12) > 7) {
11853       status = wuffs_zlib__error__bad_compression_window_size;
11854       goto exit;
11855     }
11856     if ((v_x & 32) != 0) {
11857       status = wuffs_zlib__error__todo_unsupported_preset_dictionary;
11858       goto exit;
11859     }
11860     if ((v_x % 31) != 0) {
11861       status = wuffs_zlib__error__bad_parity_check;
11862       goto exit;
11863     }
11864     while (true) {
11865       v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
11866       {
11867         if (a_dst) {
11868           a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
11869         }
11870         if (a_src) {
11871           a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
11872         }
11873         wuffs_base__status t_1 = wuffs_deflate__decoder__decode_io_writer(
11874             &self->private_data.f_flate, a_dst, a_src, a_workbuf);
11875         if (a_dst) {
11876           iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
11877         }
11878         if (a_src) {
11879           iop_a_src = a_src->data.ptr + a_src->meta.ri;
11880         }
11881         v_status = t_1;
11882       }
11883       if (!self->private_impl.f_ignore_checksum) {
11884         v_checksum_got = wuffs_adler32__hasher__update(
11885             &self->private_data.f_checksum,
11886             wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)),
11887                                   io0_a_dst));
11888       }
11889       if (wuffs_base__status__is_ok(v_status)) {
11890         goto label_0_break;
11891       }
11892       status = v_status;
11893       WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
11894     }
11895   label_0_break:;
11896     {
11897       WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
11898       uint32_t t_2;
11899       if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
11900         t_2 = wuffs_base__load_u32be(iop_a_src);
11901         iop_a_src += 4;
11902       } else {
11903         self->private_data.s_decode_io_writer[0].scratch = 0;
11904         WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
11905         while (true) {
11906           if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
11907             status = wuffs_base__suspension__short_read;
11908             goto suspend;
11909           }
11910           uint64_t* scratch = &self->private_data.s_decode_io_writer[0].scratch;
11911           uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
11912           *scratch >>= 8;
11913           *scratch <<= 8;
11914           *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
11915           if (num_bits_2 == 24) {
11916             t_2 = ((uint32_t)(*scratch >> 32));
11917             break;
11918           }
11919           num_bits_2 += 8;
11920           *scratch |= ((uint64_t)(num_bits_2));
11921         }
11922       }
11923       v_checksum_want = t_2;
11924     }
11925     if (!self->private_impl.f_ignore_checksum &&
11926         (v_checksum_got != v_checksum_want)) {
11927       status = wuffs_zlib__error__bad_checksum;
11928       goto exit;
11929     }
11930 
11931     goto ok;
11932   ok:
11933     self->private_impl.p_decode_io_writer[0] = 0;
11934     goto exit;
11935   }
11936 
11937   goto suspend;
11938 suspend:
11939   self->private_impl.p_decode_io_writer[0] =
11940       wuffs_base__status__is_suspension(status) ? coro_susp_point : 0;
11941   self->private_impl.active_coroutine =
11942       wuffs_base__status__is_suspension(status) ? 1 : 0;
11943   self->private_data.s_decode_io_writer[0].v_checksum_got = v_checksum_got;
11944 
11945   goto exit;
11946 exit:
11947   if (a_dst) {
11948     a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
11949   }
11950   if (a_src) {
11951     a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
11952   }
11953 
11954   if (wuffs_base__status__is_error(status)) {
11955     self->private_impl.magic = WUFFS_BASE__DISABLED;
11956   }
11957   return status;
11958 }
11959 
11960 #endif  // !defined(WUFFS_CONFIG__MODULES) ||
11961         // defined(WUFFS_CONFIG__MODULE__ZLIB)
11962 
11963 #endif  // WUFFS_IMPLEMENTATION
11964 
11965 #endif  // WUFFS_INCLUDE_GUARD
11966