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