1#ifndef WUFFS_INCLUDE_GUARD
2#define WUFFS_INCLUDE_GUARD
3
4// Wuffs ships as a "single file C library" or "header file library" as per
5// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
6//
7// To use that single file as a "foo.c"-like implementation, instead of a
8// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
9// compiling it.
10
11// Wuffs' C code is generated automatically, not hand-written. These warnings'
12// costs outweigh the benefits.
13#ifdef __clang__
14#pragma clang diagnostic push
15#pragma clang diagnostic ignored "-Wunreachable-code"
16#pragma clang diagnostic ignored "-Wunused-function"
17#endif
18
19// Copyright 2017 The Wuffs Authors.
20//
21// Licensed under the Apache License, Version 2.0 (the "License");
22// you may not use this file except in compliance with the License.
23// You may obtain a copy of the License at
24//
25// https://www.apache.org/licenses/LICENSE-2.0
26//
27// Unless required by applicable law or agreed to in writing, software
28// distributed under the License is distributed on an "AS IS" BASIS,
29// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30// See the License for the specific language governing permissions and
31// limitations under the License.
32
33#include <stdbool.h>
34#include <stdint.h>
35#include <stdlib.h>
36#include <string.h>
37
38// Note that Clang also defines __GNUC__.
39#ifdef __cplusplus
40#if __cplusplus >= 201103L
41#include <memory>
42#elif defined(__GNUC__)
43#warning "Wuffs' C++ code expects -std=c++11 or later"
44#elif defined(_MSC_VER)
45#pragma message("Wuffs' C++ code expects C++11 or later")
46#endif
47
48extern "C" {
49#endif
50
51// ---------------- Fundamentals
52
53// WUFFS_VERSION is the major.minor.patch version, as per https://semver.org/,
54// as a uint64_t. The major number is the high 32 bits. The minor number is the
55// middle 16 bits. The patch number is the low 16 bits. The pre-release label
56// and build metadata are part of the string representation (such as
57// "1.2.3-beta+456.20181231") but not the uint64_t representation.
58//
59// WUFFS_VERSION_PRE_RELEASE_LABEL (such as "", "beta" or "rc.1") being
60// non-empty denotes a developer preview, not a release version, and has no
61// backwards or forwards compatibility guarantees.
62//
63// WUFFS_VERSION_BUILD_METADATA_XXX, if non-zero, are the number of commits and
64// the last commit date in the repository used to build this library. Within
65// each major.minor branch, the commit count should increase monotonically.
66//
67// WUFFS_VERSION was overridden by "wuffs gen -version" based on revision
68// d377dcaea826f12b47492cced1b75450a440f6c1 committed on 2020-06-17.
69#define WUFFS_VERSION 0x000030000
70#define WUFFS_VERSION_MAJOR 0
71#define WUFFS_VERSION_MINOR 3
72#define WUFFS_VERSION_PATCH 0
73#define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.4"
74#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 2514
75#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20200617
76#define WUFFS_VERSION_STRING "0.3.0-alpha.4+2514.20200617"
77
78// Define WUFFS_CONFIG__STATIC_FUNCTIONS to make all of Wuffs' functions have
79// static storage. The motivation is discussed in the "ALLOW STATIC
80// IMPLEMENTATION" section of
81// https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
82#ifdef WUFFS_CONFIG__STATIC_FUNCTIONS
83#define WUFFS_BASE__MAYBE_STATIC static
84#else
85#define WUFFS_BASE__MAYBE_STATIC
86#endif
87
88// --------
89
90// Wuffs assumes that:
91// - converting a uint32_t to a size_t will never overflow.
92// - converting a size_t to a uint64_t will never overflow.
93#ifdef __WORDSIZE
94#if (__WORDSIZE != 32) && (__WORDSIZE != 64)
95#error "Wuffs requires a word size of either 32 or 64 bits"
96#endif
97#endif
98
99#if defined(__clang__)
100#define WUFFS_BASE__POTENTIALLY_UNUSED_FIELD __attribute__((unused))
101#else
102#define WUFFS_BASE__POTENTIALLY_UNUSED_FIELD
103#endif
104
105// Clang also defines "__GNUC__".
106#if defined(__GNUC__)
107#define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused))
108#define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result))
109#else
110#define WUFFS_BASE__POTENTIALLY_UNUSED
111#define WUFFS_BASE__WARN_UNUSED_RESULT
112#endif
113
114// Flags for wuffs_foo__bar__initialize functions.
115
116#define WUFFS_INITIALIZE__DEFAULT_OPTIONS ((uint32_t)0x00000000)
117
118// WUFFS_INITIALIZE__ALREADY_ZEROED means that the "self" receiver struct value
119// has already been set to all zeroes.
120#define WUFFS_INITIALIZE__ALREADY_ZEROED ((uint32_t)0x00000001)
121
122// WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED means that, absent
123// WUFFS_INITIALIZE__ALREADY_ZEROED, only some of the "self" receiver struct
124// value will be set to all zeroes. Internal buffers, which tend to be a large
125// proportion of the struct's size, will be left uninitialized. Internal means
126// that the buffer is contained by the receiver struct, as opposed to being
127// passed as a separately allocated "work buffer".
128//
129// For more detail, see:
130// https://github.com/google/wuffs/blob/master/doc/note/initialization.md
131#define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \
132 ((uint32_t)0x00000002)
133
134// --------
135
136// wuffs_base__empty_struct is used when a Wuffs function returns an empty
137// struct. In C, if a function f returns void, you can't say "x = f()", but in
138// Wuffs, if a function g returns empty, you can say "y = g()".
139typedef struct {
140 // private_impl is a placeholder field. It isn't explicitly used, except that
141 // without it, the sizeof a struct with no fields can differ across C/C++
142 // compilers, and it is undefined behavior in C99. For example, gcc says that
143 // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
144 // ABI incompatibility if a Wuffs .c file is processed by one compiler and
145 // its .h file with another compiler.
146 //
147 // Instead, we explicitly insert an otherwise unused field, so that the
148 // sizeof this struct is always 1.
149 uint8_t private_impl;
150} wuffs_base__empty_struct;
151
152static inline wuffs_base__empty_struct //
153wuffs_base__make_empty_struct() {
154 wuffs_base__empty_struct ret;
155 ret.private_impl = 0;
156 return ret;
157}
158
159// wuffs_base__utility is a placeholder receiver type. It enables what Java
160// calls static methods, as opposed to regular methods.
161typedef struct {
162 // private_impl is a placeholder field. It isn't explicitly used, except that
163 // without it, the sizeof a struct with no fields can differ across C/C++
164 // compilers, and it is undefined behavior in C99. For example, gcc says that
165 // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
166 // ABI incompatibility if a Wuffs .c file is processed by one compiler and
167 // its .h file with another compiler.
168 //
169 // Instead, we explicitly insert an otherwise unused field, so that the
170 // sizeof this struct is always 1.
171 uint8_t private_impl;
172} wuffs_base__utility;
173
174typedef struct {
175 const char* vtable_name;
176 const void* function_pointers;
177} wuffs_base__vtable;
178
179// --------
180
181// See https://github.com/google/wuffs/blob/master/doc/note/statuses.md
182typedef struct {
183 const char* repr;
184
185#ifdef __cplusplus
186 inline bool is_complete() const;
187 inline bool is_error() const;
188 inline bool is_note() const;
189 inline bool is_ok() const;
190 inline bool is_suspension() const;
191 inline const char* message() const;
192#endif // __cplusplus
193
194} wuffs_base__status;
195
196extern const char* wuffs_base__note__i_o_redirect;
197extern const char* wuffs_base__note__end_of_data;
198extern const char* wuffs_base__note__metadata_reported;
199extern const char* wuffs_base__suspension__even_more_information;
200extern const char* wuffs_base__suspension__mispositioned_read;
201extern const char* wuffs_base__suspension__mispositioned_write;
202extern const char* wuffs_base__suspension__short_read;
203extern const char* wuffs_base__suspension__short_write;
204extern const char* wuffs_base__error__bad_i_o_position;
205extern const char* wuffs_base__error__bad_argument_length_too_short;
206extern const char* wuffs_base__error__bad_argument;
207extern const char* wuffs_base__error__bad_call_sequence;
208extern const char* wuffs_base__error__bad_receiver;
209extern const char* wuffs_base__error__bad_restart;
210extern const char* wuffs_base__error__bad_sizeof_receiver;
211extern const char* wuffs_base__error__bad_vtable;
212extern const char* wuffs_base__error__bad_workbuf_length;
213extern const char* wuffs_base__error__bad_wuffs_version;
214extern const char* wuffs_base__error__cannot_return_a_suspension;
215extern const char* wuffs_base__error__disabled_by_previous_error;
216extern const char* wuffs_base__error__initialize_falsely_claimed_already_zeroed;
217extern const char* wuffs_base__error__initialize_not_called;
218extern const char* wuffs_base__error__interleaved_coroutine_calls;
219extern const char* wuffs_base__error__no_more_information;
220extern const char* wuffs_base__error__not_enough_data;
221extern const char* wuffs_base__error__out_of_bounds;
222extern const char* wuffs_base__error__unsupported_method;
223extern const char* wuffs_base__error__unsupported_option;
224extern const char* wuffs_base__error__unsupported_pixel_swizzler_option;
225extern const char* wuffs_base__error__too_much_data;
226
227static inline wuffs_base__status //
228wuffs_base__make_status(const char* repr) {
229 wuffs_base__status z;
230 z.repr = repr;
231 return z;
232}
233
234static inline bool //
235wuffs_base__status__is_complete(const wuffs_base__status* z) {
236 return (z->repr == NULL) || ((*z->repr != '$') && (*z->repr != '#'));
237}
238
239static inline bool //
240wuffs_base__status__is_error(const wuffs_base__status* z) {
241 return z->repr && (*z->repr == '#');
242}
243
244static inline bool //
245wuffs_base__status__is_note(const wuffs_base__status* z) {
246 return z->repr && (*z->repr != '$') && (*z->repr != '#');
247}
248
249static inline bool //
250wuffs_base__status__is_ok(const wuffs_base__status* z) {
251 return z->repr == NULL;
252}
253
254static inline bool //
255wuffs_base__status__is_suspension(const wuffs_base__status* z) {
256 return z->repr && (*z->repr == '$');
257}
258
259// wuffs_base__status__message strips the leading '$', '#' or '@'.
260static inline const char* //
261wuffs_base__status__message(const wuffs_base__status* z) {
262 if (z->repr) {
263 if ((*z->repr == '$') || (*z->repr == '#') || (*z->repr == '@')) {
264 return z->repr + 1;
265 }
266 }
267 return z->repr;
268}
269
270#ifdef __cplusplus
271
272inline bool //
273wuffs_base__status::is_complete() const {
274 return wuffs_base__status__is_complete(this);
275}
276
277inline bool //
278wuffs_base__status::is_error() const {
279 return wuffs_base__status__is_error(this);
280}
281
282inline bool //
283wuffs_base__status::is_note() const {
284 return wuffs_base__status__is_note(this);
285}
286
287inline bool //
288wuffs_base__status::is_ok() const {
289 return wuffs_base__status__is_ok(this);
290}
291
292inline bool //
293wuffs_base__status::is_suspension() const {
294 return wuffs_base__status__is_suspension(this);
295}
296
297inline const char* //
298wuffs_base__status::message() const {
299 return wuffs_base__status__message(this);
300}
301
302#endif // __cplusplus
303
304// --------
305
306// WUFFS_BASE__RESULT is a result type: either a status (an error) or a value.
307//
308// A result with all fields NULL or zero is as valid as a zero-valued T.
309#define WUFFS_BASE__RESULT(T) \
310 struct { \
311 wuffs_base__status status; \
312 T value; \
313 }
314
315typedef WUFFS_BASE__RESULT(double) wuffs_base__result_f64;
316typedef WUFFS_BASE__RESULT(int64_t) wuffs_base__result_i64;
317typedef WUFFS_BASE__RESULT(uint64_t) wuffs_base__result_u64;
318
319// --------
320
321// FourCC constants.
322
323// International Color Consortium Profile.
324#define WUFFS_BASE__FOURCC__ICCP 0x49434350
325
326// Joint Photographic Experts Group.
327#define WUFFS_BASE__FOURCC__JPEG 0x4A504547
328
329// Portable Network Graphics.
330#define WUFFS_BASE__FOURCC__PNG 0x504E4720
331
332// Extensible Metadata Platform.
333#define WUFFS_BASE__FOURCC__XMP 0x584D5020
334
335// --------
336
337// Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a
338// second. See https://github.com/OculusVR/Flicks
339typedef int64_t wuffs_base__flicks;
340
341#define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000)
342#define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600)
343
344// ---------------- Numeric Types
345
346// The helpers below are functions, instead of macros, because their arguments
347// can be an expression that we shouldn't evaluate more than once.
348//
349// They are static, so that linking multiple wuffs .o files won't complain about
350// duplicate function definitions.
351//
352// They are explicitly marked inline, even if modern compilers don't use the
353// inline attribute to guide optimizations such as inlining, to avoid the
354// -Wunused-function warning, and we like to compile with -Wall -Werror.
355
356static inline uint8_t //
357wuffs_base__u8__min(uint8_t x, uint8_t y) {
358 return x < y ? x : y;
359}
360
361static inline uint8_t //
362wuffs_base__u8__max(uint8_t x, uint8_t y) {
363 return x > y ? x : y;
364}
365
366static inline uint16_t //
367wuffs_base__u16__min(uint16_t x, uint16_t y) {
368 return x < y ? x : y;
369}
370
371static inline uint16_t //
372wuffs_base__u16__max(uint16_t x, uint16_t y) {
373 return x > y ? x : y;
374}
375
376static inline uint32_t //
377wuffs_base__u32__min(uint32_t x, uint32_t y) {
378 return x < y ? x : y;
379}
380
381static inline uint32_t //
382wuffs_base__u32__max(uint32_t x, uint32_t y) {
383 return x > y ? x : y;
384}
385
386static inline uint64_t //
387wuffs_base__u64__min(uint64_t x, uint64_t y) {
388 return x < y ? x : y;
389}
390
391static inline uint64_t //
392wuffs_base__u64__max(uint64_t x, uint64_t y) {
393 return x > y ? x : y;
394}
395
396// --------
397
398// Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms
399// are per https://locklessinc.com/articles/sat_arithmetic/
400//
401// It is important that the underlying types are unsigned integers, as signed
402// integer arithmetic overflow is undefined behavior in C.
403
404static inline uint8_t //
405wuffs_base__u8__sat_add(uint8_t x, uint8_t y) {
406 uint8_t res = (uint8_t)(x + y);
407 res |= (uint8_t)(-(res < x));
408 return res;
409}
410
411static inline uint8_t //
412wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) {
413 uint8_t res = (uint8_t)(x - y);
414 res &= (uint8_t)(-(res <= x));
415 return res;
416}
417
418static inline uint16_t //
419wuffs_base__u16__sat_add(uint16_t x, uint16_t y) {
420 uint16_t res = (uint16_t)(x + y);
421 res |= (uint16_t)(-(res < x));
422 return res;
423}
424
425static inline uint16_t //
426wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) {
427 uint16_t res = (uint16_t)(x - y);
428 res &= (uint16_t)(-(res <= x));
429 return res;
430}
431
432static inline uint32_t //
433wuffs_base__u32__sat_add(uint32_t x, uint32_t y) {
434 uint32_t res = (uint32_t)(x + y);
435 res |= (uint32_t)(-(res < x));
436 return res;
437}
438
439static inline uint32_t //
440wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) {
441 uint32_t res = (uint32_t)(x - y);
442 res &= (uint32_t)(-(res <= x));
443 return res;
444}
445
446static inline uint64_t //
447wuffs_base__u64__sat_add(uint64_t x, uint64_t y) {
448 uint64_t res = (uint64_t)(x + y);
449 res |= (uint64_t)(-(res < x));
450 return res;
451}
452
453static inline uint64_t //
454wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) {
455 uint64_t res = (uint64_t)(x - y);
456 res &= (uint64_t)(-(res <= x));
457 return res;
458}
459
460// --------
461
462typedef struct {
463 uint64_t hi;
464 uint64_t lo;
465} wuffs_base__multiply_u64__output;
466
467// wuffs_base__multiply_u64 returns x*y as a 128-bit value.
468//
469// The maximum inclusive output hi_lo is 0xFFFFFFFFFFFFFFFE_0000000000000001.
470static inline wuffs_base__multiply_u64__output //
471wuffs_base__multiply_u64(uint64_t x, uint64_t y) {
472 uint64_t x0 = x & 0xFFFFFFFF;
473 uint64_t x1 = x >> 32;
474 uint64_t y0 = y & 0xFFFFFFFF;
475 uint64_t y1 = y >> 32;
476 uint64_t w0 = x0 * y0;
477 uint64_t t = (x1 * y0) + (w0 >> 32);
478 uint64_t w1 = t & 0xFFFFFFFF;
479 uint64_t w2 = t >> 32;
480 w1 += x0 * y1;
481 wuffs_base__multiply_u64__output o;
482 o.hi = (x1 * y1) + w2 + (w1 >> 32);
483 o.lo = x * y;
484 return o;
485}
486
487// --------
488
489#if defined(__GNUC__) && (__SIZEOF_LONG__ == 8)
490
491static inline uint32_t //
492wuffs_base__count_leading_zeroes_u64(uint64_t u) {
493 return u ? ((uint32_t)(__builtin_clzl(u))) : 64u;
494}
495
496#else
497
498static inline uint32_t //
499wuffs_base__count_leading_zeroes_u64(uint64_t u) {
500 if (u == 0) {
501 return 64;
502 }
503
504 uint32_t n = 0;
505 if ((u >> 32) == 0) {
506 n |= 32;
507 u <<= 32;
508 }
509 if ((u >> 48) == 0) {
510 n |= 16;
511 u <<= 16;
512 }
513 if ((u >> 56) == 0) {
514 n |= 8;
515 u <<= 8;
516 }
517 if ((u >> 60) == 0) {
518 n |= 4;
519 u <<= 4;
520 }
521 if ((u >> 62) == 0) {
522 n |= 2;
523 u <<= 2;
524 }
525 if ((u >> 63) == 0) {
526 n |= 1;
527 u <<= 1;
528 }
529 return n;
530}
531
532#endif // defined(__GNUC__) && (__SIZEOF_LONG__ == 8)
533
534// --------
535
536#define wuffs_base__load_u8be__no_bounds_check \
537 wuffs_base__load_u8__no_bounds_check
538#define wuffs_base__load_u8le__no_bounds_check \
539 wuffs_base__load_u8__no_bounds_check
540
541static inline uint8_t //
542wuffs_base__load_u8__no_bounds_check(const uint8_t* p) {
543 return p[0];
544}
545
546static inline uint16_t //
547wuffs_base__load_u16be__no_bounds_check(const uint8_t* p) {
548 return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
549}
550
551static inline uint16_t //
552wuffs_base__load_u16le__no_bounds_check(const uint8_t* p) {
553 return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
554}
555
556static inline uint32_t //
557wuffs_base__load_u24be__no_bounds_check(const uint8_t* p) {
558 return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
559 ((uint32_t)(p[2]) << 0);
560}
561
562static inline uint32_t //
563wuffs_base__load_u24le__no_bounds_check(const uint8_t* p) {
564 return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
565 ((uint32_t)(p[2]) << 16);
566}
567
568static inline uint32_t //
569wuffs_base__load_u32be__no_bounds_check(const uint8_t* p) {
570 return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
571 ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
572}
573
574static inline uint32_t //
575wuffs_base__load_u32le__no_bounds_check(const uint8_t* p) {
576 return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
577 ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
578}
579
580static inline uint64_t //
581wuffs_base__load_u40be__no_bounds_check(const uint8_t* p) {
582 return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
583 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
584 ((uint64_t)(p[4]) << 0);
585}
586
587static inline uint64_t //
588wuffs_base__load_u40le__no_bounds_check(const uint8_t* p) {
589 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
590 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
591 ((uint64_t)(p[4]) << 32);
592}
593
594static inline uint64_t //
595wuffs_base__load_u48be__no_bounds_check(const uint8_t* p) {
596 return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
597 ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
598 ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
599}
600
601static inline uint64_t //
602wuffs_base__load_u48le__no_bounds_check(const uint8_t* p) {
603 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
604 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
605 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
606}
607
608static inline uint64_t //
609wuffs_base__load_u56be__no_bounds_check(const uint8_t* p) {
610 return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
611 ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
612 ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
613 ((uint64_t)(p[6]) << 0);
614}
615
616static inline uint64_t //
617wuffs_base__load_u56le__no_bounds_check(const uint8_t* p) {
618 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
619 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
620 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
621 ((uint64_t)(p[6]) << 48);
622}
623
624static inline uint64_t //
625wuffs_base__load_u64be__no_bounds_check(const uint8_t* p) {
626 return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
627 ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
628 ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
629 ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
630}
631
632static inline uint64_t //
633wuffs_base__load_u64le__no_bounds_check(const uint8_t* p) {
634 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
635 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
636 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
637 ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
638}
639
640// --------
641
642#define wuffs_base__store_u8be__no_bounds_check \
643 wuffs_base__store_u8__no_bounds_check
644#define wuffs_base__store_u8le__no_bounds_check \
645 wuffs_base__store_u8__no_bounds_check
646
647static inline void //
648wuffs_base__store_u8__no_bounds_check(uint8_t* p, uint8_t x) {
649 p[0] = x;
650}
651
652static inline void //
653wuffs_base__store_u16be__no_bounds_check(uint8_t* p, uint16_t x) {
654 p[0] = (uint8_t)(x >> 8);
655 p[1] = (uint8_t)(x >> 0);
656}
657
658static inline void //
659wuffs_base__store_u16le__no_bounds_check(uint8_t* p, uint16_t x) {
660 p[0] = (uint8_t)(x >> 0);
661 p[1] = (uint8_t)(x >> 8);
662}
663
664static inline void //
665wuffs_base__store_u24be__no_bounds_check(uint8_t* p, uint32_t x) {
666 p[0] = (uint8_t)(x >> 16);
667 p[1] = (uint8_t)(x >> 8);
668 p[2] = (uint8_t)(x >> 0);
669}
670
671static inline void //
672wuffs_base__store_u24le__no_bounds_check(uint8_t* p, uint32_t x) {
673 p[0] = (uint8_t)(x >> 0);
674 p[1] = (uint8_t)(x >> 8);
675 p[2] = (uint8_t)(x >> 16);
676}
677
678static inline void //
679wuffs_base__store_u32be__no_bounds_check(uint8_t* p, uint32_t x) {
680 p[0] = (uint8_t)(x >> 24);
681 p[1] = (uint8_t)(x >> 16);
682 p[2] = (uint8_t)(x >> 8);
683 p[3] = (uint8_t)(x >> 0);
684}
685
686static inline void //
687wuffs_base__store_u32le__no_bounds_check(uint8_t* p, uint32_t x) {
688 p[0] = (uint8_t)(x >> 0);
689 p[1] = (uint8_t)(x >> 8);
690 p[2] = (uint8_t)(x >> 16);
691 p[3] = (uint8_t)(x >> 24);
692}
693
694static inline void //
695wuffs_base__store_u40be__no_bounds_check(uint8_t* p, uint64_t x) {
696 p[0] = (uint8_t)(x >> 32);
697 p[1] = (uint8_t)(x >> 24);
698 p[2] = (uint8_t)(x >> 16);
699 p[3] = (uint8_t)(x >> 8);
700 p[4] = (uint8_t)(x >> 0);
701}
702
703static inline void //
704wuffs_base__store_u40le__no_bounds_check(uint8_t* p, uint64_t x) {
705 p[0] = (uint8_t)(x >> 0);
706 p[1] = (uint8_t)(x >> 8);
707 p[2] = (uint8_t)(x >> 16);
708 p[3] = (uint8_t)(x >> 24);
709 p[4] = (uint8_t)(x >> 32);
710}
711
712static inline void //
713wuffs_base__store_u48be__no_bounds_check(uint8_t* p, uint64_t x) {
714 p[0] = (uint8_t)(x >> 40);
715 p[1] = (uint8_t)(x >> 32);
716 p[2] = (uint8_t)(x >> 24);
717 p[3] = (uint8_t)(x >> 16);
718 p[4] = (uint8_t)(x >> 8);
719 p[5] = (uint8_t)(x >> 0);
720}
721
722static inline void //
723wuffs_base__store_u48le__no_bounds_check(uint8_t* p, uint64_t x) {
724 p[0] = (uint8_t)(x >> 0);
725 p[1] = (uint8_t)(x >> 8);
726 p[2] = (uint8_t)(x >> 16);
727 p[3] = (uint8_t)(x >> 24);
728 p[4] = (uint8_t)(x >> 32);
729 p[5] = (uint8_t)(x >> 40);
730}
731
732static inline void //
733wuffs_base__store_u56be__no_bounds_check(uint8_t* p, uint64_t x) {
734 p[0] = (uint8_t)(x >> 48);
735 p[1] = (uint8_t)(x >> 40);
736 p[2] = (uint8_t)(x >> 32);
737 p[3] = (uint8_t)(x >> 24);
738 p[4] = (uint8_t)(x >> 16);
739 p[5] = (uint8_t)(x >> 8);
740 p[6] = (uint8_t)(x >> 0);
741}
742
743static inline void //
744wuffs_base__store_u56le__no_bounds_check(uint8_t* p, uint64_t x) {
745 p[0] = (uint8_t)(x >> 0);
746 p[1] = (uint8_t)(x >> 8);
747 p[2] = (uint8_t)(x >> 16);
748 p[3] = (uint8_t)(x >> 24);
749 p[4] = (uint8_t)(x >> 32);
750 p[5] = (uint8_t)(x >> 40);
751 p[6] = (uint8_t)(x >> 48);
752}
753
754static inline void //
755wuffs_base__store_u64be__no_bounds_check(uint8_t* p, uint64_t x) {
756 p[0] = (uint8_t)(x >> 56);
757 p[1] = (uint8_t)(x >> 48);
758 p[2] = (uint8_t)(x >> 40);
759 p[3] = (uint8_t)(x >> 32);
760 p[4] = (uint8_t)(x >> 24);
761 p[5] = (uint8_t)(x >> 16);
762 p[6] = (uint8_t)(x >> 8);
763 p[7] = (uint8_t)(x >> 0);
764}
765
766static inline void //
767wuffs_base__store_u64le__no_bounds_check(uint8_t* p, uint64_t x) {
768 p[0] = (uint8_t)(x >> 0);
769 p[1] = (uint8_t)(x >> 8);
770 p[2] = (uint8_t)(x >> 16);
771 p[3] = (uint8_t)(x >> 24);
772 p[4] = (uint8_t)(x >> 32);
773 p[5] = (uint8_t)(x >> 40);
774 p[6] = (uint8_t)(x >> 48);
775 p[7] = (uint8_t)(x >> 56);
776}
777
778// ---------------- Slices and Tables
779
780// WUFFS_BASE__SLICE is a 1-dimensional buffer.
781//
782// len measures a number of elements, not necessarily a size in bytes.
783//
784// A value with all fields NULL or zero is a valid, empty slice.
785#define WUFFS_BASE__SLICE(T) \
786 struct { \
787 T* ptr; \
788 size_t len; \
789 }
790
791// WUFFS_BASE__TABLE is a 2-dimensional buffer.
792//
793// width height, and stride measure a number of elements, not necessarily a
794// size in bytes.
795//
796// A value with all fields NULL or zero is a valid, empty table.
797#define WUFFS_BASE__TABLE(T) \
798 struct { \
799 T* ptr; \
800 size_t width; \
801 size_t height; \
802 size_t stride; \
803 }
804
805typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;
806typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;
807typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;
808typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;
809
810typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8;
811typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;
812typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;
813typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;
814
815static inline wuffs_base__slice_u8 //
816wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {
817 wuffs_base__slice_u8 ret;
818 ret.ptr = ptr;
819 ret.len = len;
820 return ret;
821}
822
823static inline wuffs_base__slice_u16 //
824wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {
825 wuffs_base__slice_u16 ret;
826 ret.ptr = ptr;
827 ret.len = len;
828 return ret;
829}
830
831static inline wuffs_base__slice_u32 //
832wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {
833 wuffs_base__slice_u32 ret;
834 ret.ptr = ptr;
835 ret.len = len;
836 return ret;
837}
838
839static inline wuffs_base__slice_u64 //
840wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {
841 wuffs_base__slice_u64 ret;
842 ret.ptr = ptr;
843 ret.len = len;
844 return ret;
845}
846
847static inline wuffs_base__slice_u8 //
848wuffs_base__empty_slice_u8() {
849 wuffs_base__slice_u8 ret;
850 ret.ptr = NULL;
851 ret.len = 0;
852 return ret;
853}
854
855static inline wuffs_base__table_u8 //
856wuffs_base__empty_table_u8() {
857 wuffs_base__table_u8 ret;
858 ret.ptr = NULL;
859 ret.width = 0;
860 ret.height = 0;
861 ret.stride = 0;
862 return ret;
863}
864
865// wuffs_base__slice_u8__subslice_i returns s[i:].
866//
867// It returns an empty slice if i is out of bounds.
868static inline wuffs_base__slice_u8 //
869wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {
870 if ((i <= SIZE_MAX) && (i <= s.len)) {
871 return wuffs_base__make_slice_u8(s.ptr + i, s.len - i);
872 }
873 return wuffs_base__make_slice_u8(NULL, 0);
874}
875
876// wuffs_base__slice_u8__subslice_j returns s[:j].
877//
878// It returns an empty slice if j is out of bounds.
879static inline wuffs_base__slice_u8 //
880wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {
881 if ((j <= SIZE_MAX) && (j <= s.len)) {
882 return wuffs_base__make_slice_u8(s.ptr, j);
883 }
884 return wuffs_base__make_slice_u8(NULL, 0);
885}
886
887// wuffs_base__slice_u8__subslice_ij returns s[i:j].
888//
889// It returns an empty slice if i or j is out of bounds.
890static inline wuffs_base__slice_u8 //
891wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,
892 uint64_t i,
893 uint64_t j) {
894 if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {
895 return wuffs_base__make_slice_u8(s.ptr + i, j - i);
896 }
897 return wuffs_base__make_slice_u8(NULL, 0);
898}
899
900// ---------------- Ranges and Rects
901
902// See https://github.com/google/wuffs/blob/master/doc/note/ranges-and-rects.md
903
904typedef struct wuffs_base__range_ii_u32__struct {
905 uint32_t min_incl;
906 uint32_t max_incl;
907
908#ifdef __cplusplus
909 inline bool is_empty() const;
910 inline bool equals(wuffs_base__range_ii_u32__struct s) const;
911 inline wuffs_base__range_ii_u32__struct intersect(
912 wuffs_base__range_ii_u32__struct s) const;
913 inline wuffs_base__range_ii_u32__struct unite(
914 wuffs_base__range_ii_u32__struct s) const;
915 inline bool contains(uint32_t x) const;
916 inline bool contains_range(wuffs_base__range_ii_u32__struct s) const;
917#endif // __cplusplus
918
919} wuffs_base__range_ii_u32;
920
921static inline wuffs_base__range_ii_u32 //
922wuffs_base__empty_range_ii_u32() {
923 wuffs_base__range_ii_u32 ret;
924 ret.min_incl = 0;
925 ret.max_incl = 0;
926 return ret;
927}
928
929static inline wuffs_base__range_ii_u32 //
930wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) {
931 wuffs_base__range_ii_u32 ret;
932 ret.min_incl = min_incl;
933 ret.max_incl = max_incl;
934 return ret;
935}
936
937static inline bool //
938wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) {
939 return r->min_incl > r->max_incl;
940}
941
942static inline bool //
943wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r,
944 wuffs_base__range_ii_u32 s) {
945 return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
946 (wuffs_base__range_ii_u32__is_empty(r) &&
947 wuffs_base__range_ii_u32__is_empty(&s));
948}
949
950static inline wuffs_base__range_ii_u32 //
951wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r,
952 wuffs_base__range_ii_u32 s) {
953 wuffs_base__range_ii_u32 t;
954 t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
955 t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl);
956 return t;
957}
958
959static inline wuffs_base__range_ii_u32 //
960wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r,
961 wuffs_base__range_ii_u32 s) {
962 if (wuffs_base__range_ii_u32__is_empty(r)) {
963 return s;
964 }
965 if (wuffs_base__range_ii_u32__is_empty(&s)) {
966 return *r;
967 }
968 wuffs_base__range_ii_u32 t;
969 t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
970 t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl);
971 return t;
972}
973
974static inline bool //
975wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r,
976 uint32_t x) {
977 return (r->min_incl <= x) && (x <= r->max_incl);
978}
979
980static inline bool //
981wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r,
982 wuffs_base__range_ii_u32 s) {
983 return wuffs_base__range_ii_u32__equals(
984 &s, wuffs_base__range_ii_u32__intersect(r, s));
985}
986
987#ifdef __cplusplus
988
989inline bool //
990wuffs_base__range_ii_u32::is_empty() const {
991 return wuffs_base__range_ii_u32__is_empty(this);
992}
993
994inline bool //
995wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const {
996 return wuffs_base__range_ii_u32__equals(this, s);
997}
998
999inline wuffs_base__range_ii_u32 //
1000wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const {
1001 return wuffs_base__range_ii_u32__intersect(this, s);
1002}
1003
1004inline wuffs_base__range_ii_u32 //
1005wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const {
1006 return wuffs_base__range_ii_u32__unite(this, s);
1007}
1008
1009inline bool //
1010wuffs_base__range_ii_u32::contains(uint32_t x) const {
1011 return wuffs_base__range_ii_u32__contains(this, x);
1012}
1013
1014inline bool //
1015wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const {
1016 return wuffs_base__range_ii_u32__contains_range(this, s);
1017}
1018
1019#endif // __cplusplus
1020
1021// --------
1022
1023typedef struct wuffs_base__range_ie_u32__struct {
1024 uint32_t min_incl;
1025 uint32_t max_excl;
1026
1027#ifdef __cplusplus
1028 inline bool is_empty() const;
1029 inline bool equals(wuffs_base__range_ie_u32__struct s) const;
1030 inline wuffs_base__range_ie_u32__struct intersect(
1031 wuffs_base__range_ie_u32__struct s) const;
1032 inline wuffs_base__range_ie_u32__struct unite(
1033 wuffs_base__range_ie_u32__struct s) const;
1034 inline bool contains(uint32_t x) const;
1035 inline bool contains_range(wuffs_base__range_ie_u32__struct s) const;
1036 inline uint32_t length() const;
1037#endif // __cplusplus
1038
1039} wuffs_base__range_ie_u32;
1040
1041static inline wuffs_base__range_ie_u32 //
1042wuffs_base__empty_range_ie_u32() {
1043 wuffs_base__range_ie_u32 ret;
1044 ret.min_incl = 0;
1045 ret.max_excl = 0;
1046 return ret;
1047}
1048
1049static inline wuffs_base__range_ie_u32 //
1050wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) {
1051 wuffs_base__range_ie_u32 ret;
1052 ret.min_incl = min_incl;
1053 ret.max_excl = max_excl;
1054 return ret;
1055}
1056
1057static inline bool //
1058wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) {
1059 return r->min_incl >= r->max_excl;
1060}
1061
1062static inline bool //
1063wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r,
1064 wuffs_base__range_ie_u32 s) {
1065 return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
1066 (wuffs_base__range_ie_u32__is_empty(r) &&
1067 wuffs_base__range_ie_u32__is_empty(&s));
1068}
1069
1070static inline wuffs_base__range_ie_u32 //
1071wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r,
1072 wuffs_base__range_ie_u32 s) {
1073 wuffs_base__range_ie_u32 t;
1074 t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1075 t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl);
1076 return t;
1077}
1078
1079static inline wuffs_base__range_ie_u32 //
1080wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r,
1081 wuffs_base__range_ie_u32 s) {
1082 if (wuffs_base__range_ie_u32__is_empty(r)) {
1083 return s;
1084 }
1085 if (wuffs_base__range_ie_u32__is_empty(&s)) {
1086 return *r;
1087 }
1088 wuffs_base__range_ie_u32 t;
1089 t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1090 t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl);
1091 return t;
1092}
1093
1094static inline bool //
1095wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r,
1096 uint32_t x) {
1097 return (r->min_incl <= x) && (x < r->max_excl);
1098}
1099
1100static inline bool //
1101wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r,
1102 wuffs_base__range_ie_u32 s) {
1103 return wuffs_base__range_ie_u32__equals(
1104 &s, wuffs_base__range_ie_u32__intersect(r, s));
1105}
1106
1107static inline uint32_t //
1108wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) {
1109 return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl);
1110}
1111
1112#ifdef __cplusplus
1113
1114inline bool //
1115wuffs_base__range_ie_u32::is_empty() const {
1116 return wuffs_base__range_ie_u32__is_empty(this);
1117}
1118
1119inline bool //
1120wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const {
1121 return wuffs_base__range_ie_u32__equals(this, s);
1122}
1123
1124inline wuffs_base__range_ie_u32 //
1125wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const {
1126 return wuffs_base__range_ie_u32__intersect(this, s);
1127}
1128
1129inline wuffs_base__range_ie_u32 //
1130wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const {
1131 return wuffs_base__range_ie_u32__unite(this, s);
1132}
1133
1134inline bool //
1135wuffs_base__range_ie_u32::contains(uint32_t x) const {
1136 return wuffs_base__range_ie_u32__contains(this, x);
1137}
1138
1139inline bool //
1140wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const {
1141 return wuffs_base__range_ie_u32__contains_range(this, s);
1142}
1143
1144inline uint32_t //
1145wuffs_base__range_ie_u32::length() const {
1146 return wuffs_base__range_ie_u32__length(this);
1147}
1148
1149#endif // __cplusplus
1150
1151// --------
1152
1153typedef struct wuffs_base__range_ii_u64__struct {
1154 uint64_t min_incl;
1155 uint64_t max_incl;
1156
1157#ifdef __cplusplus
1158 inline bool is_empty() const;
1159 inline bool equals(wuffs_base__range_ii_u64__struct s) const;
1160 inline wuffs_base__range_ii_u64__struct intersect(
1161 wuffs_base__range_ii_u64__struct s) const;
1162 inline wuffs_base__range_ii_u64__struct unite(
1163 wuffs_base__range_ii_u64__struct s) const;
1164 inline bool contains(uint64_t x) const;
1165 inline bool contains_range(wuffs_base__range_ii_u64__struct s) const;
1166#endif // __cplusplus
1167
1168} wuffs_base__range_ii_u64;
1169
1170static inline wuffs_base__range_ii_u64 //
1171wuffs_base__empty_range_ii_u64() {
1172 wuffs_base__range_ii_u64 ret;
1173 ret.min_incl = 0;
1174 ret.max_incl = 0;
1175 return ret;
1176}
1177
1178static inline wuffs_base__range_ii_u64 //
1179wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) {
1180 wuffs_base__range_ii_u64 ret;
1181 ret.min_incl = min_incl;
1182 ret.max_incl = max_incl;
1183 return ret;
1184}
1185
1186static inline bool //
1187wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) {
1188 return r->min_incl > r->max_incl;
1189}
1190
1191static inline bool //
1192wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r,
1193 wuffs_base__range_ii_u64 s) {
1194 return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
1195 (wuffs_base__range_ii_u64__is_empty(r) &&
1196 wuffs_base__range_ii_u64__is_empty(&s));
1197}
1198
1199static inline wuffs_base__range_ii_u64 //
1200wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r,
1201 wuffs_base__range_ii_u64 s) {
1202 wuffs_base__range_ii_u64 t;
1203 t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
1204 t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl);
1205 return t;
1206}
1207
1208static inline wuffs_base__range_ii_u64 //
1209wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r,
1210 wuffs_base__range_ii_u64 s) {
1211 if (wuffs_base__range_ii_u64__is_empty(r)) {
1212 return s;
1213 }
1214 if (wuffs_base__range_ii_u64__is_empty(&s)) {
1215 return *r;
1216 }
1217 wuffs_base__range_ii_u64 t;
1218 t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
1219 t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl);
1220 return t;
1221}
1222
1223static inline bool //
1224wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r,
1225 uint64_t x) {
1226 return (r->min_incl <= x) && (x <= r->max_incl);
1227}
1228
1229static inline bool //
1230wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r,
1231 wuffs_base__range_ii_u64 s) {
1232 return wuffs_base__range_ii_u64__equals(
1233 &s, wuffs_base__range_ii_u64__intersect(r, s));
1234}
1235
1236#ifdef __cplusplus
1237
1238inline bool //
1239wuffs_base__range_ii_u64::is_empty() const {
1240 return wuffs_base__range_ii_u64__is_empty(this);
1241}
1242
1243inline bool //
1244wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const {
1245 return wuffs_base__range_ii_u64__equals(this, s);
1246}
1247
1248inline wuffs_base__range_ii_u64 //
1249wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const {
1250 return wuffs_base__range_ii_u64__intersect(this, s);
1251}
1252
1253inline wuffs_base__range_ii_u64 //
1254wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const {
1255 return wuffs_base__range_ii_u64__unite(this, s);
1256}
1257
1258inline bool //
1259wuffs_base__range_ii_u64::contains(uint64_t x) const {
1260 return wuffs_base__range_ii_u64__contains(this, x);
1261}
1262
1263inline bool //
1264wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const {
1265 return wuffs_base__range_ii_u64__contains_range(this, s);
1266}
1267
1268#endif // __cplusplus
1269
1270// --------
1271
1272typedef struct wuffs_base__range_ie_u64__struct {
1273 uint64_t min_incl;
1274 uint64_t max_excl;
1275
1276#ifdef __cplusplus
1277 inline bool is_empty() const;
1278 inline bool equals(wuffs_base__range_ie_u64__struct s) const;
1279 inline wuffs_base__range_ie_u64__struct intersect(
1280 wuffs_base__range_ie_u64__struct s) const;
1281 inline wuffs_base__range_ie_u64__struct unite(
1282 wuffs_base__range_ie_u64__struct s) const;
1283 inline bool contains(uint64_t x) const;
1284 inline bool contains_range(wuffs_base__range_ie_u64__struct s) const;
1285 inline uint64_t length() const;
1286#endif // __cplusplus
1287
1288} wuffs_base__range_ie_u64;
1289
1290static inline wuffs_base__range_ie_u64 //
1291wuffs_base__empty_range_ie_u64() {
1292 wuffs_base__range_ie_u64 ret;
1293 ret.min_incl = 0;
1294 ret.max_excl = 0;
1295 return ret;
1296}
1297
1298static inline wuffs_base__range_ie_u64 //
1299wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) {
1300 wuffs_base__range_ie_u64 ret;
1301 ret.min_incl = min_incl;
1302 ret.max_excl = max_excl;
1303 return ret;
1304}
1305
1306static inline bool //
1307wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) {
1308 return r->min_incl >= r->max_excl;
1309}
1310
1311static inline bool //
1312wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r,
1313 wuffs_base__range_ie_u64 s) {
1314 return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
1315 (wuffs_base__range_ie_u64__is_empty(r) &&
1316 wuffs_base__range_ie_u64__is_empty(&s));
1317}
1318
1319static inline wuffs_base__range_ie_u64 //
1320wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r,
1321 wuffs_base__range_ie_u64 s) {
1322 wuffs_base__range_ie_u64 t;
1323 t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
1324 t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl);
1325 return t;
1326}
1327
1328static inline wuffs_base__range_ie_u64 //
1329wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r,
1330 wuffs_base__range_ie_u64 s) {
1331 if (wuffs_base__range_ie_u64__is_empty(r)) {
1332 return s;
1333 }
1334 if (wuffs_base__range_ie_u64__is_empty(&s)) {
1335 return *r;
1336 }
1337 wuffs_base__range_ie_u64 t;
1338 t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
1339 t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl);
1340 return t;
1341}
1342
1343static inline bool //
1344wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r,
1345 uint64_t x) {
1346 return (r->min_incl <= x) && (x < r->max_excl);
1347}
1348
1349static inline bool //
1350wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r,
1351 wuffs_base__range_ie_u64 s) {
1352 return wuffs_base__range_ie_u64__equals(
1353 &s, wuffs_base__range_ie_u64__intersect(r, s));
1354}
1355
1356static inline uint64_t //
1357wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) {
1358 return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl);
1359}
1360
1361#ifdef __cplusplus
1362
1363inline bool //
1364wuffs_base__range_ie_u64::is_empty() const {
1365 return wuffs_base__range_ie_u64__is_empty(this);
1366}
1367
1368inline bool //
1369wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const {
1370 return wuffs_base__range_ie_u64__equals(this, s);
1371}
1372
1373inline wuffs_base__range_ie_u64 //
1374wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const {
1375 return wuffs_base__range_ie_u64__intersect(this, s);
1376}
1377
1378inline wuffs_base__range_ie_u64 //
1379wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const {
1380 return wuffs_base__range_ie_u64__unite(this, s);
1381}
1382
1383inline bool //
1384wuffs_base__range_ie_u64::contains(uint64_t x) const {
1385 return wuffs_base__range_ie_u64__contains(this, x);
1386}
1387
1388inline bool //
1389wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const {
1390 return wuffs_base__range_ie_u64__contains_range(this, s);
1391}
1392
1393inline uint64_t //
1394wuffs_base__range_ie_u64::length() const {
1395 return wuffs_base__range_ie_u64__length(this);
1396}
1397
1398#endif // __cplusplus
1399
1400// --------
1401
1402typedef struct wuffs_base__rect_ii_u32__struct {
1403 uint32_t min_incl_x;
1404 uint32_t min_incl_y;
1405 uint32_t max_incl_x;
1406 uint32_t max_incl_y;
1407
1408#ifdef __cplusplus
1409 inline bool is_empty() const;
1410 inline bool equals(wuffs_base__rect_ii_u32__struct s) const;
1411 inline wuffs_base__rect_ii_u32__struct intersect(
1412 wuffs_base__rect_ii_u32__struct s) const;
1413 inline wuffs_base__rect_ii_u32__struct unite(
1414 wuffs_base__rect_ii_u32__struct s) const;
1415 inline bool contains(uint32_t x, uint32_t y) const;
1416 inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const;
1417#endif // __cplusplus
1418
1419} wuffs_base__rect_ii_u32;
1420
1421static inline wuffs_base__rect_ii_u32 //
1422wuffs_base__empty_rect_ii_u32() {
1423 wuffs_base__rect_ii_u32 ret;
1424 ret.min_incl_x = 0;
1425 ret.min_incl_y = 0;
1426 ret.max_incl_x = 0;
1427 ret.max_incl_y = 0;
1428 return ret;
1429}
1430
1431static inline wuffs_base__rect_ii_u32 //
1432wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,
1433 uint32_t min_incl_y,
1434 uint32_t max_incl_x,
1435 uint32_t max_incl_y) {
1436 wuffs_base__rect_ii_u32 ret;
1437 ret.min_incl_x = min_incl_x;
1438 ret.min_incl_y = min_incl_y;
1439 ret.max_incl_x = max_incl_x;
1440 ret.max_incl_y = max_incl_y;
1441 return ret;
1442}
1443
1444static inline bool //
1445wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) {
1446 return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y);
1447}
1448
1449static inline bool //
1450wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r,
1451 wuffs_base__rect_ii_u32 s) {
1452 return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
1453 r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) ||
1454 (wuffs_base__rect_ii_u32__is_empty(r) &&
1455 wuffs_base__rect_ii_u32__is_empty(&s));
1456}
1457
1458static inline wuffs_base__rect_ii_u32 //
1459wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r,
1460 wuffs_base__rect_ii_u32 s) {
1461 wuffs_base__rect_ii_u32 t;
1462 t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
1463 t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
1464 t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x);
1465 t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y);
1466 return t;
1467}
1468
1469static inline wuffs_base__rect_ii_u32 //
1470wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r,
1471 wuffs_base__rect_ii_u32 s) {
1472 if (wuffs_base__rect_ii_u32__is_empty(r)) {
1473 return s;
1474 }
1475 if (wuffs_base__rect_ii_u32__is_empty(&s)) {
1476 return *r;
1477 }
1478 wuffs_base__rect_ii_u32 t;
1479 t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
1480 t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
1481 t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x);
1482 t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y);
1483 return t;
1484}
1485
1486static inline bool //
1487wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r,
1488 uint32_t x,
1489 uint32_t y) {
1490 return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) &&
1491 (y <= r->max_incl_y);
1492}
1493
1494static inline bool //
1495wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r,
1496 wuffs_base__rect_ii_u32 s) {
1497 return wuffs_base__rect_ii_u32__equals(
1498 &s, wuffs_base__rect_ii_u32__intersect(r, s));
1499}
1500
1501#ifdef __cplusplus
1502
1503inline bool //
1504wuffs_base__rect_ii_u32::is_empty() const {
1505 return wuffs_base__rect_ii_u32__is_empty(this);
1506}
1507
1508inline bool //
1509wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const {
1510 return wuffs_base__rect_ii_u32__equals(this, s);
1511}
1512
1513inline wuffs_base__rect_ii_u32 //
1514wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const {
1515 return wuffs_base__rect_ii_u32__intersect(this, s);
1516}
1517
1518inline wuffs_base__rect_ii_u32 //
1519wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const {
1520 return wuffs_base__rect_ii_u32__unite(this, s);
1521}
1522
1523inline bool //
1524wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const {
1525 return wuffs_base__rect_ii_u32__contains(this, x, y);
1526}
1527
1528inline bool //
1529wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const {
1530 return wuffs_base__rect_ii_u32__contains_rect(this, s);
1531}
1532
1533#endif // __cplusplus
1534
1535// --------
1536
1537typedef struct wuffs_base__rect_ie_u32__struct {
1538 uint32_t min_incl_x;
1539 uint32_t min_incl_y;
1540 uint32_t max_excl_x;
1541 uint32_t max_excl_y;
1542
1543#ifdef __cplusplus
1544 inline bool is_empty() const;
1545 inline bool equals(wuffs_base__rect_ie_u32__struct s) const;
1546 inline wuffs_base__rect_ie_u32__struct intersect(
1547 wuffs_base__rect_ie_u32__struct s) const;
1548 inline wuffs_base__rect_ie_u32__struct unite(
1549 wuffs_base__rect_ie_u32__struct s) const;
1550 inline bool contains(uint32_t x, uint32_t y) const;
1551 inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const;
1552 inline uint32_t width() const;
1553 inline uint32_t height() const;
1554#endif // __cplusplus
1555
1556} wuffs_base__rect_ie_u32;
1557
1558static inline wuffs_base__rect_ie_u32 //
1559wuffs_base__empty_rect_ie_u32() {
1560 wuffs_base__rect_ie_u32 ret;
1561 ret.min_incl_x = 0;
1562 ret.min_incl_y = 0;
1563 ret.max_excl_x = 0;
1564 ret.max_excl_y = 0;
1565 return ret;
1566}
1567
1568static inline wuffs_base__rect_ie_u32 //
1569wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,
1570 uint32_t min_incl_y,
1571 uint32_t max_excl_x,
1572 uint32_t max_excl_y) {
1573 wuffs_base__rect_ie_u32 ret;
1574 ret.min_incl_x = min_incl_x;
1575 ret.min_incl_y = min_incl_y;
1576 ret.max_excl_x = max_excl_x;
1577 ret.max_excl_y = max_excl_y;
1578 return ret;
1579}
1580
1581static inline bool //
1582wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) {
1583 return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y);
1584}
1585
1586static inline bool //
1587wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r,
1588 wuffs_base__rect_ie_u32 s) {
1589 return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
1590 r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) ||
1591 (wuffs_base__rect_ie_u32__is_empty(r) &&
1592 wuffs_base__rect_ie_u32__is_empty(&s));
1593}
1594
1595static inline wuffs_base__rect_ie_u32 //
1596wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r,
1597 wuffs_base__rect_ie_u32 s) {
1598 wuffs_base__rect_ie_u32 t;
1599 t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
1600 t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
1601 t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x);
1602 t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y);
1603 return t;
1604}
1605
1606static inline wuffs_base__rect_ie_u32 //
1607wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r,
1608 wuffs_base__rect_ie_u32 s) {
1609 if (wuffs_base__rect_ie_u32__is_empty(r)) {
1610 return s;
1611 }
1612 if (wuffs_base__rect_ie_u32__is_empty(&s)) {
1613 return *r;
1614 }
1615 wuffs_base__rect_ie_u32 t;
1616 t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
1617 t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
1618 t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x);
1619 t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y);
1620 return t;
1621}
1622
1623static inline bool //
1624wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r,
1625 uint32_t x,
1626 uint32_t y) {
1627 return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) &&
1628 (y < r->max_excl_y);
1629}
1630
1631static inline bool //
1632wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r,
1633 wuffs_base__rect_ie_u32 s) {
1634 return wuffs_base__rect_ie_u32__equals(
1635 &s, wuffs_base__rect_ie_u32__intersect(r, s));
1636}
1637
1638static inline uint32_t //
1639wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) {
1640 return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x);
1641}
1642
1643static inline uint32_t //
1644wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) {
1645 return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y);
1646}
1647
1648#ifdef __cplusplus
1649
1650inline bool //
1651wuffs_base__rect_ie_u32::is_empty() const {
1652 return wuffs_base__rect_ie_u32__is_empty(this);
1653}
1654
1655inline bool //
1656wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const {
1657 return wuffs_base__rect_ie_u32__equals(this, s);
1658}
1659
1660inline wuffs_base__rect_ie_u32 //
1661wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const {
1662 return wuffs_base__rect_ie_u32__intersect(this, s);
1663}
1664
1665inline wuffs_base__rect_ie_u32 //
1666wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const {
1667 return wuffs_base__rect_ie_u32__unite(this, s);
1668}
1669
1670inline bool //
1671wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const {
1672 return wuffs_base__rect_ie_u32__contains(this, x, y);
1673}
1674
1675inline bool //
1676wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const {
1677 return wuffs_base__rect_ie_u32__contains_rect(this, s);
1678}
1679
1680inline uint32_t //
1681wuffs_base__rect_ie_u32::width() const {
1682 return wuffs_base__rect_ie_u32__width(this);
1683}
1684
1685inline uint32_t //
1686wuffs_base__rect_ie_u32::height() const {
1687 return wuffs_base__rect_ie_u32__height(this);
1688}
1689
1690#endif // __cplusplus
1691
1692// ---------------- More Information
1693
1694// wuffs_base__more_information holds additional fields, typically when a Wuffs
1695// method returns a [note status](/doc/note/statuses.md).
1696//
1697// The flavor field follows the base38 namespace
1698// convention](/doc/note/base38-and-fourcc.md). The other fields' semantics
1699// depends on the flavor.
1700typedef struct {
1701 uint32_t flavor;
1702 uint32_t w;
1703 uint64_t x;
1704 uint64_t y;
1705 uint64_t z;
1706
1707#ifdef __cplusplus
1708 inline void set(uint32_t flavor_arg,
1709 uint32_t w_arg,
1710 uint64_t x_arg,
1711 uint64_t y_arg,
1712 uint64_t z_arg);
1713 inline uint32_t io_redirect__fourcc() const;
1714 inline wuffs_base__range_ie_u64 io_redirect__range() const;
1715 inline uint64_t io_seek__position() const;
1716 inline uint32_t metadata__fourcc() const;
1717 inline wuffs_base__range_ie_u64 metadata__range() const;
1718#endif // __cplusplus
1719
1720} wuffs_base__more_information;
1721
1722#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT 1
1723#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK 2
1724#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA 3
1725
1726static inline wuffs_base__more_information //
1727wuffs_base__empty_more_information() {
1728 wuffs_base__more_information ret;
1729 ret.flavor = 0;
1730 ret.w = 0;
1731 ret.x = 0;
1732 ret.y = 0;
1733 ret.z = 0;
1734 return ret;
1735}
1736
1737static inline void //
1738wuffs_base__more_information__set(wuffs_base__more_information* m,
1739 uint32_t flavor,
1740 uint32_t w,
1741 uint64_t x,
1742 uint64_t y,
1743 uint64_t z) {
1744 if (!m) {
1745 return;
1746 }
1747 m->flavor = flavor;
1748 m->w = w;
1749 m->x = x;
1750 m->y = y;
1751 m->z = z;
1752}
1753
1754static inline uint32_t //
1755wuffs_base__more_information__io_redirect__fourcc(
1756 const wuffs_base__more_information* m) {
1757 return m->w;
1758}
1759
1760static inline wuffs_base__range_ie_u64 //
1761wuffs_base__more_information__io_redirect__range(
1762 const wuffs_base__more_information* m) {
1763 wuffs_base__range_ie_u64 ret;
1764 ret.min_incl = m->y;
1765 ret.max_excl = m->z;
1766 return ret;
1767}
1768
1769static inline uint64_t //
1770wuffs_base__more_information__io_seek__position(
1771 const wuffs_base__more_information* m) {
1772 return m->x;
1773}
1774
1775static inline uint32_t //
1776wuffs_base__more_information__metadata__fourcc(
1777 const wuffs_base__more_information* m) {
1778 return m->w;
1779}
1780
1781static inline wuffs_base__range_ie_u64 //
1782wuffs_base__more_information__metadata__range(
1783 const wuffs_base__more_information* m) {
1784 wuffs_base__range_ie_u64 ret;
1785 ret.min_incl = m->y;
1786 ret.max_excl = m->z;
1787 return ret;
1788}
1789
1790#ifdef __cplusplus
1791
1792inline void //
1793wuffs_base__more_information::set(uint32_t flavor_arg,
1794 uint32_t w_arg,
1795 uint64_t x_arg,
1796 uint64_t y_arg,
1797 uint64_t z_arg) {
1798 wuffs_base__more_information__set(this, flavor_arg, w_arg, x_arg, y_arg,
1799 z_arg);
1800}
1801
1802inline uint32_t //
1803wuffs_base__more_information::io_redirect__fourcc() const {
1804 return wuffs_base__more_information__io_redirect__fourcc(this);
1805}
1806
1807inline wuffs_base__range_ie_u64 //
1808wuffs_base__more_information::io_redirect__range() const {
1809 return wuffs_base__more_information__io_redirect__range(this);
1810}
1811
1812inline uint64_t //
1813wuffs_base__more_information::io_seek__position() const {
1814 return wuffs_base__more_information__io_seek__position(this);
1815}
1816
1817inline uint32_t //
1818wuffs_base__more_information::metadata__fourcc() const {
1819 return wuffs_base__more_information__metadata__fourcc(this);
1820}
1821
1822inline wuffs_base__range_ie_u64 //
1823wuffs_base__more_information::metadata__range() const {
1824 return wuffs_base__more_information__metadata__range(this);
1825}
1826
1827#endif // __cplusplus
1828
1829// ---------------- I/O
1830//
1831// See (/doc/note/io-input-output.md).
1832
1833// wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's
1834// data.
1835typedef struct {
1836 size_t wi; // Write index. Invariant: wi <= len.
1837 size_t ri; // Read index. Invariant: ri <= wi.
1838 uint64_t pos; // Position of the buffer start relative to the stream start.
1839 bool closed; // No further writes are expected.
1840} wuffs_base__io_buffer_meta;
1841
1842// wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus
1843// additional metadata.
1844//
1845// A value with all fields zero is a valid, empty buffer.
1846typedef struct {
1847 wuffs_base__slice_u8 data;
1848 wuffs_base__io_buffer_meta meta;
1849
1850#ifdef __cplusplus
1851 inline bool is_valid() const;
1852 inline void compact();
1853 inline uint64_t reader_available() const;
1854 inline uint64_t reader_io_position() const;
1855 inline uint64_t writer_available() const;
1856 inline uint64_t writer_io_position() const;
1857#endif // __cplusplus
1858
1859} wuffs_base__io_buffer;
1860
1861static inline wuffs_base__io_buffer //
1862wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,
1863 wuffs_base__io_buffer_meta meta) {
1864 wuffs_base__io_buffer ret;
1865 ret.data = data;
1866 ret.meta = meta;
1867 return ret;
1868}
1869
1870static inline wuffs_base__io_buffer_meta //
1871wuffs_base__make_io_buffer_meta(size_t wi,
1872 size_t ri,
1873 uint64_t pos,
1874 bool closed) {
1875 wuffs_base__io_buffer_meta ret;
1876 ret.wi = wi;
1877 ret.ri = ri;
1878 ret.pos = pos;
1879 ret.closed = closed;
1880 return ret;
1881}
1882
1883static inline wuffs_base__io_buffer //
1884wuffs_base__ptr_u8__reader(uint8_t* ptr, size_t len, bool closed) {
1885 wuffs_base__io_buffer ret;
1886 ret.data.ptr = ptr;
1887 ret.data.len = len;
1888 ret.meta.wi = len;
1889 ret.meta.ri = 0;
1890 ret.meta.pos = 0;
1891 ret.meta.closed = closed;
1892 return ret;
1893}
1894
1895static inline wuffs_base__io_buffer //
1896wuffs_base__ptr_u8__writer(uint8_t* ptr, size_t len) {
1897 wuffs_base__io_buffer ret;
1898 ret.data.ptr = ptr;
1899 ret.data.len = len;
1900 ret.meta.wi = 0;
1901 ret.meta.ri = 0;
1902 ret.meta.pos = 0;
1903 ret.meta.closed = false;
1904 return ret;
1905}
1906
1907static inline wuffs_base__io_buffer //
1908wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s, bool closed) {
1909 wuffs_base__io_buffer ret;
1910 ret.data.ptr = s.ptr;
1911 ret.data.len = s.len;
1912 ret.meta.wi = s.len;
1913 ret.meta.ri = 0;
1914 ret.meta.pos = 0;
1915 ret.meta.closed = closed;
1916 return ret;
1917}
1918
1919static inline wuffs_base__io_buffer //
1920wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s) {
1921 wuffs_base__io_buffer ret;
1922 ret.data.ptr = s.ptr;
1923 ret.data.len = s.len;
1924 ret.meta.wi = 0;
1925 ret.meta.ri = 0;
1926 ret.meta.pos = 0;
1927 ret.meta.closed = false;
1928 return ret;
1929}
1930
1931static inline wuffs_base__io_buffer //
1932wuffs_base__empty_io_buffer() {
1933 wuffs_base__io_buffer ret;
1934 ret.data.ptr = NULL;
1935 ret.data.len = 0;
1936 ret.meta.wi = 0;
1937 ret.meta.ri = 0;
1938 ret.meta.pos = 0;
1939 ret.meta.closed = false;
1940 return ret;
1941}
1942
1943static inline wuffs_base__io_buffer_meta //
1944wuffs_base__empty_io_buffer_meta() {
1945 wuffs_base__io_buffer_meta ret;
1946 ret.wi = 0;
1947 ret.ri = 0;
1948 ret.pos = 0;
1949 ret.closed = false;
1950 return ret;
1951}
1952
1953static inline bool //
1954wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer* buf) {
1955 if (buf) {
1956 if (buf->data.ptr) {
1957 return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
1958 } else {
1959 return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
1960 }
1961 }
1962 return false;
1963}
1964
1965// wuffs_base__io_buffer__compact moves any written but unread bytes to the
1966// start of the buffer.
1967static inline void //
1968wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) {
1969 if (!buf || (buf->meta.ri == 0)) {
1970 return;
1971 }
1972 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
1973 size_t n = buf->meta.wi - buf->meta.ri;
1974 if (n != 0) {
1975 memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, n);
1976 }
1977 buf->meta.wi = n;
1978 buf->meta.ri = 0;
1979}
1980
1981static inline uint64_t //
1982wuffs_base__io_buffer__reader_available(const wuffs_base__io_buffer* buf) {
1983 return buf ? buf->meta.wi - buf->meta.ri : 0;
1984}
1985
1986static inline uint64_t //
1987wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer* buf) {
1988 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
1989}
1990
1991static inline uint64_t //
1992wuffs_base__io_buffer__writer_available(const wuffs_base__io_buffer* buf) {
1993 return buf ? buf->data.len - buf->meta.wi : 0;
1994}
1995
1996static inline uint64_t //
1997wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer* buf) {
1998 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
1999}
2000
2001#ifdef __cplusplus
2002
2003inline bool //
2004wuffs_base__io_buffer::is_valid() const {
2005 return wuffs_base__io_buffer__is_valid(this);
2006}
2007
2008inline void //
2009wuffs_base__io_buffer::compact() {
2010 wuffs_base__io_buffer__compact(this);
2011}
2012
2013inline uint64_t //
2014wuffs_base__io_buffer::reader_available() const {
2015 return wuffs_base__io_buffer__reader_available(this);
2016}
2017
2018inline uint64_t //
2019wuffs_base__io_buffer::reader_io_position() const {
2020 return wuffs_base__io_buffer__reader_io_position(this);
2021}
2022
2023inline uint64_t //
2024wuffs_base__io_buffer::writer_available() const {
2025 return wuffs_base__io_buffer__writer_available(this);
2026}
2027
2028inline uint64_t //
2029wuffs_base__io_buffer::writer_io_position() const {
2030 return wuffs_base__io_buffer__writer_io_position(this);
2031}
2032
2033#endif // __cplusplus
2034
2035// ---------------- Tokens
2036
2037// wuffs_base__token is an element of a byte stream's tokenization.
2038//
2039// See https://github.com/google/wuffs/blob/master/doc/note/tokens.md
2040typedef struct {
2041 uint64_t repr;
2042
2043#ifdef __cplusplus
2044 inline int64_t value() const;
2045 inline int64_t value_extension() const;
2046 inline int64_t value_major() const;
2047 inline int64_t value_base_category() const;
2048 inline uint64_t value_minor() const;
2049 inline uint64_t value_base_detail() const;
2050 inline bool continued() const;
2051 inline uint64_t length() const;
2052#endif // __cplusplus
2053
2054} wuffs_base__token;
2055
2056static inline wuffs_base__token //
2057wuffs_base__make_token(uint64_t repr) {
2058 wuffs_base__token ret;
2059 ret.repr = repr;
2060 return ret;
2061}
2062
2063// --------
2064
2065#define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF
2066
2067#define WUFFS_BASE__TOKEN__VALUE__SHIFT 17
2068#define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17
2069#define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42
2070#define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17
2071#define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38
2072#define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17
2073#define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16
2074#define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0
2075
2076// --------
2077
2078#define WUFFS_BASE__TOKEN__VBC__FILLER 0
2079#define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1
2080#define WUFFS_BASE__TOKEN__VBC__STRING 2
2081#define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3
2082#define WUFFS_BASE__TOKEN__VBC__LITERAL 4
2083#define WUFFS_BASE__TOKEN__VBC__NUMBER 5
2084
2085// --------
2086
2087#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00001
2088#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002
2089
2090// --------
2091
2092#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001
2093#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002
2094#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010
2095#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020
2096#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040
2097#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000
2098#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000
2099#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000
2100
2101// --------
2102
2103// "DEFINITELY_FOO" means that the destination bytes (and also the source
2104// bytes, for 1_DST_1_SRC_COPY) are in the FOO format. Definitely means that
2105// the lack of the bit is conservative: it is valid for all-ASCII strings to
2106// have neither DEFINITELY_UTF_8 or DEFINITELY_ASCII bits set.
2107#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001
2108#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00002
2109
2110// "CONVERT_D_DST_S_SRC" means that multiples of S source bytes (possibly
2111// padded) produces multiples of D destination bytes. For example,
2112// CONVERT_1_DST_4_SRC_BACKSLASH_X means a source like "\\x23\\x67\\xAB", where
2113// 12 src bytes encode 3 dst bytes.
2114//
2115// Post-processing may further transform those D destination bytes (e.g. treat
2116// "\\xFF" as the Unicode code point U+00FF instead of the byte 0xFF), but that
2117// is out of scope of this VBD's semantics.
2118//
2119// When src is the empty string, multiple conversion algorithms are applicable
2120// (so these bits are not necessarily mutually exclusive), all producing the
2121// same empty dst string.
2122#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00010
2123#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00020
2124#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00040
2125#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00080
2126#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x00100
2127#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x00200
2128#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x00400
2129
2130// --------
2131
2132#define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001
2133#define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002
2134#define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004
2135#define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008
2136
2137// --------
2138
2139// For a source string of "123" or "0x9A", it is valid for a tokenizer to
2140// return any one of:
2141// - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT.
2142// - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED.
2143// - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED.
2144//
2145// For a source string of "+123" or "-0x9A", only the first two are valid.
2146//
2147// For a source string of "123.", only the first one is valid.
2148#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001
2149#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002
2150#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004
2151
2152#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010
2153#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF 0x00020
2154#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN 0x00040
2155#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN 0x00080
2156
2157// The number 300 might be represented as "\x01\x2C", "\x2C\x01\x00\x00" or
2158// "300", which are big-endian, little-endian or text. For binary formats, the
2159// token length discriminates e.g. u16 little-endian vs u32 little-endian.
2160#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100
2161#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200
2162#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400
2163
2164// --------
2165
2166// wuffs_base__token__value returns the token's high 46 bits, sign-extended. A
2167// negative value means an extended token, non-negative means a simple token.
2168static inline int64_t //
2169wuffs_base__token__value(const wuffs_base__token* t) {
2170 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE__SHIFT;
2171}
2172
2173// wuffs_base__token__value_extension returns a negative value if the token was
2174// not an extended token.
2175static inline int64_t //
2176wuffs_base__token__value_extension(const wuffs_base__token* t) {
2177 return (~(int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT;
2178}
2179
2180// wuffs_base__token__value_major returns a negative value if the token was not
2181// a simple token.
2182static inline int64_t //
2183wuffs_base__token__value_major(const wuffs_base__token* t) {
2184 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT;
2185}
2186
2187// wuffs_base__token__value_base_category returns a negative value if the token
2188// was not a simple token.
2189static inline int64_t //
2190wuffs_base__token__value_base_category(const wuffs_base__token* t) {
2191 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT;
2192}
2193
2194static inline uint64_t //
2195wuffs_base__token__value_minor(const wuffs_base__token* t) {
2196 return (t->repr >> WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) & 0x1FFFFFF;
2197}
2198
2199static inline uint64_t //
2200wuffs_base__token__value_base_detail(const wuffs_base__token* t) {
2201 return (t->repr >> WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) & 0x1FFFFF;
2202}
2203
2204static inline bool //
2205wuffs_base__token__continued(const wuffs_base__token* t) {
2206 return t->repr & 0x10000;
2207}
2208
2209static inline uint64_t //
2210wuffs_base__token__length(const wuffs_base__token* t) {
2211 return (t->repr >> WUFFS_BASE__TOKEN__LENGTH__SHIFT) & 0xFFFF;
2212}
2213
2214#ifdef __cplusplus
2215
2216inline int64_t //
2217wuffs_base__token::value() const {
2218 return wuffs_base__token__value(this);
2219}
2220
2221inline int64_t //
2222wuffs_base__token::value_extension() const {
2223 return wuffs_base__token__value_extension(this);
2224}
2225
2226inline int64_t //
2227wuffs_base__token::value_major() const {
2228 return wuffs_base__token__value_major(this);
2229}
2230
2231inline int64_t //
2232wuffs_base__token::value_base_category() const {
2233 return wuffs_base__token__value_base_category(this);
2234}
2235
2236inline uint64_t //
2237wuffs_base__token::value_minor() const {
2238 return wuffs_base__token__value_minor(this);
2239}
2240
2241inline uint64_t //
2242wuffs_base__token::value_base_detail() const {
2243 return wuffs_base__token__value_base_detail(this);
2244}
2245
2246inline bool //
2247wuffs_base__token::continued() const {
2248 return wuffs_base__token__continued(this);
2249}
2250
2251inline uint64_t //
2252wuffs_base__token::length() const {
2253 return wuffs_base__token__length(this);
2254}
2255
2256#endif // __cplusplus
2257
2258// --------
2259
2260typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token;
2261
2262static inline wuffs_base__slice_token //
2263wuffs_base__make_slice_token(wuffs_base__token* ptr, size_t len) {
2264 wuffs_base__slice_token ret;
2265 ret.ptr = ptr;
2266 ret.len = len;
2267 return ret;
2268}
2269
2270// --------
2271
2272// wuffs_base__token_buffer_meta is the metadata for a
2273// wuffs_base__token_buffer's data.
2274typedef struct {
2275 size_t wi; // Write index. Invariant: wi <= len.
2276 size_t ri; // Read index. Invariant: ri <= wi.
2277 uint64_t pos; // Position of the buffer start relative to the stream start.
2278 bool closed; // No further writes are expected.
2279} wuffs_base__token_buffer_meta;
2280
2281// wuffs_base__token_buffer is a 1-dimensional buffer (a pointer and length)
2282// plus additional metadata.
2283//
2284// A value with all fields zero is a valid, empty buffer.
2285typedef struct {
2286 wuffs_base__slice_token data;
2287 wuffs_base__token_buffer_meta meta;
2288
2289#ifdef __cplusplus
2290 inline bool is_valid() const;
2291 inline void compact();
2292 inline uint64_t reader_available() const;
2293 inline uint64_t reader_token_position() const;
2294 inline uint64_t writer_available() const;
2295 inline uint64_t writer_token_position() const;
2296#endif // __cplusplus
2297
2298} wuffs_base__token_buffer;
2299
2300static inline wuffs_base__token_buffer //
2301wuffs_base__make_token_buffer(wuffs_base__slice_token data,
2302 wuffs_base__token_buffer_meta meta) {
2303 wuffs_base__token_buffer ret;
2304 ret.data = data;
2305 ret.meta = meta;
2306 return ret;
2307}
2308
2309static inline wuffs_base__token_buffer_meta //
2310wuffs_base__make_token_buffer_meta(size_t wi,
2311 size_t ri,
2312 uint64_t pos,
2313 bool closed) {
2314 wuffs_base__token_buffer_meta ret;
2315 ret.wi = wi;
2316 ret.ri = ri;
2317 ret.pos = pos;
2318 ret.closed = closed;
2319 return ret;
2320}
2321
2322static inline wuffs_base__token_buffer //
2323wuffs_base__slice_token__reader(wuffs_base__slice_token s, bool closed) {
2324 wuffs_base__token_buffer ret;
2325 ret.data.ptr = s.ptr;
2326 ret.data.len = s.len;
2327 ret.meta.wi = s.len;
2328 ret.meta.ri = 0;
2329 ret.meta.pos = 0;
2330 ret.meta.closed = closed;
2331 return ret;
2332}
2333
2334static inline wuffs_base__token_buffer //
2335wuffs_base__slice_token__writer(wuffs_base__slice_token s) {
2336 wuffs_base__token_buffer ret;
2337 ret.data.ptr = s.ptr;
2338 ret.data.len = s.len;
2339 ret.meta.wi = 0;
2340 ret.meta.ri = 0;
2341 ret.meta.pos = 0;
2342 ret.meta.closed = false;
2343 return ret;
2344}
2345
2346static inline wuffs_base__token_buffer //
2347wuffs_base__empty_token_buffer() {
2348 wuffs_base__token_buffer ret;
2349 ret.data.ptr = NULL;
2350 ret.data.len = 0;
2351 ret.meta.wi = 0;
2352 ret.meta.ri = 0;
2353 ret.meta.pos = 0;
2354 ret.meta.closed = false;
2355 return ret;
2356}
2357
2358static inline wuffs_base__token_buffer_meta //
2359wuffs_base__empty_token_buffer_meta() {
2360 wuffs_base__token_buffer_meta ret;
2361 ret.wi = 0;
2362 ret.ri = 0;
2363 ret.pos = 0;
2364 ret.closed = false;
2365 return ret;
2366}
2367
2368static inline bool //
2369wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer* buf) {
2370 if (buf) {
2371 if (buf->data.ptr) {
2372 return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
2373 } else {
2374 return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
2375 }
2376 }
2377 return false;
2378}
2379
2380// wuffs_base__token_buffer__compact moves any written but unread tokens to the
2381// start of the buffer.
2382static inline void //
2383wuffs_base__token_buffer__compact(wuffs_base__token_buffer* buf) {
2384 if (!buf || (buf->meta.ri == 0)) {
2385 return;
2386 }
2387 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
2388 size_t n = buf->meta.wi - buf->meta.ri;
2389 if (n != 0) {
2390 memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri,
2391 n * sizeof(wuffs_base__token));
2392 }
2393 buf->meta.wi = n;
2394 buf->meta.ri = 0;
2395}
2396
2397static inline uint64_t //
2398wuffs_base__token_buffer__reader_available(
2399 const wuffs_base__token_buffer* buf) {
2400 return buf ? buf->meta.wi - buf->meta.ri : 0;
2401}
2402
2403static inline uint64_t //
2404wuffs_base__token_buffer__reader_token_position(
2405 const wuffs_base__token_buffer* buf) {
2406 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
2407}
2408
2409static inline uint64_t //
2410wuffs_base__token_buffer__writer_available(
2411 const wuffs_base__token_buffer* buf) {
2412 return buf ? buf->data.len - buf->meta.wi : 0;
2413}
2414
2415static inline uint64_t //
2416wuffs_base__token_buffer__writer_token_position(
2417 const wuffs_base__token_buffer* buf) {
2418 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
2419}
2420
2421#ifdef __cplusplus
2422
2423inline bool //
2424wuffs_base__token_buffer::is_valid() const {
2425 return wuffs_base__token_buffer__is_valid(this);
2426}
2427
2428inline void //
2429wuffs_base__token_buffer::compact() {
2430 wuffs_base__token_buffer__compact(this);
2431}
2432
2433inline uint64_t //
2434wuffs_base__token_buffer::reader_available() const {
2435 return wuffs_base__token_buffer__reader_available(this);
2436}
2437
2438inline uint64_t //
2439wuffs_base__token_buffer::reader_token_position() const {
2440 return wuffs_base__token_buffer__reader_token_position(this);
2441}
2442
2443inline uint64_t //
2444wuffs_base__token_buffer::writer_available() const {
2445 return wuffs_base__token_buffer__writer_available(this);
2446}
2447
2448inline uint64_t //
2449wuffs_base__token_buffer::writer_token_position() const {
2450 return wuffs_base__token_buffer__writer_token_position(this);
2451}
2452
2453#endif // __cplusplus
2454
2455// ---------------- Memory Allocation
2456
2457// The memory allocation related functions in this section aren't used by Wuffs
2458// per se, but they may be helpful to the code that uses Wuffs.
2459
2460// wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except
2461// that it takes a uint64_t number of elements instead of a size_t size in
2462// bytes, and it returns a slice (a pointer and a length) instead of just a
2463// pointer.
2464//
2465// You can pass the C stdlib's malloc as the malloc_func.
2466//
2467// It returns an empty slice (containing a NULL ptr field) if (num_uxx *
2468// sizeof(uintxx_t)) would overflow SIZE_MAX.
2469
2470static inline wuffs_base__slice_u8 //
2471wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) {
2472 if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) {
2473 void* p = (*malloc_func)(num_u8 * sizeof(uint8_t));
2474 if (p) {
2475 return wuffs_base__make_slice_u8((uint8_t*)(p), num_u8);
2476 }
2477 }
2478 return wuffs_base__make_slice_u8(NULL, 0);
2479}
2480
2481static inline wuffs_base__slice_u16 //
2482wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) {
2483 if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) {
2484 void* p = (*malloc_func)(num_u16 * sizeof(uint16_t));
2485 if (p) {
2486 return wuffs_base__make_slice_u16((uint16_t*)(p), num_u16);
2487 }
2488 }
2489 return wuffs_base__make_slice_u16(NULL, 0);
2490}
2491
2492static inline wuffs_base__slice_u32 //
2493wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) {
2494 if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) {
2495 void* p = (*malloc_func)(num_u32 * sizeof(uint32_t));
2496 if (p) {
2497 return wuffs_base__make_slice_u32((uint32_t*)(p), num_u32);
2498 }
2499 }
2500 return wuffs_base__make_slice_u32(NULL, 0);
2501}
2502
2503static inline wuffs_base__slice_u64 //
2504wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) {
2505 if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) {
2506 void* p = (*malloc_func)(num_u64 * sizeof(uint64_t));
2507 if (p) {
2508 return wuffs_base__make_slice_u64((uint64_t*)(p), num_u64);
2509 }
2510 }
2511 return wuffs_base__make_slice_u64(NULL, 0);
2512}
2513
2514// ---------------- Images
2515
2516// wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
2517// Alpha, Red, Green, Blue color, as a uint32_t value. Its value is always
2518// 0xAARRGGBB (Alpha most significant, Blue least), regardless of endianness.
2519typedef uint32_t wuffs_base__color_u32_argb_premul;
2520
2521static inline uint16_t //
2522wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
2523 wuffs_base__color_u32_argb_premul c) {
2524 uint32_t r5 = 0xF800 & (c >> 8);
2525 uint32_t g6 = 0x07E0 & (c >> 5);
2526 uint32_t b5 = 0x001F & (c >> 3);
2527 return (uint16_t)(r5 | g6 | b5);
2528}
2529
2530static inline wuffs_base__color_u32_argb_premul //
2531wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565) {
2532 uint32_t b5 = 0x1F & (rgb_565 >> 0);
2533 uint32_t b = (b5 << 3) | (b5 >> 2);
2534 uint32_t g6 = 0x3F & (rgb_565 >> 5);
2535 uint32_t g = (g6 << 2) | (g6 >> 4);
2536 uint32_t r5 = 0x1F & (rgb_565 >> 11);
2537 uint32_t r = (r5 << 3) | (r5 >> 2);
2538 return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
2539}
2540
2541static inline uint8_t //
2542wuffs_base__color_u32_argb_premul__as__color_u8_gray(
2543 wuffs_base__color_u32_argb_premul c) {
2544 // Work in 16-bit color.
2545 uint32_t cr = 0x101 * (0xFF & (c >> 16));
2546 uint32_t cg = 0x101 * (0xFF & (c >> 8));
2547 uint32_t cb = 0x101 * (0xFF & (c >> 0));
2548
2549 // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
2550 // as those given by the JFIF specification.
2551 //
2552 // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16). We
2553 // shift by 24, not just by 16, because the return value is 8-bit color, not
2554 // 16-bit color.
2555 uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
2556 return (uint8_t)(weighted_average >> 24);
2557}
2558
2559// wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul converts
2560// from non-premultiplied alpha to premultiplied alpha.
2561static inline wuffs_base__color_u32_argb_premul //
2562wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
2563 uint32_t argb_nonpremul) {
2564 // Multiplying by 0x101 (twice, once for alpha and once for color) converts
2565 // from 8-bit to 16-bit color. Shifting right by 8 undoes that.
2566 //
2567 // Working in the higher bit depth can produce slightly different (and
2568 // arguably slightly more accurate) results. For example, given 8-bit blue
2569 // and alpha of 0x80 and 0x81:
2570 //
2571 // - ((0x80 * 0x81 ) / 0xFF ) = 0x40 = 0x40
2572 // - ((0x8080 * 0x8181) / 0xFFFF) >> 8 = 0x4101 >> 8 = 0x41
2573 uint32_t a = 0xFF & (argb_nonpremul >> 24);
2574 uint32_t a16 = a * (0x101 * 0x101);
2575
2576 uint32_t r = 0xFF & (argb_nonpremul >> 16);
2577 r = ((r * a16) / 0xFFFF) >> 8;
2578 uint32_t g = 0xFF & (argb_nonpremul >> 8);
2579 g = ((g * a16) / 0xFFFF) >> 8;
2580 uint32_t b = 0xFF & (argb_nonpremul >> 0);
2581 b = ((b * a16) / 0xFFFF) >> 8;
2582
2583 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
2584}
2585
2586// wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul converts
2587// from premultiplied alpha to non-premultiplied alpha.
2588static inline uint32_t //
2589wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
2590 wuffs_base__color_u32_argb_premul c) {
2591 uint32_t a = 0xFF & (c >> 24);
2592 if (a == 0xFF) {
2593 return c;
2594 } else if (a == 0) {
2595 return 0;
2596 }
2597 uint32_t a16 = a * 0x101;
2598
2599 uint32_t r = 0xFF & (c >> 16);
2600 r = ((r * (0x101 * 0xFFFF)) / a16) >> 8;
2601 uint32_t g = 0xFF & (c >> 8);
2602 g = ((g * (0x101 * 0xFFFF)) / a16) >> 8;
2603 uint32_t b = 0xFF & (c >> 0);
2604 b = ((b * (0x101 * 0xFFFF)) / a16) >> 8;
2605
2606 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
2607}
2608
2609// --------
2610
2611typedef uint8_t wuffs_base__pixel_blend;
2612
2613// wuffs_base__pixel_blend encodes how to blend source and destination pixels,
2614// accounting for transparency. It encompasses the Porter-Duff compositing
2615// operators as well as the other blending modes defined by PDF.
2616//
2617// TODO: implement the other modes.
2618#define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
2619#define WUFFS_BASE__PIXEL_BLEND__SRC_OVER ((wuffs_base__pixel_blend)1)
2620
2621// --------
2622
2623// wuffs_base__pixel_alpha_transparency is a pixel format's alpha channel
2624// model. It is a property of the pixel format in general, not of a specific
2625// pixel. An RGBA pixel format (with alpha) can still have fully opaque pixels.
2626typedef uint32_t wuffs_base__pixel_alpha_transparency;
2627
2628#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE 0
2629#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NON_PREMULTIPLIED_ALPHA 1
2630#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__PREMULTIPLIED_ALPHA 2
2631#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__BINARY_ALPHA 3
2632
2633// --------
2634
2635#define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
2636
2637#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
2638#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
2639
2640// wuffs_base__pixel_format encodes the format of the bytes that constitute an
2641// image frame's pixel data.
2642//
2643// See https://github.com/google/wuffs/blob/master/doc/note/pixel-formats.md
2644//
2645// Do not manipulate its bits directly; they are private implementation
2646// details. Use methods such as wuffs_base__pixel_format__num_planes instead.
2647typedef struct {
2648 uint32_t repr;
2649
2650#ifdef __cplusplus
2651 inline bool is_valid() const;
2652 inline uint32_t bits_per_pixel() const;
2653 inline bool is_direct() const;
2654 inline bool is_indexed() const;
2655 inline bool is_interleaved() const;
2656 inline bool is_planar() const;
2657 inline uint32_t num_planes() const;
2658 inline wuffs_base__pixel_alpha_transparency transparency() const;
2659#endif // __cplusplus
2660
2661} wuffs_base__pixel_format;
2662
2663static inline wuffs_base__pixel_format //
2664wuffs_base__make_pixel_format(uint32_t repr) {
2665 wuffs_base__pixel_format f;
2666 f.repr = repr;
2667 return f;
2668}
2669
2670// Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid
2671// wuffs_base__pixel_format values are present.
2672
2673#define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000
2674
2675#define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008
2676
2677#define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008
2678#define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000008
2679#define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000008
2680
2681#define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888
2682#define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888
2683#define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888
2684
2685#define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888
2686#define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888
2687#define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888
2688
2689#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008
2690#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008
2691#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008
2692
2693#define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565
2694#define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888
2695#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888
2696#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888
2697#define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888
2698#define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888
2699
2700#define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888
2701#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888
2702#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888
2703#define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888
2704#define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888
2705
2706#define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888
2707#define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888
2708
2709extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];
2710
2711static inline bool //
2712wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {
2713 return f->repr != 0;
2714}
2715
2716// wuffs_base__pixel_format__bits_per_pixel returns the number of bits per
2717// pixel for interleaved pixel formats, and returns 0 for planar pixel formats.
2718static inline uint32_t //
2719wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) {
2720 if (((f->repr >> 16) & 0x03) != 0) {
2721 return 0;
2722 }
2723 return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] +
2724 wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] +
2725 wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 8)] +
2726 wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 12)];
2727}
2728
2729static inline bool //
2730wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format* f) {
2731 return ((f->repr >> 18) & 0x01) == 0;
2732}
2733
2734static inline bool //
2735wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format* f) {
2736 return ((f->repr >> 18) & 0x01) != 0;
2737}
2738
2739static inline bool //
2740wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format* f) {
2741 return ((f->repr >> 16) & 0x03) == 0;
2742}
2743
2744static inline bool //
2745wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format* f) {
2746 return ((f->repr >> 16) & 0x03) != 0;
2747}
2748
2749static inline uint32_t //
2750wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format* f) {
2751 return ((f->repr >> 16) & 0x03) + 1;
2752}
2753
2754static inline wuffs_base__pixel_alpha_transparency //
2755wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format* f) {
2756 return (wuffs_base__pixel_alpha_transparency)((f->repr >> 24) & 0x03);
2757}
2758
2759#ifdef __cplusplus
2760
2761inline bool //
2762wuffs_base__pixel_format::is_valid() const {
2763 return wuffs_base__pixel_format__is_valid(this);
2764}
2765
2766inline uint32_t //
2767wuffs_base__pixel_format::bits_per_pixel() const {
2768 return wuffs_base__pixel_format__bits_per_pixel(this);
2769}
2770
2771inline bool //
2772wuffs_base__pixel_format::is_direct() const {
2773 return wuffs_base__pixel_format__is_direct(this);
2774}
2775
2776inline bool //
2777wuffs_base__pixel_format::is_indexed() const {
2778 return wuffs_base__pixel_format__is_indexed(this);
2779}
2780
2781inline bool //
2782wuffs_base__pixel_format::is_interleaved() const {
2783 return wuffs_base__pixel_format__is_interleaved(this);
2784}
2785
2786inline bool //
2787wuffs_base__pixel_format::is_planar() const {
2788 return wuffs_base__pixel_format__is_planar(this);
2789}
2790
2791inline uint32_t //
2792wuffs_base__pixel_format::num_planes() const {
2793 return wuffs_base__pixel_format__num_planes(this);
2794}
2795
2796inline wuffs_base__pixel_alpha_transparency //
2797wuffs_base__pixel_format::transparency() const {
2798 return wuffs_base__pixel_format__transparency(this);
2799}
2800
2801#endif // __cplusplus
2802
2803// --------
2804
2805// wuffs_base__pixel_subsampling encodes whether sample values cover one pixel
2806// or cover multiple pixels.
2807//
2808// See https://github.com/google/wuffs/blob/master/doc/note/pixel-subsampling.md
2809//
2810// Do not manipulate its bits directly; they are private implementation
2811// details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead.
2812typedef struct {
2813 uint32_t repr;
2814
2815#ifdef __cplusplus
2816 inline uint32_t bias_x(uint32_t plane) const;
2817 inline uint32_t denominator_x(uint32_t plane) const;
2818 inline uint32_t bias_y(uint32_t plane) const;
2819 inline uint32_t denominator_y(uint32_t plane) const;
2820#endif // __cplusplus
2821
2822} wuffs_base__pixel_subsampling;
2823
2824static inline wuffs_base__pixel_subsampling //
2825wuffs_base__make_pixel_subsampling(uint32_t repr) {
2826 wuffs_base__pixel_subsampling s;
2827 s.repr = repr;
2828 return s;
2829}
2830
2831#define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE 0x00000000
2832
2833#define WUFFS_BASE__PIXEL_SUBSAMPLING__444 0x000000
2834#define WUFFS_BASE__PIXEL_SUBSAMPLING__440 0x010100
2835#define WUFFS_BASE__PIXEL_SUBSAMPLING__422 0x101000
2836#define WUFFS_BASE__PIXEL_SUBSAMPLING__420 0x111100
2837#define WUFFS_BASE__PIXEL_SUBSAMPLING__411 0x303000
2838#define WUFFS_BASE__PIXEL_SUBSAMPLING__410 0x313100
2839
2840static inline uint32_t //
2841wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling* s,
2842 uint32_t plane) {
2843 uint32_t shift = ((plane & 0x03) * 8) + 6;
2844 return (s->repr >> shift) & 0x03;
2845}
2846
2847static inline uint32_t //
2848wuffs_base__pixel_subsampling__denominator_x(
2849 const wuffs_base__pixel_subsampling* s,
2850 uint32_t plane) {
2851 uint32_t shift = ((plane & 0x03) * 8) + 4;
2852 return ((s->repr >> shift) & 0x03) + 1;
2853}
2854
2855static inline uint32_t //
2856wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling* s,
2857 uint32_t plane) {
2858 uint32_t shift = ((plane & 0x03) * 8) + 2;
2859 return (s->repr >> shift) & 0x03;
2860}
2861
2862static inline uint32_t //
2863wuffs_base__pixel_subsampling__denominator_y(
2864 const wuffs_base__pixel_subsampling* s,
2865 uint32_t plane) {
2866 uint32_t shift = ((plane & 0x03) * 8) + 0;
2867 return ((s->repr >> shift) & 0x03) + 1;
2868}
2869
2870#ifdef __cplusplus
2871
2872inline uint32_t //
2873wuffs_base__pixel_subsampling::bias_x(uint32_t plane) const {
2874 return wuffs_base__pixel_subsampling__bias_x(this, plane);
2875}
2876
2877inline uint32_t //
2878wuffs_base__pixel_subsampling::denominator_x(uint32_t plane) const {
2879 return wuffs_base__pixel_subsampling__denominator_x(this, plane);
2880}
2881
2882inline uint32_t //
2883wuffs_base__pixel_subsampling::bias_y(uint32_t plane) const {
2884 return wuffs_base__pixel_subsampling__bias_y(this, plane);
2885}
2886
2887inline uint32_t //
2888wuffs_base__pixel_subsampling::denominator_y(uint32_t plane) const {
2889 return wuffs_base__pixel_subsampling__denominator_y(this, plane);
2890}
2891
2892#endif // __cplusplus
2893
2894// --------
2895
2896typedef struct {
2897 // Do not access the private_impl's fields directly. There is no API/ABI
2898 // compatibility or safety guarantee if you do so.
2899 struct {
2900 wuffs_base__pixel_format pixfmt;
2901 wuffs_base__pixel_subsampling pixsub;
2902 uint32_t width;
2903 uint32_t height;
2904 } private_impl;
2905
2906#ifdef __cplusplus
2907 inline void set(uint32_t pixfmt_repr,
2908 uint32_t pixsub_repr,
2909 uint32_t width,
2910 uint32_t height);
2911 inline void invalidate();
2912 inline bool is_valid() const;
2913 inline wuffs_base__pixel_format pixel_format() const;
2914 inline wuffs_base__pixel_subsampling pixel_subsampling() const;
2915 inline wuffs_base__rect_ie_u32 bounds() const;
2916 inline uint32_t width() const;
2917 inline uint32_t height() const;
2918 inline uint64_t pixbuf_len() const;
2919#endif // __cplusplus
2920
2921} wuffs_base__pixel_config;
2922
2923static inline wuffs_base__pixel_config //
2924wuffs_base__null_pixel_config() {
2925 wuffs_base__pixel_config ret;
2926 ret.private_impl.pixfmt.repr = 0;
2927 ret.private_impl.pixsub.repr = 0;
2928 ret.private_impl.width = 0;
2929 ret.private_impl.height = 0;
2930 return ret;
2931}
2932
2933// TODO: Should this function return bool? An error type?
2934static inline void //
2935wuffs_base__pixel_config__set(wuffs_base__pixel_config* c,
2936 uint32_t pixfmt_repr,
2937 uint32_t pixsub_repr,
2938 uint32_t width,
2939 uint32_t height) {
2940 if (!c) {
2941 return;
2942 }
2943 if (pixfmt_repr) {
2944 uint64_t wh = ((uint64_t)width) * ((uint64_t)height);
2945 // TODO: handle things other than 1 byte per pixel.
2946 if (wh <= ((uint64_t)SIZE_MAX)) {
2947 c->private_impl.pixfmt.repr = pixfmt_repr;
2948 c->private_impl.pixsub.repr = pixsub_repr;
2949 c->private_impl.width = width;
2950 c->private_impl.height = height;
2951 return;
2952 }
2953 }
2954
2955 c->private_impl.pixfmt.repr = 0;
2956 c->private_impl.pixsub.repr = 0;
2957 c->private_impl.width = 0;
2958 c->private_impl.height = 0;
2959}
2960
2961static inline void //
2962wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) {
2963 if (c) {
2964 c->private_impl.pixfmt.repr = 0;
2965 c->private_impl.pixsub.repr = 0;
2966 c->private_impl.width = 0;
2967 c->private_impl.height = 0;
2968 }
2969}
2970
2971static inline bool //
2972wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) {
2973 return c && c->private_impl.pixfmt.repr;
2974}
2975
2976static inline wuffs_base__pixel_format //
2977wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
2978 return c ? c->private_impl.pixfmt : wuffs_base__make_pixel_format(0);
2979}
2980
2981static inline wuffs_base__pixel_subsampling //
2982wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) {
2983 return c ? c->private_impl.pixsub : wuffs_base__make_pixel_subsampling(0);
2984}
2985
2986static inline wuffs_base__rect_ie_u32 //
2987wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) {
2988 if (c) {
2989 wuffs_base__rect_ie_u32 ret;
2990 ret.min_incl_x = 0;
2991 ret.min_incl_y = 0;
2992 ret.max_excl_x = c->private_impl.width;
2993 ret.max_excl_y = c->private_impl.height;
2994 return ret;
2995 }
2996
2997 wuffs_base__rect_ie_u32 ret;
2998 ret.min_incl_x = 0;
2999 ret.min_incl_y = 0;
3000 ret.max_excl_x = 0;
3001 ret.max_excl_y = 0;
3002 return ret;
3003}
3004
3005static inline uint32_t //
3006wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) {
3007 return c ? c->private_impl.width : 0;
3008}
3009
3010static inline uint32_t //
3011wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) {
3012 return c ? c->private_impl.height : 0;
3013}
3014
3015// TODO: this is the right API for planar (not interleaved) pixbufs? Should it
3016// allow decoding into a color model different from the format's intrinsic one?
3017// For example, decoding a JPEG image straight to RGBA instead of to YCbCr?
3018static inline uint64_t //
3019wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) {
3020 if (!c) {
3021 return 0;
3022 }
3023 if (wuffs_base__pixel_format__is_planar(&c->private_impl.pixfmt)) {
3024 // TODO: support planar pixel formats, concious of pixel subsampling.
3025 return 0;
3026 }
3027 uint32_t bits_per_pixel =
3028 wuffs_base__pixel_format__bits_per_pixel(&c->private_impl.pixfmt);
3029 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
3030 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
3031 return 0;
3032 }
3033 uint64_t bytes_per_pixel = bits_per_pixel / 8;
3034
3035 uint64_t n =
3036 ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height);
3037 if (n > (UINT64_MAX / bytes_per_pixel)) {
3038 return 0;
3039 }
3040 n *= bytes_per_pixel;
3041
3042 if (wuffs_base__pixel_format__is_indexed(&c->private_impl.pixfmt)) {
3043 if (n > (UINT64_MAX - 1024)) {
3044 return 0;
3045 }
3046 n += 1024;
3047 }
3048
3049 return n;
3050}
3051
3052#ifdef __cplusplus
3053
3054inline void //
3055wuffs_base__pixel_config::set(uint32_t pixfmt_repr,
3056 uint32_t pixsub_repr,
3057 uint32_t width,
3058 uint32_t height) {
3059 wuffs_base__pixel_config__set(this, pixfmt_repr, pixsub_repr, width, height);
3060}
3061
3062inline void //
3063wuffs_base__pixel_config::invalidate() {
3064 wuffs_base__pixel_config__invalidate(this);
3065}
3066
3067inline bool //
3068wuffs_base__pixel_config::is_valid() const {
3069 return wuffs_base__pixel_config__is_valid(this);
3070}
3071
3072inline wuffs_base__pixel_format //
3073wuffs_base__pixel_config::pixel_format() const {
3074 return wuffs_base__pixel_config__pixel_format(this);
3075}
3076
3077inline wuffs_base__pixel_subsampling //
3078wuffs_base__pixel_config::pixel_subsampling() const {
3079 return wuffs_base__pixel_config__pixel_subsampling(this);
3080}
3081
3082inline wuffs_base__rect_ie_u32 //
3083wuffs_base__pixel_config::bounds() const {
3084 return wuffs_base__pixel_config__bounds(this);
3085}
3086
3087inline uint32_t //
3088wuffs_base__pixel_config::width() const {
3089 return wuffs_base__pixel_config__width(this);
3090}
3091
3092inline uint32_t //
3093wuffs_base__pixel_config::height() const {
3094 return wuffs_base__pixel_config__height(this);
3095}
3096
3097inline uint64_t //
3098wuffs_base__pixel_config::pixbuf_len() const {
3099 return wuffs_base__pixel_config__pixbuf_len(this);
3100}
3101
3102#endif // __cplusplus
3103
3104// --------
3105
3106typedef struct {
3107 wuffs_base__pixel_config pixcfg;
3108
3109 // Do not access the private_impl's fields directly. There is no API/ABI
3110 // compatibility or safety guarantee if you do so.
3111 struct {
3112 uint64_t first_frame_io_position;
3113 bool first_frame_is_opaque;
3114 } private_impl;
3115
3116#ifdef __cplusplus
3117 inline void set(uint32_t pixfmt_repr,
3118 uint32_t pixsub_repr,
3119 uint32_t width,
3120 uint32_t height,
3121 uint64_t first_frame_io_position,
3122 bool first_frame_is_opaque);
3123 inline void invalidate();
3124 inline bool is_valid() const;
3125 inline uint64_t first_frame_io_position() const;
3126 inline bool first_frame_is_opaque() const;
3127#endif // __cplusplus
3128
3129} wuffs_base__image_config;
3130
3131static inline wuffs_base__image_config //
3132wuffs_base__null_image_config() {
3133 wuffs_base__image_config ret;
3134 ret.pixcfg = wuffs_base__null_pixel_config();
3135 ret.private_impl.first_frame_io_position = 0;
3136 ret.private_impl.first_frame_is_opaque = false;
3137 return ret;
3138}
3139
3140// TODO: Should this function return bool? An error type?
3141static inline void //
3142wuffs_base__image_config__set(wuffs_base__image_config* c,
3143 uint32_t pixfmt_repr,
3144 uint32_t pixsub_repr,
3145 uint32_t width,
3146 uint32_t height,
3147 uint64_t first_frame_io_position,
3148 bool first_frame_is_opaque) {
3149 if (!c) {
3150 return;
3151 }
3152 if (pixfmt_repr) {
3153 c->pixcfg.private_impl.pixfmt.repr = pixfmt_repr;
3154 c->pixcfg.private_impl.pixsub.repr = pixsub_repr;
3155 c->pixcfg.private_impl.width = width;
3156 c->pixcfg.private_impl.height = height;
3157 c->private_impl.first_frame_io_position = first_frame_io_position;
3158 c->private_impl.first_frame_is_opaque = first_frame_is_opaque;
3159 return;
3160 }
3161
3162 c->pixcfg.private_impl.pixfmt.repr = 0;
3163 c->pixcfg.private_impl.pixsub.repr = 0;
3164 c->pixcfg.private_impl.width = 0;
3165 c->pixcfg.private_impl.height = 0;
3166 c->private_impl.first_frame_io_position = 0;
3167 c->private_impl.first_frame_is_opaque = 0;
3168}
3169
3170static inline void //
3171wuffs_base__image_config__invalidate(wuffs_base__image_config* c) {
3172 if (c) {
3173 c->pixcfg.private_impl.pixfmt.repr = 0;
3174 c->pixcfg.private_impl.pixsub.repr = 0;
3175 c->pixcfg.private_impl.width = 0;
3176 c->pixcfg.private_impl.height = 0;
3177 c->private_impl.first_frame_io_position = 0;
3178 c->private_impl.first_frame_is_opaque = 0;
3179 }
3180}
3181
3182static inline bool //
3183wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {
3184 return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));
3185}
3186
3187static inline uint64_t //
3188wuffs_base__image_config__first_frame_io_position(
3189 const wuffs_base__image_config* c) {
3190 return c ? c->private_impl.first_frame_io_position : 0;
3191}
3192
3193static inline bool //
3194wuffs_base__image_config__first_frame_is_opaque(
3195 const wuffs_base__image_config* c) {
3196 return c ? c->private_impl.first_frame_is_opaque : false;
3197}
3198
3199#ifdef __cplusplus
3200
3201inline void //
3202wuffs_base__image_config::set(uint32_t pixfmt_repr,
3203 uint32_t pixsub_repr,
3204 uint32_t width,
3205 uint32_t height,
3206 uint64_t first_frame_io_position,
3207 bool first_frame_is_opaque) {
3208 wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, width, height,
3209 first_frame_io_position, first_frame_is_opaque);
3210}
3211
3212inline void //
3213wuffs_base__image_config::invalidate() {
3214 wuffs_base__image_config__invalidate(this);
3215}
3216
3217inline bool //
3218wuffs_base__image_config::is_valid() const {
3219 return wuffs_base__image_config__is_valid(this);
3220}
3221
3222inline uint64_t //
3223wuffs_base__image_config::first_frame_io_position() const {
3224 return wuffs_base__image_config__first_frame_io_position(this);
3225}
3226
3227inline bool //
3228wuffs_base__image_config::first_frame_is_opaque() const {
3229 return wuffs_base__image_config__first_frame_is_opaque(this);
3230}
3231
3232#endif // __cplusplus
3233
3234// --------
3235
3236// Deprecated: use wuffs_base__pixel_blend instead.
3237//
3238// wuffs_base__animation_blend encodes, for an animated image, how to blend the
3239// transparent pixels of this frame with the existing canvas. In Porter-Duff
3240// compositing operator terminology:
3241// - 0 means the frame may be transparent, and should be blended "src over
3242// dst", also known as just "over".
3243// - 1 means the frame may be transparent, and should be blended "src".
3244// - 2 means the frame is completely opaque, so that "src over dst" and "src"
3245// are equivalent.
3246//
3247// These semantics are conservative. It is valid for a completely opaque frame
3248// to have a blend value other than 2.
3249typedef uint8_t wuffs_base__animation_blend;
3250
3251#define WUFFS_BASE__ANIMATION_BLEND__SRC_OVER_DST \
3252 ((wuffs_base__animation_blend)0)
3253#define WUFFS_BASE__ANIMATION_BLEND__SRC ((wuffs_base__animation_blend)1)
3254#define WUFFS_BASE__ANIMATION_BLEND__OPAQUE ((wuffs_base__animation_blend)2)
3255
3256// --------
3257
3258// wuffs_base__animation_disposal encodes, for an animated image, how to
3259// dispose of a frame after displaying it:
3260// - None means to draw the next frame on top of this one.
3261// - Restore Background means to clear the frame's dirty rectangle to "the
3262// background color" (in practice, this means transparent black) before
3263// drawing the next frame.
3264// - Restore Previous means to undo the current frame, so that the next frame
3265// is drawn on top of the previous one.
3266typedef uint8_t wuffs_base__animation_disposal;
3267
3268#define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)
3269#define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \
3270 ((wuffs_base__animation_disposal)1)
3271#define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \
3272 ((wuffs_base__animation_disposal)2)
3273
3274// --------
3275
3276typedef struct {
3277 // Do not access the private_impl's fields directly. There is no API/ABI
3278 // compatibility or safety guarantee if you do so.
3279 struct {
3280 wuffs_base__rect_ie_u32 bounds;
3281 wuffs_base__flicks duration;
3282 uint64_t index;
3283 uint64_t io_position;
3284 wuffs_base__animation_disposal disposal;
3285 bool opaque_within_bounds;
3286 bool overwrite_instead_of_blend;
3287 wuffs_base__color_u32_argb_premul background_color;
3288 } private_impl;
3289
3290#ifdef __cplusplus
3291 inline void set(wuffs_base__rect_ie_u32 bounds,
3292 wuffs_base__flicks duration,
3293 uint64_t index,
3294 uint64_t io_position,
3295 wuffs_base__animation_disposal disposal,
3296 bool opaque_within_bounds,
3297 bool overwrite_instead_of_blend,
3298 wuffs_base__color_u32_argb_premul background_color);
3299 inline wuffs_base__rect_ie_u32 bounds() const;
3300 inline uint32_t width() const;
3301 inline uint32_t height() const;
3302 inline wuffs_base__flicks duration() const;
3303 inline uint64_t index() const;
3304 inline uint64_t io_position() const;
3305 inline wuffs_base__animation_disposal disposal() const;
3306 inline bool opaque_within_bounds() const;
3307 inline bool overwrite_instead_of_blend() const;
3308 inline wuffs_base__color_u32_argb_premul background_color() const;
3309#endif // __cplusplus
3310
3311} wuffs_base__frame_config;
3312
3313static inline wuffs_base__frame_config //
3314wuffs_base__null_frame_config() {
3315 wuffs_base__frame_config ret;
3316 ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);
3317 ret.private_impl.duration = 0;
3318 ret.private_impl.index = 0;
3319 ret.private_impl.io_position = 0;
3320 ret.private_impl.disposal = 0;
3321 ret.private_impl.opaque_within_bounds = false;
3322 ret.private_impl.overwrite_instead_of_blend = false;
3323 return ret;
3324}
3325
3326static inline void //
3327wuffs_base__frame_config__set(
3328 wuffs_base__frame_config* c,
3329 wuffs_base__rect_ie_u32 bounds,
3330 wuffs_base__flicks duration,
3331 uint64_t index,
3332 uint64_t io_position,
3333 wuffs_base__animation_disposal disposal,
3334 bool opaque_within_bounds,
3335 bool overwrite_instead_of_blend,
3336 wuffs_base__color_u32_argb_premul background_color) {
3337 if (!c) {
3338 return;
3339 }
3340
3341 c->private_impl.bounds = bounds;
3342 c->private_impl.duration = duration;
3343 c->private_impl.index = index;
3344 c->private_impl.io_position = io_position;
3345 c->private_impl.disposal = disposal;
3346 c->private_impl.opaque_within_bounds = opaque_within_bounds;
3347 c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
3348 c->private_impl.background_color = background_color;
3349}
3350
3351static inline wuffs_base__rect_ie_u32 //
3352wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {
3353 if (c) {
3354 return c->private_impl.bounds;
3355 }
3356
3357 wuffs_base__rect_ie_u32 ret;
3358 ret.min_incl_x = 0;
3359 ret.min_incl_y = 0;
3360 ret.max_excl_x = 0;
3361 ret.max_excl_y = 0;
3362 return ret;
3363}
3364
3365static inline uint32_t //
3366wuffs_base__frame_config__width(const wuffs_base__frame_config* c) {
3367 return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;
3368}
3369
3370static inline uint32_t //
3371wuffs_base__frame_config__height(const wuffs_base__frame_config* c) {
3372 return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;
3373}
3374
3375// wuffs_base__frame_config__duration returns the amount of time to display
3376// this frame. Zero means to display forever - a still (non-animated) image.
3377static inline wuffs_base__flicks //
3378wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {
3379 return c ? c->private_impl.duration : 0;
3380}
3381
3382// wuffs_base__frame_config__index returns the index of this frame. The first
3383// frame in an image has index 0, the second frame has index 1, and so on.
3384static inline uint64_t //
3385wuffs_base__frame_config__index(const wuffs_base__frame_config* c) {
3386 return c ? c->private_impl.index : 0;
3387}
3388
3389// wuffs_base__frame_config__io_position returns the I/O stream position before
3390// the frame config.
3391static inline uint64_t //
3392wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {
3393 return c ? c->private_impl.io_position : 0;
3394}
3395
3396// wuffs_base__frame_config__disposal returns, for an animated image, how to
3397// dispose of this frame after displaying it.
3398static inline wuffs_base__animation_disposal //
3399wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {
3400 return c ? c->private_impl.disposal : 0;
3401}
3402
3403// wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
3404// within the frame's bounds are fully opaque. It makes no claim about pixels
3405// outside the frame bounds but still inside the overall image. The two
3406// bounding rectangles can differ for animated images.
3407//
3408// Its semantics are conservative. It is valid for a fully opaque frame to have
3409// this value be false: a false negative.
3410//
3411// If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
3412// WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
3413// resultant pixels, but the former may be faster.
3414static inline bool //
3415wuffs_base__frame_config__opaque_within_bounds(
3416 const wuffs_base__frame_config* c) {
3417 return c && c->private_impl.opaque_within_bounds;
3418}
3419
3420// wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
3421// animated image, whether to ignore the previous image state (within the frame
3422// bounds) when drawing this incremental frame. Equivalently, whether to use
3423// WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
3424//
3425// The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
3426// calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
3427// Wuffs' "overwrite_instead_of_blend".
3428static inline bool //
3429wuffs_base__frame_config__overwrite_instead_of_blend(
3430 const wuffs_base__frame_config* c) {
3431 return c && c->private_impl.overwrite_instead_of_blend;
3432}
3433
3434static inline wuffs_base__color_u32_argb_premul //
3435wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
3436 return c ? c->private_impl.background_color : 0;
3437}
3438
3439#ifdef __cplusplus
3440
3441inline void //
3442wuffs_base__frame_config::set(
3443 wuffs_base__rect_ie_u32 bounds,
3444 wuffs_base__flicks duration,
3445 uint64_t index,
3446 uint64_t io_position,
3447 wuffs_base__animation_disposal disposal,
3448 bool opaque_within_bounds,
3449 bool overwrite_instead_of_blend,
3450 wuffs_base__color_u32_argb_premul background_color) {
3451 wuffs_base__frame_config__set(this, bounds, duration, index, io_position,
3452 disposal, opaque_within_bounds,
3453 overwrite_instead_of_blend, background_color);
3454}
3455
3456inline wuffs_base__rect_ie_u32 //
3457wuffs_base__frame_config::bounds() const {
3458 return wuffs_base__frame_config__bounds(this);
3459}
3460
3461inline uint32_t //
3462wuffs_base__frame_config::width() const {
3463 return wuffs_base__frame_config__width(this);
3464}
3465
3466inline uint32_t //
3467wuffs_base__frame_config::height() const {
3468 return wuffs_base__frame_config__height(this);
3469}
3470
3471inline wuffs_base__flicks //
3472wuffs_base__frame_config::duration() const {
3473 return wuffs_base__frame_config__duration(this);
3474}
3475
3476inline uint64_t //
3477wuffs_base__frame_config::index() const {
3478 return wuffs_base__frame_config__index(this);
3479}
3480
3481inline uint64_t //
3482wuffs_base__frame_config::io_position() const {
3483 return wuffs_base__frame_config__io_position(this);
3484}
3485
3486inline wuffs_base__animation_disposal //
3487wuffs_base__frame_config::disposal() const {
3488 return wuffs_base__frame_config__disposal(this);
3489}
3490
3491inline bool //
3492wuffs_base__frame_config::opaque_within_bounds() const {
3493 return wuffs_base__frame_config__opaque_within_bounds(this);
3494}
3495
3496inline bool //
3497wuffs_base__frame_config::overwrite_instead_of_blend() const {
3498 return wuffs_base__frame_config__overwrite_instead_of_blend(this);
3499}
3500
3501inline wuffs_base__color_u32_argb_premul //
3502wuffs_base__frame_config::background_color() const {
3503 return wuffs_base__frame_config__background_color(this);
3504}
3505
3506#endif // __cplusplus
3507
3508// --------
3509
3510typedef struct {
3511 wuffs_base__pixel_config pixcfg;
3512
3513 // Do not access the private_impl's fields directly. There is no API/ABI
3514 // compatibility or safety guarantee if you do so.
3515 struct {
3516 wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX];
3517 // TODO: color spaces.
3518 } private_impl;
3519
3520#ifdef __cplusplus
3521 inline wuffs_base__status set_from_slice(
3522 const wuffs_base__pixel_config* pixcfg,
3523 wuffs_base__slice_u8 pixbuf_memory);
3524 inline wuffs_base__status set_from_table(
3525 const wuffs_base__pixel_config* pixcfg,
3526 wuffs_base__table_u8 pixbuf_memory);
3527 inline wuffs_base__slice_u8 palette();
3528 inline wuffs_base__pixel_format pixel_format() const;
3529 inline wuffs_base__table_u8 plane(uint32_t p);
3530 inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,
3531 uint32_t y) const;
3532 inline wuffs_base__status set_color_u32_at(
3533 uint32_t x,
3534 uint32_t y,
3535 wuffs_base__color_u32_argb_premul color);
3536#endif // __cplusplus
3537
3538} wuffs_base__pixel_buffer;
3539
3540static inline wuffs_base__pixel_buffer //
3541wuffs_base__null_pixel_buffer() {
3542 wuffs_base__pixel_buffer ret;
3543 ret.pixcfg = wuffs_base__null_pixel_config();
3544 ret.private_impl.planes[0] = wuffs_base__empty_table_u8();
3545 ret.private_impl.planes[1] = wuffs_base__empty_table_u8();
3546 ret.private_impl.planes[2] = wuffs_base__empty_table_u8();
3547 ret.private_impl.planes[3] = wuffs_base__empty_table_u8();
3548 return ret;
3549}
3550
3551static inline wuffs_base__status //
3552wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
3553 const wuffs_base__pixel_config* pixcfg,
3554 wuffs_base__slice_u8 pixbuf_memory) {
3555 if (!pb) {
3556 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
3557 }
3558 memset(pb, 0, sizeof(*pb));
3559 if (!pixcfg) {
3560 return wuffs_base__make_status(wuffs_base__error__bad_argument);
3561 }
3562 if (wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
3563 // TODO: support planar pixel formats, concious of pixel subsampling.
3564 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
3565 }
3566 uint32_t bits_per_pixel =
3567 wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
3568 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
3569 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
3570 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
3571 }
3572 uint64_t bytes_per_pixel = bits_per_pixel / 8;
3573
3574 uint8_t* ptr = pixbuf_memory.ptr;
3575 uint64_t len = pixbuf_memory.len;
3576 if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
3577 // Split a 1024 byte chunk (256 palette entries × 4 bytes per entry) from
3578 // the start of pixbuf_memory. We split from the start, not the end, so
3579 // that the both chunks' pointers have the same alignment as the original
3580 // pointer, up to an alignment of 1024.
3581 if (len < 1024) {
3582 return wuffs_base__make_status(
3583 wuffs_base__error__bad_argument_length_too_short);
3584 }
3585 wuffs_base__table_u8* tab =
3586 &pb->private_impl
3587 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
3588 tab->ptr = ptr;
3589 tab->width = 1024;
3590 tab->height = 1;
3591 tab->stride = 1024;
3592 ptr += 1024;
3593 len -= 1024;
3594 }
3595
3596 uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *
3597 ((uint64_t)pixcfg->private_impl.height);
3598 size_t width = (size_t)(pixcfg->private_impl.width);
3599 if ((wh > (UINT64_MAX / bytes_per_pixel)) ||
3600 (width > (SIZE_MAX / bytes_per_pixel))) {
3601 return wuffs_base__make_status(wuffs_base__error__bad_argument);
3602 }
3603 wh *= bytes_per_pixel;
3604 width *= bytes_per_pixel;
3605 if (wh > len) {
3606 return wuffs_base__make_status(
3607 wuffs_base__error__bad_argument_length_too_short);
3608 }
3609
3610 pb->pixcfg = *pixcfg;
3611 wuffs_base__table_u8* tab = &pb->private_impl.planes[0];
3612 tab->ptr = ptr;
3613 tab->width = width;
3614 tab->height = pixcfg->private_impl.height;
3615 tab->stride = width;
3616 return wuffs_base__make_status(NULL);
3617}
3618
3619static inline wuffs_base__status //
3620wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,
3621 const wuffs_base__pixel_config* pixcfg,
3622 wuffs_base__table_u8 pixbuf_memory) {
3623 if (!pb) {
3624 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
3625 }
3626 memset(pb, 0, sizeof(*pb));
3627 if (!pixcfg ||
3628 wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
3629 return wuffs_base__make_status(wuffs_base__error__bad_argument);
3630 }
3631 uint32_t bits_per_pixel =
3632 wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
3633 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
3634 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
3635 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
3636 }
3637 uint64_t bytes_per_pixel = bits_per_pixel / 8;
3638
3639 uint64_t width_in_bytes =
3640 ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
3641 if ((width_in_bytes > pixbuf_memory.width) ||
3642 (pixcfg->private_impl.height > pixbuf_memory.height)) {
3643 return wuffs_base__make_status(wuffs_base__error__bad_argument);
3644 }
3645
3646 pb->pixcfg = *pixcfg;
3647 pb->private_impl.planes[0] = pixbuf_memory;
3648 return wuffs_base__make_status(NULL);
3649}
3650
3651// wuffs_base__pixel_buffer__palette returns the palette color data. If
3652// non-empty, it will have length 1024.
3653static inline wuffs_base__slice_u8 //
3654wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {
3655 if (pb &&
3656 wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
3657 wuffs_base__table_u8* tab =
3658 &pb->private_impl
3659 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
3660 if ((tab->width == 1024) && (tab->height == 1)) {
3661 return wuffs_base__make_slice_u8(tab->ptr, 1024);
3662 }
3663 }
3664 return wuffs_base__make_slice_u8(NULL, 0);
3665}
3666
3667static inline wuffs_base__pixel_format //
3668wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {
3669 if (pb) {
3670 return pb->pixcfg.private_impl.pixfmt;
3671 }
3672 return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);
3673}
3674
3675static inline wuffs_base__table_u8 //
3676wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {
3677 if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) {
3678 return pb->private_impl.planes[p];
3679 }
3680
3681 wuffs_base__table_u8 ret;
3682 ret.ptr = NULL;
3683 ret.width = 0;
3684 ret.height = 0;
3685 ret.stride = 0;
3686 return ret;
3687}
3688
3689WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
3690wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
3691 uint32_t x,
3692 uint32_t y);
3693
3694WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
3695wuffs_base__pixel_buffer__set_color_u32_at(
3696 wuffs_base__pixel_buffer* pb,
3697 uint32_t x,
3698 uint32_t y,
3699 wuffs_base__color_u32_argb_premul color);
3700
3701#ifdef __cplusplus
3702
3703inline wuffs_base__status //
3704wuffs_base__pixel_buffer::set_from_slice(
3705 const wuffs_base__pixel_config* pixcfg_arg,
3706 wuffs_base__slice_u8 pixbuf_memory) {
3707 return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,
3708 pixbuf_memory);
3709}
3710
3711inline wuffs_base__status //
3712wuffs_base__pixel_buffer::set_from_table(
3713 const wuffs_base__pixel_config* pixcfg_arg,
3714 wuffs_base__table_u8 pixbuf_memory) {
3715 return wuffs_base__pixel_buffer__set_from_table(this, pixcfg_arg,
3716 pixbuf_memory);
3717}
3718
3719inline wuffs_base__slice_u8 //
3720wuffs_base__pixel_buffer::palette() {
3721 return wuffs_base__pixel_buffer__palette(this);
3722}
3723
3724inline wuffs_base__pixel_format //
3725wuffs_base__pixel_buffer::pixel_format() const {
3726 return wuffs_base__pixel_buffer__pixel_format(this);
3727}
3728
3729inline wuffs_base__table_u8 //
3730wuffs_base__pixel_buffer::plane(uint32_t p) {
3731 return wuffs_base__pixel_buffer__plane(this, p);
3732}
3733
3734inline wuffs_base__color_u32_argb_premul //
3735wuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {
3736 return wuffs_base__pixel_buffer__color_u32_at(this, x, y);
3737}
3738
3739inline wuffs_base__status //
3740wuffs_base__pixel_buffer::set_color_u32_at(
3741 uint32_t x,
3742 uint32_t y,
3743 wuffs_base__color_u32_argb_premul color) {
3744 return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);
3745}
3746
3747#endif // __cplusplus
3748
3749// --------
3750
3751typedef struct {
3752 // Do not access the private_impl's fields directly. There is no API/ABI
3753 // compatibility or safety guarantee if you do so.
3754 struct {
3755 uint8_t TODO;
3756 } private_impl;
3757
3758#ifdef __cplusplus
3759#endif // __cplusplus
3760
3761} wuffs_base__decode_frame_options;
3762
3763#ifdef __cplusplus
3764
3765#endif // __cplusplus
3766
3767// --------
3768
3769// wuffs_base__pixel_palette__closest_element returns the index of the palette
3770// element that minimizes the sum of squared differences of the four ARGB
3771// channels, working in premultiplied alpha. Ties favor the smaller index.
3772//
3773// The palette_slice.len may equal (N*4), for N less than 256, which means that
3774// only the first N palette elements are considered. It returns 0 when N is 0.
3775//
3776// Applying this function on a per-pixel basis will not produce whole-of-image
3777// dithering.
3778WUFFS_BASE__MAYBE_STATIC uint8_t //
3779wuffs_base__pixel_palette__closest_element(
3780 wuffs_base__slice_u8 palette_slice,
3781 wuffs_base__pixel_format palette_format,
3782 wuffs_base__color_u32_argb_premul c);
3783
3784// --------
3785
3786// TODO: should the func type take restrict pointers?
3787typedef uint64_t (*wuffs_base__pixel_swizzler__func)(uint8_t* dst_ptr,
3788 size_t dst_len,
3789 uint8_t* dst_palette_ptr,
3790 size_t dst_palette_len,
3791 const uint8_t* src_ptr,
3792 size_t src_len);
3793
3794typedef struct {
3795 // Do not access the private_impl's fields directly. There is no API/ABI
3796 // compatibility or safety guarantee if you do so.
3797 struct {
3798 wuffs_base__pixel_swizzler__func func;
3799 uint32_t src_pixfmt_bytes_per_pixel;
3800 } private_impl;
3801
3802#ifdef __cplusplus
3803 inline wuffs_base__status prepare(wuffs_base__pixel_format dst_pixfmt,
3804 wuffs_base__slice_u8 dst_palette,
3805 wuffs_base__pixel_format src_pixfmt,
3806 wuffs_base__slice_u8 src_palette,
3807 wuffs_base__pixel_blend blend);
3808 inline uint64_t swizzle_interleaved_from_slice(
3809 wuffs_base__slice_u8 dst,
3810 wuffs_base__slice_u8 dst_palette,
3811 wuffs_base__slice_u8 src) const;
3812#endif // __cplusplus
3813
3814} wuffs_base__pixel_swizzler;
3815
3816// wuffs_base__pixel_swizzler__prepare readies the pixel swizzler so that its
3817// other methods may be called.
3818//
3819// For modular builds that divide the base module into sub-modules, using this
3820// function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
3821// just WUFFS_CONFIG__MODULE__BASE__CORE.
3822WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
3823wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
3824 wuffs_base__pixel_format dst_pixfmt,
3825 wuffs_base__slice_u8 dst_palette,
3826 wuffs_base__pixel_format src_pixfmt,
3827 wuffs_base__slice_u8 src_palette,
3828 wuffs_base__pixel_blend blend);
3829
3830// wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice converts pixels
3831// from a source format to a destination format.
3832//
3833// For modular builds that divide the base module into sub-modules, using this
3834// function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
3835// just WUFFS_CONFIG__MODULE__BASE__CORE.
3836WUFFS_BASE__MAYBE_STATIC uint64_t //
3837wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
3838 const wuffs_base__pixel_swizzler* p,
3839 wuffs_base__slice_u8 dst,
3840 wuffs_base__slice_u8 dst_palette,
3841 wuffs_base__slice_u8 src);
3842
3843#ifdef __cplusplus
3844
3845inline wuffs_base__status //
3846wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_pixfmt,
3847 wuffs_base__slice_u8 dst_palette,
3848 wuffs_base__pixel_format src_pixfmt,
3849 wuffs_base__slice_u8 src_palette,
3850 wuffs_base__pixel_blend blend) {
3851 return wuffs_base__pixel_swizzler__prepare(this, dst_pixfmt, dst_palette,
3852 src_pixfmt, src_palette, blend);
3853}
3854
3855uint64_t //
3856wuffs_base__pixel_swizzler::swizzle_interleaved_from_slice(
3857 wuffs_base__slice_u8 dst,
3858 wuffs_base__slice_u8 dst_palette,
3859 wuffs_base__slice_u8 src) const {
3860 return wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
3861 this, dst, dst_palette, src);
3862}
3863
3864#endif // __cplusplus
3865
3866// ---------------- String Conversions
3867
3868// wuffs_base__parse_number_i64 parses the ASCII integer in s. For example, if
3869// s contains the bytes "-123" then it will return the int64_t -123.
3870//
3871// It returns an error if s does not contain an integer or if the integer
3872// within would overflow an int64_t.
3873//
3874// It is similar to wuffs_base__parse_number_u64 but it returns a signed
3875// integer, not an unsigned integer. It also allows a leading '+' or '-'.
3876WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
3877wuffs_base__parse_number_i64(wuffs_base__slice_u8 s);
3878
3879// wuffs_base__parse_number_u64 parses the ASCII integer in s. For example, if
3880// s contains the bytes "123" then it will return the uint64_t 123.
3881//
3882// It returns an error if s does not contain an integer or if the integer
3883// within would overflow a uint64_t.
3884//
3885// It is similar to the C standard library's strtoull function, but:
3886// - Errors are returned in-band (in a result type), not out-of-band (errno).
3887// - It takes a slice (a pointer and length), not a NUL-terminated C string.
3888// - It does not take an optional endptr argument. It does not allow a partial
3889// parse: it returns an error unless all of s is consumed.
3890// - It does not allow whitespace, leading or otherwise.
3891// - It does not allow a leading '+' or '-'.
3892// - It does not allow unnecessary leading zeroes ("0" is valid and its sole
3893// zero is necessary). All of "00", "0644" and "007" are invalid.
3894// - It does not take a base argument (e.g. base 10 vs base 16). Instead, it
3895// always accepts both decimal (e.g "1234", "0d5678") and hexadecimal (e.g.
3896// "0x9aBC"). The caller is responsible for prior filtering of e.g. hex
3897// numbers if they are unwanted. For example, Wuffs' JSON decoder will only
3898// produce a wuffs_base__token for decimal numbers, not hexadecimal.
3899// - It is not affected by i18n / l10n settings such as environment variables.
3900// - It does allow arbitrary underscores, except inside the optional 2-byte
3901// opening "0d" or "0X" that denotes base-10 or base-16. For example,
3902// "__0D_1_002" would successfully parse as "one thousand and two".
3903WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
3904wuffs_base__parse_number_u64(wuffs_base__slice_u8 s);
3905
3906// ---------------- IEEE 754 Floating Point
3907
3908// wuffs_base__parse_number_f64 parses the floating point number in s. For
3909// example, if s contains the bytes "1.5" then it will return the double 1.5.
3910//
3911// It returns an error if s does not contain a floating point number.
3912//
3913// It does not necessarily return an error if the conversion is lossy, e.g. if
3914// s is "0.3", which double-precision floating point cannot represent exactly.
3915//
3916// Similarly, the returned value may be infinite (and no error returned) even
3917// if s was not "inf", when the input is nominally finite but sufficiently
3918// larger than DBL_MAX, about 1.8e+308.
3919//
3920// It is similar to the C standard library's strtod function, but:
3921// - Errors are returned in-band (in a result type), not out-of-band (errno).
3922// - It takes a slice (a pointer and length), not a NUL-terminated C string.
3923// - It does not take an optional endptr argument. It does not allow a partial
3924// parse: it returns an error unless all of s is consumed.
3925// - It does not allow whitespace, leading or otherwise.
3926// - It does not allow unnecessary leading zeroes ("0" is valid and its sole
3927// zero is necessary). All of "00", "0644" and "00.7" are invalid.
3928// - It is not affected by i18n / l10n settings such as environment variables.
3929// - Conversely, it always accepts either ',' or '.' as a decimal separator.
3930// In particular, "3,141,592" is always invalid but "3,141" is always valid
3931// (and approximately π). The caller is responsible for e.g. previously
3932// rejecting or filtering s if it contains a comma, if that is unacceptable
3933// to the caller. For example, JSON numbers always use a dot '.' and never a
3934// comma ',', regardless of the LOCALE environment variable.
3935// - It does allow arbitrary underscores. For example, "_3.141_592" would
3936// successfully parse, again approximately π.
3937// - It does allow "inf", "+Infinity" and "-NAN", case insensitive, but it
3938// does not permit "nan" to be followed by an integer mantissa.
3939// - It does not allow hexadecimal floating point numbers.
3940//
3941// For modular builds that divide the base module into sub-modules, using this
3942// function requires the WUFFS_CONFIG__MODULE__BASE__F64CONV sub-module, not
3943// just WUFFS_CONFIG__MODULE__BASE__CORE.
3944WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
3945wuffs_base__parse_number_f64(wuffs_base__slice_u8 s);
3946
3947// wuffs_base__ieee_754_bit_representation__etc converts between a double
3948// precision numerical value and its IEEE 754 64-bit representation (1 sign
3949// bit, 11 exponent bits, 52 explicit significand bits).
3950//
3951// For example, it converts between:
3952// - +1.0 and 0x3FF0_0000_0000_0000.
3953// - +5.5 and 0x4016_0000_0000_0000.
3954// - -inf and 0xFFF0_0000_0000_0000.
3955//
3956// See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
3957
3958static inline uint64_t //
3959wuffs_base__ieee_754_bit_representation__from_f64(double f) {
3960 uint64_t u = 0;
3961 if (sizeof(uint64_t) == sizeof(double)) {
3962 memcpy(&u, &f, sizeof(uint64_t));
3963 }
3964 return u;
3965}
3966
3967static inline double //
3968wuffs_base__ieee_754_bit_representation__to_f64(uint64_t u) {
3969 double f = 0;
3970 if (sizeof(uint64_t) == sizeof(double)) {
3971 memcpy(&f, &u, sizeof(uint64_t));
3972 }
3973 return f;
3974}
3975
3976// ---------------- Hexadecimal
3977
3978// wuffs_base__hexadecimal__decode2 converts "6A6b" to "jk", where e.g. 'j' is
3979// U+006A. There are 2 source bytes for every destination byte.
3980//
3981// It returns the number of dst bytes written: the minimum of dst.len and
3982// (src.len / 2). Excess source bytes are ignored.
3983//
3984// It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
3985// repeated. It may write nonsense bytes if not, although it will not read or
3986// write out of bounds.
3987WUFFS_BASE__MAYBE_STATIC size_t //
3988wuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,
3989 wuffs_base__slice_u8 src);
3990
3991// wuffs_base__hexadecimal__decode4 converts "\\x6A\\x6b" to "jk", where e.g.
3992// 'j' is U+006A. There are 4 source bytes for every destination byte.
3993//
3994// It returns the number of dst bytes written: the minimum of dst.len and
3995// (src.len / 4). Excess source bytes are ignored.
3996//
3997// It assumes that the src bytes are two ignored bytes and then two hexadecimal
3998// digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
3999// although it will not read or write out of bounds.
4000WUFFS_BASE__MAYBE_STATIC size_t //
4001wuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,
4002 wuffs_base__slice_u8 src);
4003
4004// ---------------- Unicode and UTF-8
4005
4006#define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
4007#define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
4008
4009#define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD
4010
4011#define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800
4012#define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF
4013
4014#define WUFFS_BASE__ASCII__MIN_INCL 0x00
4015#define WUFFS_BASE__ASCII__MAX_INCL 0x7F
4016
4017#define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1
4018#define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4
4019
4020#define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000
4021#define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F
4022#define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080
4023#define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF
4024#define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800
4025#define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF
4026#define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MIN_INCL 0x00010000
4027#define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF
4028
4029// --------
4030
4031// wuffs_base__utf_8__next__output is the type returned by
4032// wuffs_base__utf_8__next.
4033typedef struct {
4034 uint32_t code_point;
4035 uint32_t byte_length;
4036
4037#ifdef __cplusplus
4038 inline bool is_valid() const;
4039#endif // __cplusplus
4040
4041} wuffs_base__utf_8__next__output;
4042
4043static inline wuffs_base__utf_8__next__output //
4044wuffs_base__make_utf_8__next__output(uint32_t code_point,
4045 uint32_t byte_length) {
4046 wuffs_base__utf_8__next__output ret;
4047 ret.code_point = code_point;
4048 ret.byte_length = byte_length;
4049 return ret;
4050}
4051
4052static inline bool //
4053wuffs_base__utf_8__next__output__is_valid(
4054 const wuffs_base__utf_8__next__output* o) {
4055 if (o) {
4056 uint32_t cp = o->code_point;
4057 switch (o->byte_length) {
4058 case 1:
4059 return (cp <= 0x7F);
4060 case 2:
4061 return (0x080 <= cp) && (cp <= 0x7FF);
4062 case 3:
4063 // Avoid the 0xD800 ..= 0xDFFF surrogate range.
4064 return ((0x0800 <= cp) && (cp <= 0xD7FF)) ||
4065 ((0xE000 <= cp) && (cp <= 0xFFFF));
4066 case 4:
4067 return (0x00010000 <= cp) && (cp <= 0x0010FFFF);
4068 }
4069 }
4070 return false;
4071}
4072
4073#ifdef __cplusplus
4074
4075inline bool //
4076wuffs_base__utf_8__next__output::is_valid() const {
4077 return wuffs_base__utf_8__next__output__is_valid(this);
4078}
4079
4080#endif // __cplusplus
4081
4082// --------
4083
4084// wuffs_base__utf_8__encode writes the UTF-8 encoding of code_point to s and
4085// returns the number of bytes written. If code_point is invalid, or if s is
4086// shorter than the entire encoding, it returns 0 (and no bytes are written).
4087//
4088// s will never be too short if its length is at least 4, also known as
4089// WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL.
4090WUFFS_BASE__MAYBE_STATIC size_t //
4091wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point);
4092
4093// wuffs_base__utf_8__next returns the next UTF-8 code point (and that code
4094// point's byte length) at the start of s.
4095//
4096// There are exactly two cases in which this function returns something where
4097// wuffs_base__utf_8__next__output__is_valid is false:
4098// - If s is empty then it returns {.code_point=0, .byte_length=0}.
4099// - If s is non-empty and starts with invalid UTF-8 then it returns
4100// {.code_point=WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, .byte_length=1}.
4101//
4102// Otherwise, it returns something where
4103// wuffs_base__utf_8__next__output__is_valid is true.
4104//
4105// In any case, it always returns an output that satisfies both of:
4106// - (output.code_point <= WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL).
4107// - (output.byte_length <= s.len).
4108//
4109// If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
4110// boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
4111// code point, then this function may return something invalid. It is the
4112// caller's responsibility to split on or otherwise manage UTF-8 boundaries.
4113WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
4114wuffs_base__utf_8__next(wuffs_base__slice_u8 s);
4115
4116// wuffs_base__utf_8__longest_valid_prefix returns the largest n such that the
4117// sub-slice s[..n] is valid UTF-8.
4118//
4119// In particular, it returns s.len if and only if all of s is valid UTF-8.
4120//
4121// If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
4122// boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
4123// code point, then this function will return less than s.len. It is the
4124// caller's responsibility to split on or otherwise manage UTF-8 boundaries.
4125WUFFS_BASE__MAYBE_STATIC size_t //
4126wuffs_base__utf_8__longest_valid_prefix(wuffs_base__slice_u8 s);
4127
4128// wuffs_base__ascii__longest_valid_prefix returns the largest n such that the
4129// sub-slice s[..n] is valid ASCII.
4130//
4131// In particular, it returns s.len if and only if all of s is valid ASCII.
4132// Equivalently, when none of the bytes in s have the 0x80 high bit set.
4133WUFFS_BASE__MAYBE_STATIC size_t //
4134wuffs_base__ascii__longest_valid_prefix(wuffs_base__slice_u8 s);
4135
4136// ---------------- Interface Declarations.
4137
4138// For modular builds that divide the base module into sub-modules, using these
4139// functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
4140// just WUFFS_CONFIG__MODULE__BASE__CORE.
4141
4142// --------
4143
4144extern const char* wuffs_base__hasher_u32__vtable_name;
4145
4146typedef struct {
4147 wuffs_base__empty_struct (*set_quirk_enabled)(
4148 void* self,
4149 uint32_t a_quirk,
4150 bool a_enabled);
4151 uint32_t (*update_u32)(
4152 void* self,
4153 wuffs_base__slice_u8 a_x);
4154} wuffs_base__hasher_u32__func_ptrs;
4155
4156typedef struct wuffs_base__hasher_u32__struct wuffs_base__hasher_u32;
4157
4158WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4159wuffs_base__hasher_u32__set_quirk_enabled(
4160 wuffs_base__hasher_u32* self,
4161 uint32_t a_quirk,
4162 bool a_enabled);
4163
4164WUFFS_BASE__MAYBE_STATIC uint32_t
4165wuffs_base__hasher_u32__update_u32(
4166 wuffs_base__hasher_u32* self,
4167 wuffs_base__slice_u8 a_x);
4168
4169#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4170
4171struct wuffs_base__hasher_u32__struct {
4172 struct {
4173 uint32_t magic;
4174 uint32_t active_coroutine;
4175 wuffs_base__vtable first_vtable;
4176 } private_impl;
4177
4178#ifdef __cplusplus
4179#if (__cplusplus >= 201103L)
4180 using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, decltype(&free)>;
4181#endif
4182
4183 inline wuffs_base__empty_struct
4184 set_quirk_enabled(
4185 uint32_t a_quirk,
4186 bool a_enabled) {
4187 return wuffs_base__hasher_u32__set_quirk_enabled(
4188 this, a_quirk, a_enabled);
4189 }
4190
4191 inline uint32_t
4192 update_u32(
4193 wuffs_base__slice_u8 a_x) {
4194 return wuffs_base__hasher_u32__update_u32(
4195 this, a_x);
4196 }
4197
4198#endif // __cplusplus
4199}; // struct wuffs_base__hasher_u32__struct
4200
4201#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4202
4203// --------
4204
4205extern const char* wuffs_base__image_decoder__vtable_name;
4206
4207typedef struct {
4208 wuffs_base__status (*decode_frame)(
4209 void* self,
4210 wuffs_base__pixel_buffer* a_dst,
4211 wuffs_base__io_buffer* a_src,
4212 wuffs_base__pixel_blend a_blend,
4213 wuffs_base__slice_u8 a_workbuf,
4214 wuffs_base__decode_frame_options* a_opts);
4215 wuffs_base__status (*decode_frame_config)(
4216 void* self,
4217 wuffs_base__frame_config* a_dst,
4218 wuffs_base__io_buffer* a_src);
4219 wuffs_base__status (*decode_image_config)(
4220 void* self,
4221 wuffs_base__image_config* a_dst,
4222 wuffs_base__io_buffer* a_src);
4223 wuffs_base__rect_ie_u32 (*frame_dirty_rect)(
4224 const void* self);
4225 uint32_t (*num_animation_loops)(
4226 const void* self);
4227 uint64_t (*num_decoded_frame_configs)(
4228 const void* self);
4229 uint64_t (*num_decoded_frames)(
4230 const void* self);
4231 wuffs_base__status (*restart_frame)(
4232 void* self,
4233 uint64_t a_index,
4234 uint64_t a_io_position);
4235 wuffs_base__empty_struct (*set_quirk_enabled)(
4236 void* self,
4237 uint32_t a_quirk,
4238 bool a_enabled);
4239 wuffs_base__empty_struct (*set_report_metadata)(
4240 void* self,
4241 uint32_t a_fourcc,
4242 bool a_report);
4243 wuffs_base__status (*tell_me_more)(
4244 void* self,
4245 wuffs_base__io_buffer* a_dst,
4246 wuffs_base__more_information* a_minfo,
4247 wuffs_base__io_buffer* a_src);
4248 wuffs_base__range_ii_u64 (*workbuf_len)(
4249 const void* self);
4250} wuffs_base__image_decoder__func_ptrs;
4251
4252typedef struct wuffs_base__image_decoder__struct wuffs_base__image_decoder;
4253
4254WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4255wuffs_base__image_decoder__decode_frame(
4256 wuffs_base__image_decoder* self,
4257 wuffs_base__pixel_buffer* a_dst,
4258 wuffs_base__io_buffer* a_src,
4259 wuffs_base__pixel_blend a_blend,
4260 wuffs_base__slice_u8 a_workbuf,
4261 wuffs_base__decode_frame_options* a_opts);
4262
4263WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4264wuffs_base__image_decoder__decode_frame_config(
4265 wuffs_base__image_decoder* self,
4266 wuffs_base__frame_config* a_dst,
4267 wuffs_base__io_buffer* a_src);
4268
4269WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4270wuffs_base__image_decoder__decode_image_config(
4271 wuffs_base__image_decoder* self,
4272 wuffs_base__image_config* a_dst,
4273 wuffs_base__io_buffer* a_src);
4274
4275WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
4276wuffs_base__image_decoder__frame_dirty_rect(
4277 const wuffs_base__image_decoder* self);
4278
4279WUFFS_BASE__MAYBE_STATIC uint32_t
4280wuffs_base__image_decoder__num_animation_loops(
4281 const wuffs_base__image_decoder* self);
4282
4283WUFFS_BASE__MAYBE_STATIC uint64_t
4284wuffs_base__image_decoder__num_decoded_frame_configs(
4285 const wuffs_base__image_decoder* self);
4286
4287WUFFS_BASE__MAYBE_STATIC uint64_t
4288wuffs_base__image_decoder__num_decoded_frames(
4289 const wuffs_base__image_decoder* self);
4290
4291WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4292wuffs_base__image_decoder__restart_frame(
4293 wuffs_base__image_decoder* self,
4294 uint64_t a_index,
4295 uint64_t a_io_position);
4296
4297WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4298wuffs_base__image_decoder__set_quirk_enabled(
4299 wuffs_base__image_decoder* self,
4300 uint32_t a_quirk,
4301 bool a_enabled);
4302
4303WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4304wuffs_base__image_decoder__set_report_metadata(
4305 wuffs_base__image_decoder* self,
4306 uint32_t a_fourcc,
4307 bool a_report);
4308
4309WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4310wuffs_base__image_decoder__tell_me_more(
4311 wuffs_base__image_decoder* self,
4312 wuffs_base__io_buffer* a_dst,
4313 wuffs_base__more_information* a_minfo,
4314 wuffs_base__io_buffer* a_src);
4315
4316WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
4317wuffs_base__image_decoder__workbuf_len(
4318 const wuffs_base__image_decoder* self);
4319
4320#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4321
4322struct wuffs_base__image_decoder__struct {
4323 struct {
4324 uint32_t magic;
4325 uint32_t active_coroutine;
4326 wuffs_base__vtable first_vtable;
4327 } private_impl;
4328
4329#ifdef __cplusplus
4330#if (__cplusplus >= 201103L)
4331 using unique_ptr = std::unique_ptr<wuffs_base__image_decoder, decltype(&free)>;
4332#endif
4333
4334 inline wuffs_base__status
4335 decode_frame(
4336 wuffs_base__pixel_buffer* a_dst,
4337 wuffs_base__io_buffer* a_src,
4338 wuffs_base__pixel_blend a_blend,
4339 wuffs_base__slice_u8 a_workbuf,
4340 wuffs_base__decode_frame_options* a_opts) {
4341 return wuffs_base__image_decoder__decode_frame(
4342 this, a_dst, a_src, a_blend, a_workbuf, a_opts);
4343 }
4344
4345 inline wuffs_base__status
4346 decode_frame_config(
4347 wuffs_base__frame_config* a_dst,
4348 wuffs_base__io_buffer* a_src) {
4349 return wuffs_base__image_decoder__decode_frame_config(
4350 this, a_dst, a_src);
4351 }
4352
4353 inline wuffs_base__status
4354 decode_image_config(
4355 wuffs_base__image_config* a_dst,
4356 wuffs_base__io_buffer* a_src) {
4357 return wuffs_base__image_decoder__decode_image_config(
4358 this, a_dst, a_src);
4359 }
4360
4361 inline wuffs_base__rect_ie_u32
4362 frame_dirty_rect() const {
4363 return wuffs_base__image_decoder__frame_dirty_rect(this);
4364 }
4365
4366 inline uint32_t
4367 num_animation_loops() const {
4368 return wuffs_base__image_decoder__num_animation_loops(this);
4369 }
4370
4371 inline uint64_t
4372 num_decoded_frame_configs() const {
4373 return wuffs_base__image_decoder__num_decoded_frame_configs(this);
4374 }
4375
4376 inline uint64_t
4377 num_decoded_frames() const {
4378 return wuffs_base__image_decoder__num_decoded_frames(this);
4379 }
4380
4381 inline wuffs_base__status
4382 restart_frame(
4383 uint64_t a_index,
4384 uint64_t a_io_position) {
4385 return wuffs_base__image_decoder__restart_frame(
4386 this, a_index, a_io_position);
4387 }
4388
4389 inline wuffs_base__empty_struct
4390 set_quirk_enabled(
4391 uint32_t a_quirk,
4392 bool a_enabled) {
4393 return wuffs_base__image_decoder__set_quirk_enabled(
4394 this, a_quirk, a_enabled);
4395 }
4396
4397 inline wuffs_base__empty_struct
4398 set_report_metadata(
4399 uint32_t a_fourcc,
4400 bool a_report) {
4401 return wuffs_base__image_decoder__set_report_metadata(
4402 this, a_fourcc, a_report);
4403 }
4404
4405 inline wuffs_base__status
4406 tell_me_more(
4407 wuffs_base__io_buffer* a_dst,
4408 wuffs_base__more_information* a_minfo,
4409 wuffs_base__io_buffer* a_src) {
4410 return wuffs_base__image_decoder__tell_me_more(
4411 this, a_dst, a_minfo, a_src);
4412 }
4413
4414 inline wuffs_base__range_ii_u64
4415 workbuf_len() const {
4416 return wuffs_base__image_decoder__workbuf_len(this);
4417 }
4418
4419#endif // __cplusplus
4420}; // struct wuffs_base__image_decoder__struct
4421
4422#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4423
4424// --------
4425
4426extern const char* wuffs_base__io_transformer__vtable_name;
4427
4428typedef struct {
4429 wuffs_base__empty_struct (*set_quirk_enabled)(
4430 void* self,
4431 uint32_t a_quirk,
4432 bool a_enabled);
4433 wuffs_base__status (*transform_io)(
4434 void* self,
4435 wuffs_base__io_buffer* a_dst,
4436 wuffs_base__io_buffer* a_src,
4437 wuffs_base__slice_u8 a_workbuf);
4438 wuffs_base__range_ii_u64 (*workbuf_len)(
4439 const void* self);
4440} wuffs_base__io_transformer__func_ptrs;
4441
4442typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer;
4443
4444WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4445wuffs_base__io_transformer__set_quirk_enabled(
4446 wuffs_base__io_transformer* self,
4447 uint32_t a_quirk,
4448 bool a_enabled);
4449
4450WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4451wuffs_base__io_transformer__transform_io(
4452 wuffs_base__io_transformer* self,
4453 wuffs_base__io_buffer* a_dst,
4454 wuffs_base__io_buffer* a_src,
4455 wuffs_base__slice_u8 a_workbuf);
4456
4457WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
4458wuffs_base__io_transformer__workbuf_len(
4459 const wuffs_base__io_transformer* self);
4460
4461#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4462
4463struct wuffs_base__io_transformer__struct {
4464 struct {
4465 uint32_t magic;
4466 uint32_t active_coroutine;
4467 wuffs_base__vtable first_vtable;
4468 } private_impl;
4469
4470#ifdef __cplusplus
4471#if (__cplusplus >= 201103L)
4472 using unique_ptr = std::unique_ptr<wuffs_base__io_transformer, decltype(&free)>;
4473#endif
4474
4475 inline wuffs_base__empty_struct
4476 set_quirk_enabled(
4477 uint32_t a_quirk,
4478 bool a_enabled) {
4479 return wuffs_base__io_transformer__set_quirk_enabled(
4480 this, a_quirk, a_enabled);
4481 }
4482
4483 inline wuffs_base__status
4484 transform_io(
4485 wuffs_base__io_buffer* a_dst,
4486 wuffs_base__io_buffer* a_src,
4487 wuffs_base__slice_u8 a_workbuf) {
4488 return wuffs_base__io_transformer__transform_io(
4489 this, a_dst, a_src, a_workbuf);
4490 }
4491
4492 inline wuffs_base__range_ii_u64
4493 workbuf_len() const {
4494 return wuffs_base__io_transformer__workbuf_len(this);
4495 }
4496
4497#endif // __cplusplus
4498}; // struct wuffs_base__io_transformer__struct
4499
4500#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4501
4502// --------
4503
4504extern const char* wuffs_base__token_decoder__vtable_name;
4505
4506typedef struct {
4507 wuffs_base__status (*decode_tokens)(
4508 void* self,
4509 wuffs_base__token_buffer* a_dst,
4510 wuffs_base__io_buffer* a_src,
4511 wuffs_base__slice_u8 a_workbuf);
4512 wuffs_base__empty_struct (*set_quirk_enabled)(
4513 void* self,
4514 uint32_t a_quirk,
4515 bool a_enabled);
4516 wuffs_base__range_ii_u64 (*workbuf_len)(
4517 const void* self);
4518} wuffs_base__token_decoder__func_ptrs;
4519
4520typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
4521
4522WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4523wuffs_base__token_decoder__decode_tokens(
4524 wuffs_base__token_decoder* self,
4525 wuffs_base__token_buffer* a_dst,
4526 wuffs_base__io_buffer* a_src,
4527 wuffs_base__slice_u8 a_workbuf);
4528
4529WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4530wuffs_base__token_decoder__set_quirk_enabled(
4531 wuffs_base__token_decoder* self,
4532 uint32_t a_quirk,
4533 bool a_enabled);
4534
4535WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
4536wuffs_base__token_decoder__workbuf_len(
4537 const wuffs_base__token_decoder* self);
4538
4539#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4540
4541struct wuffs_base__token_decoder__struct {
4542 struct {
4543 uint32_t magic;
4544 uint32_t active_coroutine;
4545 wuffs_base__vtable first_vtable;
4546 } private_impl;
4547
4548#ifdef __cplusplus
4549#if (__cplusplus >= 201103L)
4550 using unique_ptr = std::unique_ptr<wuffs_base__token_decoder, decltype(&free)>;
4551#endif
4552
4553 inline wuffs_base__status
4554 decode_tokens(
4555 wuffs_base__token_buffer* a_dst,
4556 wuffs_base__io_buffer* a_src,
4557 wuffs_base__slice_u8 a_workbuf) {
4558 return wuffs_base__token_decoder__decode_tokens(
4559 this, a_dst, a_src, a_workbuf);
4560 }
4561
4562 inline wuffs_base__empty_struct
4563 set_quirk_enabled(
4564 uint32_t a_quirk,
4565 bool a_enabled) {
4566 return wuffs_base__token_decoder__set_quirk_enabled(
4567 this, a_quirk, a_enabled);
4568 }
4569
4570 inline wuffs_base__range_ii_u64
4571 workbuf_len() const {
4572 return wuffs_base__token_decoder__workbuf_len(this);
4573 }
4574
4575#endif // __cplusplus
4576}; // struct wuffs_base__token_decoder__struct
4577
4578#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4579
4580// ----------------
4581
4582#ifdef __cplusplus
4583} // extern "C"
4584#endif
4585
4586#ifdef __cplusplus
4587extern "C" {
4588#endif
4589
4590// ---------------- Status Codes
4591
4592// ---------------- Public Consts
4593
4594// ---------------- Struct Declarations
4595
4596typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
4597
4598// ---------------- Public Initializer Prototypes
4599
4600// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
4601// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
4602//
4603// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
4604// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
4605
4606wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
4607wuffs_adler32__hasher__initialize(
4608 wuffs_adler32__hasher* self,
4609 size_t sizeof_star_self,
4610 uint64_t wuffs_version,
4611 uint32_t initialize_flags);
4612
4613size_t
4614sizeof__wuffs_adler32__hasher();
4615
4616// ---------------- Allocs
4617
4618// These functions allocate and initialize Wuffs structs. They return NULL if
4619// memory allocation fails. If they return non-NULL, there is no need to call
4620// wuffs_foo__bar__initialize, but the caller is responsible for eventually
4621// calling free on the returned pointer. That pointer is effectively a C++
4622// std::unique_ptr<T, decltype(&free)>.
4623
4624wuffs_adler32__hasher*
4625wuffs_adler32__hasher__alloc();
4626
4627static inline wuffs_base__hasher_u32*
4628wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32() {
4629 return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
4630}
4631
4632// ---------------- Upcasts
4633
4634static inline wuffs_base__hasher_u32*
4635wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(
4636 wuffs_adler32__hasher* p) {
4637 return (wuffs_base__hasher_u32*)p;
4638}
4639
4640// ---------------- Public Function Prototypes
4641
4642WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4643wuffs_adler32__hasher__set_quirk_enabled(
4644 wuffs_adler32__hasher* self,
4645 uint32_t a_quirk,
4646 bool a_enabled);
4647
4648WUFFS_BASE__MAYBE_STATIC uint32_t
4649wuffs_adler32__hasher__update_u32(
4650 wuffs_adler32__hasher* self,
4651 wuffs_base__slice_u8 a_x);
4652
4653// ---------------- Struct Definitions
4654
4655// These structs' fields, and the sizeof them, are private implementation
4656// details that aren't guaranteed to be stable across Wuffs versions.
4657//
4658// See https://en.wikipedia.org/wiki/Opaque_pointer#C
4659
4660#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4661
4662struct wuffs_adler32__hasher__struct {
4663 // Do not access the private_impl's or private_data's fields directly. There
4664 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
4665 // the wuffs_foo__bar__baz functions.
4666 //
4667 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
4668 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
4669
4670 struct {
4671 uint32_t magic;
4672 uint32_t active_coroutine;
4673 wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
4674 wuffs_base__vtable null_vtable;
4675
4676 uint32_t f_state;
4677 bool f_started;
4678 } private_impl;
4679
4680#ifdef __cplusplus
4681#if (__cplusplus >= 201103L)
4682 using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, decltype(&free)>;
4683
4684 // On failure, the alloc_etc functions return nullptr. They don't throw.
4685
4686 static inline unique_ptr
4687 alloc() {
4688 return unique_ptr(wuffs_adler32__hasher__alloc(), &free);
4689 }
4690
4691 static inline wuffs_base__hasher_u32::unique_ptr
4692 alloc_as__wuffs_base__hasher_u32() {
4693 return wuffs_base__hasher_u32::unique_ptr(
4694 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(), &free);
4695 }
4696#endif // (__cplusplus >= 201103L)
4697
4698#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
4699 // Disallow constructing or copying an object via standard C++ mechanisms,
4700 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
4701 // size and field layout is not part of the public, stable, memory-safe API.
4702 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
4703 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
4704 // their first argument) rather than tweaking bar.private_impl.qux fields.
4705 //
4706 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
4707 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
4708 // order to provide convenience methods. These forward on "this", so that you
4709 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
4710 wuffs_adler32__hasher__struct() = delete;
4711 wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
4712 wuffs_adler32__hasher__struct& operator=(
4713 const wuffs_adler32__hasher__struct&) = delete;
4714
4715 // As above, the size of the struct is not part of the public API, and unless
4716 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
4717 // allocated, not stack allocated. Its size is not intended to be known at
4718 // compile time, but it is unfortunately divulged as a side effect of
4719 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
4720 // instead of "sizeof T", invoking the operator. To make the two values
4721 // different, so that passing the latter will be rejected by the initialize
4722 // function, we add an arbitrary amount of dead weight.
4723 uint8_t dead_weight[123000000]; // 123 MB.
4724#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
4725
4726 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
4727 initialize(
4728 size_t sizeof_star_self,
4729 uint64_t wuffs_version,
4730 uint32_t initialize_flags) {
4731 return wuffs_adler32__hasher__initialize(
4732 this, sizeof_star_self, wuffs_version, initialize_flags);
4733 }
4734
4735 inline wuffs_base__hasher_u32*
4736 upcast_as__wuffs_base__hasher_u32() {
4737 return (wuffs_base__hasher_u32*)this;
4738 }
4739
4740 inline wuffs_base__empty_struct
4741 set_quirk_enabled(
4742 uint32_t a_quirk,
4743 bool a_enabled) {
4744 return wuffs_adler32__hasher__set_quirk_enabled(this, a_quirk, a_enabled);
4745 }
4746
4747 inline uint32_t
4748 update_u32(
4749 wuffs_base__slice_u8 a_x) {
4750 return wuffs_adler32__hasher__update_u32(this, a_x);
4751 }
4752
4753#endif // __cplusplus
4754}; // struct wuffs_adler32__hasher__struct
4755
4756#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4757
4758#ifdef __cplusplus
4759} // extern "C"
4760#endif
4761
4762#ifdef __cplusplus
4763extern "C" {
4764#endif
4765
4766// ---------------- Status Codes
4767
4768extern const char* wuffs_bmp__error__bad_header;
4769extern const char* wuffs_bmp__error__unsupported_bmp_file;
4770
4771// ---------------- Public Consts
4772
4773#define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
4774
4775// ---------------- Struct Declarations
4776
4777typedef struct wuffs_bmp__decoder__struct wuffs_bmp__decoder;
4778
4779// ---------------- Public Initializer Prototypes
4780
4781// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
4782// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
4783//
4784// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
4785// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
4786
4787wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
4788wuffs_bmp__decoder__initialize(
4789 wuffs_bmp__decoder* self,
4790 size_t sizeof_star_self,
4791 uint64_t wuffs_version,
4792 uint32_t initialize_flags);
4793
4794size_t
4795sizeof__wuffs_bmp__decoder();
4796
4797// ---------------- Allocs
4798
4799// These functions allocate and initialize Wuffs structs. They return NULL if
4800// memory allocation fails. If they return non-NULL, there is no need to call
4801// wuffs_foo__bar__initialize, but the caller is responsible for eventually
4802// calling free on the returned pointer. That pointer is effectively a C++
4803// std::unique_ptr<T, decltype(&free)>.
4804
4805wuffs_bmp__decoder*
4806wuffs_bmp__decoder__alloc();
4807
4808static inline wuffs_base__image_decoder*
4809wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder() {
4810 return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
4811}
4812
4813// ---------------- Upcasts
4814
4815static inline wuffs_base__image_decoder*
4816wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
4817 wuffs_bmp__decoder* p) {
4818 return (wuffs_base__image_decoder*)p;
4819}
4820
4821// ---------------- Public Function Prototypes
4822
4823WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4824wuffs_bmp__decoder__set_quirk_enabled(
4825 wuffs_bmp__decoder* self,
4826 uint32_t a_quirk,
4827 bool a_enabled);
4828
4829WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4830wuffs_bmp__decoder__decode_image_config(
4831 wuffs_bmp__decoder* self,
4832 wuffs_base__image_config* a_dst,
4833 wuffs_base__io_buffer* a_src);
4834
4835WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4836wuffs_bmp__decoder__decode_frame_config(
4837 wuffs_bmp__decoder* self,
4838 wuffs_base__frame_config* a_dst,
4839 wuffs_base__io_buffer* a_src);
4840
4841WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4842wuffs_bmp__decoder__decode_frame(
4843 wuffs_bmp__decoder* self,
4844 wuffs_base__pixel_buffer* a_dst,
4845 wuffs_base__io_buffer* a_src,
4846 wuffs_base__pixel_blend a_blend,
4847 wuffs_base__slice_u8 a_workbuf,
4848 wuffs_base__decode_frame_options* a_opts);
4849
4850WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
4851wuffs_bmp__decoder__frame_dirty_rect(
4852 const wuffs_bmp__decoder* self);
4853
4854WUFFS_BASE__MAYBE_STATIC uint32_t
4855wuffs_bmp__decoder__num_animation_loops(
4856 const wuffs_bmp__decoder* self);
4857
4858WUFFS_BASE__MAYBE_STATIC uint64_t
4859wuffs_bmp__decoder__num_decoded_frame_configs(
4860 const wuffs_bmp__decoder* self);
4861
4862WUFFS_BASE__MAYBE_STATIC uint64_t
4863wuffs_bmp__decoder__num_decoded_frames(
4864 const wuffs_bmp__decoder* self);
4865
4866WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4867wuffs_bmp__decoder__restart_frame(
4868 wuffs_bmp__decoder* self,
4869 uint64_t a_index,
4870 uint64_t a_io_position);
4871
4872WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
4873wuffs_bmp__decoder__set_report_metadata(
4874 wuffs_bmp__decoder* self,
4875 uint32_t a_fourcc,
4876 bool a_report);
4877
4878WUFFS_BASE__MAYBE_STATIC wuffs_base__status
4879wuffs_bmp__decoder__tell_me_more(
4880 wuffs_bmp__decoder* self,
4881 wuffs_base__io_buffer* a_dst,
4882 wuffs_base__more_information* a_minfo,
4883 wuffs_base__io_buffer* a_src);
4884
4885WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
4886wuffs_bmp__decoder__workbuf_len(
4887 const wuffs_bmp__decoder* self);
4888
4889// ---------------- Struct Definitions
4890
4891// These structs' fields, and the sizeof them, are private implementation
4892// details that aren't guaranteed to be stable across Wuffs versions.
4893//
4894// See https://en.wikipedia.org/wiki/Opaque_pointer#C
4895
4896#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
4897
4898struct wuffs_bmp__decoder__struct {
4899 // Do not access the private_impl's or private_data's fields directly. There
4900 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
4901 // the wuffs_foo__bar__baz functions.
4902 //
4903 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
4904 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
4905
4906 struct {
4907 uint32_t magic;
4908 uint32_t active_coroutine;
4909 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
4910 wuffs_base__vtable null_vtable;
4911
4912 uint32_t f_width;
4913 uint32_t f_height;
4914 uint8_t f_call_sequence;
4915 bool f_top_down;
4916 uint32_t f_pad_per_row;
4917 uint64_t f_bytes_per_row;
4918 wuffs_base__pixel_format f_pixfmt;
4919 uint32_t f_io_redirect_fourcc;
4920 uint64_t f_io_redirect_pos;
4921 uint64_t f_frame_config_io_position;
4922 uint32_t f_padding;
4923 uint32_t f_mask_r;
4924 uint32_t f_mask_g;
4925 uint32_t f_mask_b;
4926 uint32_t f_mask_a;
4927 uint32_t f_dst_x;
4928 uint32_t f_dst_y;
4929 uint32_t f_dst_y_end;
4930 uint32_t f_dst_y_inc;
4931 uint32_t f_pending_pad;
4932 wuffs_base__pixel_swizzler f_swizzler;
4933
4934 uint32_t p_decode_image_config[1];
4935 uint32_t p_decode_frame_config[1];
4936 uint32_t p_decode_frame[1];
4937 uint32_t p_skip_frame[1];
4938 } private_impl;
4939
4940 struct {
4941 struct {
4942 uint32_t v_bitmap_info_len;
4943 uint32_t v_bits_per_pixel;
4944 uint32_t v_compression;
4945 uint64_t scratch;
4946 } s_decode_image_config[1];
4947 struct {
4948 uint64_t scratch;
4949 } s_decode_frame[1];
4950 struct {
4951 uint64_t scratch;
4952 } s_skip_frame[1];
4953 } private_data;
4954
4955#ifdef __cplusplus
4956#if (__cplusplus >= 201103L)
4957 using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, decltype(&free)>;
4958
4959 // On failure, the alloc_etc functions return nullptr. They don't throw.
4960
4961 static inline unique_ptr
4962 alloc() {
4963 return unique_ptr(wuffs_bmp__decoder__alloc(), &free);
4964 }
4965
4966 static inline wuffs_base__image_decoder::unique_ptr
4967 alloc_as__wuffs_base__image_decoder() {
4968 return wuffs_base__image_decoder::unique_ptr(
4969 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
4970 }
4971#endif // (__cplusplus >= 201103L)
4972
4973#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
4974 // Disallow constructing or copying an object via standard C++ mechanisms,
4975 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
4976 // size and field layout is not part of the public, stable, memory-safe API.
4977 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
4978 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
4979 // their first argument) rather than tweaking bar.private_impl.qux fields.
4980 //
4981 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
4982 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
4983 // order to provide convenience methods. These forward on "this", so that you
4984 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
4985 wuffs_bmp__decoder__struct() = delete;
4986 wuffs_bmp__decoder__struct(const wuffs_bmp__decoder__struct&) = delete;
4987 wuffs_bmp__decoder__struct& operator=(
4988 const wuffs_bmp__decoder__struct&) = delete;
4989
4990 // As above, the size of the struct is not part of the public API, and unless
4991 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
4992 // allocated, not stack allocated. Its size is not intended to be known at
4993 // compile time, but it is unfortunately divulged as a side effect of
4994 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
4995 // instead of "sizeof T", invoking the operator. To make the two values
4996 // different, so that passing the latter will be rejected by the initialize
4997 // function, we add an arbitrary amount of dead weight.
4998 uint8_t dead_weight[123000000]; // 123 MB.
4999#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
5000
5001 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5002 initialize(
5003 size_t sizeof_star_self,
5004 uint64_t wuffs_version,
5005 uint32_t initialize_flags) {
5006 return wuffs_bmp__decoder__initialize(
5007 this, sizeof_star_self, wuffs_version, initialize_flags);
5008 }
5009
5010 inline wuffs_base__image_decoder*
5011 upcast_as__wuffs_base__image_decoder() {
5012 return (wuffs_base__image_decoder*)this;
5013 }
5014
5015 inline wuffs_base__empty_struct
5016 set_quirk_enabled(
5017 uint32_t a_quirk,
5018 bool a_enabled) {
5019 return wuffs_bmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
5020 }
5021
5022 inline wuffs_base__status
5023 decode_image_config(
5024 wuffs_base__image_config* a_dst,
5025 wuffs_base__io_buffer* a_src) {
5026 return wuffs_bmp__decoder__decode_image_config(this, a_dst, a_src);
5027 }
5028
5029 inline wuffs_base__status
5030 decode_frame_config(
5031 wuffs_base__frame_config* a_dst,
5032 wuffs_base__io_buffer* a_src) {
5033 return wuffs_bmp__decoder__decode_frame_config(this, a_dst, a_src);
5034 }
5035
5036 inline wuffs_base__status
5037 decode_frame(
5038 wuffs_base__pixel_buffer* a_dst,
5039 wuffs_base__io_buffer* a_src,
5040 wuffs_base__pixel_blend a_blend,
5041 wuffs_base__slice_u8 a_workbuf,
5042 wuffs_base__decode_frame_options* a_opts) {
5043 return wuffs_bmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
5044 }
5045
5046 inline wuffs_base__rect_ie_u32
5047 frame_dirty_rect() const {
5048 return wuffs_bmp__decoder__frame_dirty_rect(this);
5049 }
5050
5051 inline uint32_t
5052 num_animation_loops() const {
5053 return wuffs_bmp__decoder__num_animation_loops(this);
5054 }
5055
5056 inline uint64_t
5057 num_decoded_frame_configs() const {
5058 return wuffs_bmp__decoder__num_decoded_frame_configs(this);
5059 }
5060
5061 inline uint64_t
5062 num_decoded_frames() const {
5063 return wuffs_bmp__decoder__num_decoded_frames(this);
5064 }
5065
5066 inline wuffs_base__status
5067 restart_frame(
5068 uint64_t a_index,
5069 uint64_t a_io_position) {
5070 return wuffs_bmp__decoder__restart_frame(this, a_index, a_io_position);
5071 }
5072
5073 inline wuffs_base__empty_struct
5074 set_report_metadata(
5075 uint32_t a_fourcc,
5076 bool a_report) {
5077 return wuffs_bmp__decoder__set_report_metadata(this, a_fourcc, a_report);
5078 }
5079
5080 inline wuffs_base__status
5081 tell_me_more(
5082 wuffs_base__io_buffer* a_dst,
5083 wuffs_base__more_information* a_minfo,
5084 wuffs_base__io_buffer* a_src) {
5085 return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
5086 }
5087
5088 inline wuffs_base__range_ii_u64
5089 workbuf_len() const {
5090 return wuffs_bmp__decoder__workbuf_len(this);
5091 }
5092
5093#endif // __cplusplus
5094}; // struct wuffs_bmp__decoder__struct
5095
5096#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5097
5098#ifdef __cplusplus
5099} // extern "C"
5100#endif
5101
5102#ifdef __cplusplus
5103extern "C" {
5104#endif
5105
5106// ---------------- Status Codes
5107
5108// ---------------- Public Consts
5109
5110// ---------------- Struct Declarations
5111
5112typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
5113
5114// ---------------- Public Initializer Prototypes
5115
5116// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
5117// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
5118//
5119// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
5120// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
5121
5122wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5123wuffs_crc32__ieee_hasher__initialize(
5124 wuffs_crc32__ieee_hasher* self,
5125 size_t sizeof_star_self,
5126 uint64_t wuffs_version,
5127 uint32_t initialize_flags);
5128
5129size_t
5130sizeof__wuffs_crc32__ieee_hasher();
5131
5132// ---------------- Allocs
5133
5134// These functions allocate and initialize Wuffs structs. They return NULL if
5135// memory allocation fails. If they return non-NULL, there is no need to call
5136// wuffs_foo__bar__initialize, but the caller is responsible for eventually
5137// calling free on the returned pointer. That pointer is effectively a C++
5138// std::unique_ptr<T, decltype(&free)>.
5139
5140wuffs_crc32__ieee_hasher*
5141wuffs_crc32__ieee_hasher__alloc();
5142
5143static inline wuffs_base__hasher_u32*
5144wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32() {
5145 return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
5146}
5147
5148// ---------------- Upcasts
5149
5150static inline wuffs_base__hasher_u32*
5151wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(
5152 wuffs_crc32__ieee_hasher* p) {
5153 return (wuffs_base__hasher_u32*)p;
5154}
5155
5156// ---------------- Public Function Prototypes
5157
5158WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5159wuffs_crc32__ieee_hasher__set_quirk_enabled(
5160 wuffs_crc32__ieee_hasher* self,
5161 uint32_t a_quirk,
5162 bool a_enabled);
5163
5164WUFFS_BASE__MAYBE_STATIC uint32_t
5165wuffs_crc32__ieee_hasher__update_u32(
5166 wuffs_crc32__ieee_hasher* self,
5167 wuffs_base__slice_u8 a_x);
5168
5169// ---------------- Struct Definitions
5170
5171// These structs' fields, and the sizeof them, are private implementation
5172// details that aren't guaranteed to be stable across Wuffs versions.
5173//
5174// See https://en.wikipedia.org/wiki/Opaque_pointer#C
5175
5176#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5177
5178struct wuffs_crc32__ieee_hasher__struct {
5179 // Do not access the private_impl's or private_data's fields directly. There
5180 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
5181 // the wuffs_foo__bar__baz functions.
5182 //
5183 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
5184 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
5185
5186 struct {
5187 uint32_t magic;
5188 uint32_t active_coroutine;
5189 wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
5190 wuffs_base__vtable null_vtable;
5191
5192 uint32_t f_state;
5193 } private_impl;
5194
5195#ifdef __cplusplus
5196#if (__cplusplus >= 201103L)
5197 using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, decltype(&free)>;
5198
5199 // On failure, the alloc_etc functions return nullptr. They don't throw.
5200
5201 static inline unique_ptr
5202 alloc() {
5203 return unique_ptr(wuffs_crc32__ieee_hasher__alloc(), &free);
5204 }
5205
5206 static inline wuffs_base__hasher_u32::unique_ptr
5207 alloc_as__wuffs_base__hasher_u32() {
5208 return wuffs_base__hasher_u32::unique_ptr(
5209 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(), &free);
5210 }
5211#endif // (__cplusplus >= 201103L)
5212
5213#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
5214 // Disallow constructing or copying an object via standard C++ mechanisms,
5215 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
5216 // size and field layout is not part of the public, stable, memory-safe API.
5217 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
5218 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
5219 // their first argument) rather than tweaking bar.private_impl.qux fields.
5220 //
5221 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
5222 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
5223 // order to provide convenience methods. These forward on "this", so that you
5224 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
5225 wuffs_crc32__ieee_hasher__struct() = delete;
5226 wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) = delete;
5227 wuffs_crc32__ieee_hasher__struct& operator=(
5228 const wuffs_crc32__ieee_hasher__struct&) = delete;
5229
5230 // As above, the size of the struct is not part of the public API, and unless
5231 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
5232 // allocated, not stack allocated. Its size is not intended to be known at
5233 // compile time, but it is unfortunately divulged as a side effect of
5234 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
5235 // instead of "sizeof T", invoking the operator. To make the two values
5236 // different, so that passing the latter will be rejected by the initialize
5237 // function, we add an arbitrary amount of dead weight.
5238 uint8_t dead_weight[123000000]; // 123 MB.
5239#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
5240
5241 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5242 initialize(
5243 size_t sizeof_star_self,
5244 uint64_t wuffs_version,
5245 uint32_t initialize_flags) {
5246 return wuffs_crc32__ieee_hasher__initialize(
5247 this, sizeof_star_self, wuffs_version, initialize_flags);
5248 }
5249
5250 inline wuffs_base__hasher_u32*
5251 upcast_as__wuffs_base__hasher_u32() {
5252 return (wuffs_base__hasher_u32*)this;
5253 }
5254
5255 inline wuffs_base__empty_struct
5256 set_quirk_enabled(
5257 uint32_t a_quirk,
5258 bool a_enabled) {
5259 return wuffs_crc32__ieee_hasher__set_quirk_enabled(this, a_quirk, a_enabled);
5260 }
5261
5262 inline uint32_t
5263 update_u32(
5264 wuffs_base__slice_u8 a_x) {
5265 return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
5266 }
5267
5268#endif // __cplusplus
5269}; // struct wuffs_crc32__ieee_hasher__struct
5270
5271#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5272
5273#ifdef __cplusplus
5274} // extern "C"
5275#endif
5276
5277#ifdef __cplusplus
5278extern "C" {
5279#endif
5280
5281// ---------------- Status Codes
5282
5283extern const char* wuffs_deflate__error__bad_huffman_code_over_subscribed;
5284extern const char* wuffs_deflate__error__bad_huffman_code_under_subscribed;
5285extern const char* wuffs_deflate__error__bad_huffman_code_length_count;
5286extern const char* wuffs_deflate__error__bad_huffman_code_length_repetition;
5287extern const char* wuffs_deflate__error__bad_huffman_code;
5288extern const char* wuffs_deflate__error__bad_huffman_minimum_code_length;
5289extern const char* wuffs_deflate__error__bad_block;
5290extern const char* wuffs_deflate__error__bad_distance;
5291extern const char* wuffs_deflate__error__bad_distance_code_count;
5292extern const char* wuffs_deflate__error__bad_literal_length_code_count;
5293extern const char* wuffs_deflate__error__inconsistent_stored_block_length;
5294extern const char* wuffs_deflate__error__missing_end_of_block_code;
5295extern const char* wuffs_deflate__error__no_huffman_codes;
5296
5297// ---------------- Public Consts
5298
5299#define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
5300
5301// ---------------- Struct Declarations
5302
5303typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
5304
5305// ---------------- Public Initializer Prototypes
5306
5307// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
5308// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
5309//
5310// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
5311// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
5312
5313wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5314wuffs_deflate__decoder__initialize(
5315 wuffs_deflate__decoder* self,
5316 size_t sizeof_star_self,
5317 uint64_t wuffs_version,
5318 uint32_t initialize_flags);
5319
5320size_t
5321sizeof__wuffs_deflate__decoder();
5322
5323// ---------------- Allocs
5324
5325// These functions allocate and initialize Wuffs structs. They return NULL if
5326// memory allocation fails. If they return non-NULL, there is no need to call
5327// wuffs_foo__bar__initialize, but the caller is responsible for eventually
5328// calling free on the returned pointer. That pointer is effectively a C++
5329// std::unique_ptr<T, decltype(&free)>.
5330
5331wuffs_deflate__decoder*
5332wuffs_deflate__decoder__alloc();
5333
5334static inline wuffs_base__io_transformer*
5335wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer() {
5336 return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
5337}
5338
5339// ---------------- Upcasts
5340
5341static inline wuffs_base__io_transformer*
5342wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(
5343 wuffs_deflate__decoder* p) {
5344 return (wuffs_base__io_transformer*)p;
5345}
5346
5347// ---------------- Public Function Prototypes
5348
5349WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5350wuffs_deflate__decoder__add_history(
5351 wuffs_deflate__decoder* self,
5352 wuffs_base__slice_u8 a_hist);
5353
5354WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5355wuffs_deflate__decoder__set_quirk_enabled(
5356 wuffs_deflate__decoder* self,
5357 uint32_t a_quirk,
5358 bool a_enabled);
5359
5360WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
5361wuffs_deflate__decoder__workbuf_len(
5362 const wuffs_deflate__decoder* self);
5363
5364WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5365wuffs_deflate__decoder__transform_io(
5366 wuffs_deflate__decoder* self,
5367 wuffs_base__io_buffer* a_dst,
5368 wuffs_base__io_buffer* a_src,
5369 wuffs_base__slice_u8 a_workbuf);
5370
5371// ---------------- Struct Definitions
5372
5373// These structs' fields, and the sizeof them, are private implementation
5374// details that aren't guaranteed to be stable across Wuffs versions.
5375//
5376// See https://en.wikipedia.org/wiki/Opaque_pointer#C
5377
5378#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5379
5380struct wuffs_deflate__decoder__struct {
5381 // Do not access the private_impl's or private_data's fields directly. There
5382 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
5383 // the wuffs_foo__bar__baz functions.
5384 //
5385 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
5386 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
5387
5388 struct {
5389 uint32_t magic;
5390 uint32_t active_coroutine;
5391 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
5392 wuffs_base__vtable null_vtable;
5393
5394 uint32_t f_bits;
5395 uint32_t f_n_bits;
5396 uint32_t f_history_index;
5397 uint32_t f_n_huffs_bits[2];
5398 bool f_end_of_block;
5399
5400 uint32_t p_transform_io[1];
5401 uint32_t p_decode_blocks[1];
5402 uint32_t p_decode_uncompressed[1];
5403 uint32_t p_init_dynamic_huffman[1];
5404 uint32_t p_decode_huffman_slow[1];
5405 } private_impl;
5406
5407 struct {
5408 uint32_t f_huffs[2][1024];
5409 uint8_t f_history[33025];
5410 uint8_t f_code_lengths[320];
5411
5412 struct {
5413 uint32_t v_final;
5414 } s_decode_blocks[1];
5415 struct {
5416 uint32_t v_length;
5417 uint64_t scratch;
5418 } s_decode_uncompressed[1];
5419 struct {
5420 uint32_t v_bits;
5421 uint32_t v_n_bits;
5422 uint32_t v_n_lit;
5423 uint32_t v_n_dist;
5424 uint32_t v_n_clen;
5425 uint32_t v_i;
5426 uint32_t v_mask;
5427 uint32_t v_table_entry;
5428 uint32_t v_n_extra_bits;
5429 uint8_t v_rep_symbol;
5430 uint32_t v_rep_count;
5431 } s_init_dynamic_huffman[1];
5432 struct {
5433 uint32_t v_bits;
5434 uint32_t v_n_bits;
5435 uint32_t v_table_entry;
5436 uint32_t v_table_entry_n_bits;
5437 uint32_t v_lmask;
5438 uint32_t v_dmask;
5439 uint32_t v_redir_top;
5440 uint32_t v_redir_mask;
5441 uint32_t v_length;
5442 uint32_t v_dist_minus_1;
5443 uint32_t v_hlen;
5444 uint32_t v_hdist;
5445 uint64_t scratch;
5446 } s_decode_huffman_slow[1];
5447 } private_data;
5448
5449#ifdef __cplusplus
5450#if (__cplusplus >= 201103L)
5451 using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, decltype(&free)>;
5452
5453 // On failure, the alloc_etc functions return nullptr. They don't throw.
5454
5455 static inline unique_ptr
5456 alloc() {
5457 return unique_ptr(wuffs_deflate__decoder__alloc(), &free);
5458 }
5459
5460 static inline wuffs_base__io_transformer::unique_ptr
5461 alloc_as__wuffs_base__io_transformer() {
5462 return wuffs_base__io_transformer::unique_ptr(
5463 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(), &free);
5464 }
5465#endif // (__cplusplus >= 201103L)
5466
5467#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
5468 // Disallow constructing or copying an object via standard C++ mechanisms,
5469 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
5470 // size and field layout is not part of the public, stable, memory-safe API.
5471 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
5472 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
5473 // their first argument) rather than tweaking bar.private_impl.qux fields.
5474 //
5475 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
5476 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
5477 // order to provide convenience methods. These forward on "this", so that you
5478 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
5479 wuffs_deflate__decoder__struct() = delete;
5480 wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = delete;
5481 wuffs_deflate__decoder__struct& operator=(
5482 const wuffs_deflate__decoder__struct&) = delete;
5483
5484 // As above, the size of the struct is not part of the public API, and unless
5485 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
5486 // allocated, not stack allocated. Its size is not intended to be known at
5487 // compile time, but it is unfortunately divulged as a side effect of
5488 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
5489 // instead of "sizeof T", invoking the operator. To make the two values
5490 // different, so that passing the latter will be rejected by the initialize
5491 // function, we add an arbitrary amount of dead weight.
5492 uint8_t dead_weight[123000000]; // 123 MB.
5493#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
5494
5495 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5496 initialize(
5497 size_t sizeof_star_self,
5498 uint64_t wuffs_version,
5499 uint32_t initialize_flags) {
5500 return wuffs_deflate__decoder__initialize(
5501 this, sizeof_star_self, wuffs_version, initialize_flags);
5502 }
5503
5504 inline wuffs_base__io_transformer*
5505 upcast_as__wuffs_base__io_transformer() {
5506 return (wuffs_base__io_transformer*)this;
5507 }
5508
5509 inline wuffs_base__empty_struct
5510 add_history(
5511 wuffs_base__slice_u8 a_hist) {
5512 return wuffs_deflate__decoder__add_history(this, a_hist);
5513 }
5514
5515 inline wuffs_base__empty_struct
5516 set_quirk_enabled(
5517 uint32_t a_quirk,
5518 bool a_enabled) {
5519 return wuffs_deflate__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
5520 }
5521
5522 inline wuffs_base__range_ii_u64
5523 workbuf_len() const {
5524 return wuffs_deflate__decoder__workbuf_len(this);
5525 }
5526
5527 inline wuffs_base__status
5528 transform_io(
5529 wuffs_base__io_buffer* a_dst,
5530 wuffs_base__io_buffer* a_src,
5531 wuffs_base__slice_u8 a_workbuf) {
5532 return wuffs_deflate__decoder__transform_io(this, a_dst, a_src, a_workbuf);
5533 }
5534
5535#endif // __cplusplus
5536}; // struct wuffs_deflate__decoder__struct
5537
5538#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5539
5540#ifdef __cplusplus
5541} // extern "C"
5542#endif
5543
5544#ifdef __cplusplus
5545extern "C" {
5546#endif
5547
5548// ---------------- Status Codes
5549
5550extern const char* wuffs_lzw__error__bad_code;
5551
5552// ---------------- Public Consts
5553
5554#define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
5555
5556// ---------------- Struct Declarations
5557
5558typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
5559
5560// ---------------- Public Initializer Prototypes
5561
5562// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
5563// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
5564//
5565// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
5566// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
5567
5568wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5569wuffs_lzw__decoder__initialize(
5570 wuffs_lzw__decoder* self,
5571 size_t sizeof_star_self,
5572 uint64_t wuffs_version,
5573 uint32_t initialize_flags);
5574
5575size_t
5576sizeof__wuffs_lzw__decoder();
5577
5578// ---------------- Allocs
5579
5580// These functions allocate and initialize Wuffs structs. They return NULL if
5581// memory allocation fails. If they return non-NULL, there is no need to call
5582// wuffs_foo__bar__initialize, but the caller is responsible for eventually
5583// calling free on the returned pointer. That pointer is effectively a C++
5584// std::unique_ptr<T, decltype(&free)>.
5585
5586wuffs_lzw__decoder*
5587wuffs_lzw__decoder__alloc();
5588
5589static inline wuffs_base__io_transformer*
5590wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer() {
5591 return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
5592}
5593
5594// ---------------- Upcasts
5595
5596static inline wuffs_base__io_transformer*
5597wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(
5598 wuffs_lzw__decoder* p) {
5599 return (wuffs_base__io_transformer*)p;
5600}
5601
5602// ---------------- Public Function Prototypes
5603
5604WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5605wuffs_lzw__decoder__set_quirk_enabled(
5606 wuffs_lzw__decoder* self,
5607 uint32_t a_quirk,
5608 bool a_enabled);
5609
5610WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5611wuffs_lzw__decoder__set_literal_width(
5612 wuffs_lzw__decoder* self,
5613 uint32_t a_lw);
5614
5615WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
5616wuffs_lzw__decoder__workbuf_len(
5617 const wuffs_lzw__decoder* self);
5618
5619WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5620wuffs_lzw__decoder__transform_io(
5621 wuffs_lzw__decoder* self,
5622 wuffs_base__io_buffer* a_dst,
5623 wuffs_base__io_buffer* a_src,
5624 wuffs_base__slice_u8 a_workbuf);
5625
5626WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
5627wuffs_lzw__decoder__flush(
5628 wuffs_lzw__decoder* self);
5629
5630// ---------------- Struct Definitions
5631
5632// These structs' fields, and the sizeof them, are private implementation
5633// details that aren't guaranteed to be stable across Wuffs versions.
5634//
5635// See https://en.wikipedia.org/wiki/Opaque_pointer#C
5636
5637#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5638
5639struct wuffs_lzw__decoder__struct {
5640 // Do not access the private_impl's or private_data's fields directly. There
5641 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
5642 // the wuffs_foo__bar__baz functions.
5643 //
5644 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
5645 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
5646
5647 struct {
5648 uint32_t magic;
5649 uint32_t active_coroutine;
5650 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
5651 wuffs_base__vtable null_vtable;
5652
5653 uint32_t f_set_literal_width_arg;
5654 uint32_t f_literal_width;
5655 uint32_t f_clear_code;
5656 uint32_t f_end_code;
5657 uint32_t f_save_code;
5658 uint32_t f_prev_code;
5659 uint32_t f_width;
5660 uint32_t f_bits;
5661 uint32_t f_n_bits;
5662 uint32_t f_output_ri;
5663 uint32_t f_output_wi;
5664 uint32_t f_read_from_return_value;
5665 uint16_t f_prefixes[4096];
5666
5667 uint32_t p_transform_io[1];
5668 uint32_t p_write_to[1];
5669 } private_impl;
5670
5671 struct {
5672 uint8_t f_suffixes[4096][8];
5673 uint16_t f_lm1s[4096];
5674 uint8_t f_output[8199];
5675 } private_data;
5676
5677#ifdef __cplusplus
5678#if (__cplusplus >= 201103L)
5679 using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, decltype(&free)>;
5680
5681 // On failure, the alloc_etc functions return nullptr. They don't throw.
5682
5683 static inline unique_ptr
5684 alloc() {
5685 return unique_ptr(wuffs_lzw__decoder__alloc(), &free);
5686 }
5687
5688 static inline wuffs_base__io_transformer::unique_ptr
5689 alloc_as__wuffs_base__io_transformer() {
5690 return wuffs_base__io_transformer::unique_ptr(
5691 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(), &free);
5692 }
5693#endif // (__cplusplus >= 201103L)
5694
5695#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
5696 // Disallow constructing or copying an object via standard C++ mechanisms,
5697 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
5698 // size and field layout is not part of the public, stable, memory-safe API.
5699 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
5700 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
5701 // their first argument) rather than tweaking bar.private_impl.qux fields.
5702 //
5703 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
5704 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
5705 // order to provide convenience methods. These forward on "this", so that you
5706 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
5707 wuffs_lzw__decoder__struct() = delete;
5708 wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
5709 wuffs_lzw__decoder__struct& operator=(
5710 const wuffs_lzw__decoder__struct&) = delete;
5711
5712 // As above, the size of the struct is not part of the public API, and unless
5713 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
5714 // allocated, not stack allocated. Its size is not intended to be known at
5715 // compile time, but it is unfortunately divulged as a side effect of
5716 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
5717 // instead of "sizeof T", invoking the operator. To make the two values
5718 // different, so that passing the latter will be rejected by the initialize
5719 // function, we add an arbitrary amount of dead weight.
5720 uint8_t dead_weight[123000000]; // 123 MB.
5721#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
5722
5723 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5724 initialize(
5725 size_t sizeof_star_self,
5726 uint64_t wuffs_version,
5727 uint32_t initialize_flags) {
5728 return wuffs_lzw__decoder__initialize(
5729 this, sizeof_star_self, wuffs_version, initialize_flags);
5730 }
5731
5732 inline wuffs_base__io_transformer*
5733 upcast_as__wuffs_base__io_transformer() {
5734 return (wuffs_base__io_transformer*)this;
5735 }
5736
5737 inline wuffs_base__empty_struct
5738 set_quirk_enabled(
5739 uint32_t a_quirk,
5740 bool a_enabled) {
5741 return wuffs_lzw__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
5742 }
5743
5744 inline wuffs_base__empty_struct
5745 set_literal_width(
5746 uint32_t a_lw) {
5747 return wuffs_lzw__decoder__set_literal_width(this, a_lw);
5748 }
5749
5750 inline wuffs_base__range_ii_u64
5751 workbuf_len() const {
5752 return wuffs_lzw__decoder__workbuf_len(this);
5753 }
5754
5755 inline wuffs_base__status
5756 transform_io(
5757 wuffs_base__io_buffer* a_dst,
5758 wuffs_base__io_buffer* a_src,
5759 wuffs_base__slice_u8 a_workbuf) {
5760 return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf);
5761 }
5762
5763 inline wuffs_base__slice_u8
5764 flush() {
5765 return wuffs_lzw__decoder__flush(this);
5766 }
5767
5768#endif // __cplusplus
5769}; // struct wuffs_lzw__decoder__struct
5770
5771#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5772
5773#ifdef __cplusplus
5774} // extern "C"
5775#endif
5776
5777#ifdef __cplusplus
5778extern "C" {
5779#endif
5780
5781// ---------------- Status Codes
5782
5783extern const char* wuffs_gif__error__bad_extension_label;
5784extern const char* wuffs_gif__error__bad_frame_size;
5785extern const char* wuffs_gif__error__bad_graphic_control;
5786extern const char* wuffs_gif__error__bad_header;
5787extern const char* wuffs_gif__error__bad_literal_width;
5788extern const char* wuffs_gif__error__bad_palette;
5789
5790// ---------------- Public Consts
5791
5792#define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
5793
5794#define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328
5795
5796#define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329
5797
5798#define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330
5799
5800#define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331
5801
5802#define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332
5803
5804#define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333
5805
5806#define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334
5807
5808// ---------------- Struct Declarations
5809
5810typedef struct wuffs_gif__config_decoder__struct wuffs_gif__config_decoder;
5811
5812typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder;
5813
5814// ---------------- Public Initializer Prototypes
5815
5816// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
5817// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
5818//
5819// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
5820// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
5821
5822wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5823wuffs_gif__config_decoder__initialize(
5824 wuffs_gif__config_decoder* self,
5825 size_t sizeof_star_self,
5826 uint64_t wuffs_version,
5827 uint32_t initialize_flags);
5828
5829size_t
5830sizeof__wuffs_gif__config_decoder();
5831
5832wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
5833wuffs_gif__decoder__initialize(
5834 wuffs_gif__decoder* self,
5835 size_t sizeof_star_self,
5836 uint64_t wuffs_version,
5837 uint32_t initialize_flags);
5838
5839size_t
5840sizeof__wuffs_gif__decoder();
5841
5842// ---------------- Allocs
5843
5844// These functions allocate and initialize Wuffs structs. They return NULL if
5845// memory allocation fails. If they return non-NULL, there is no need to call
5846// wuffs_foo__bar__initialize, but the caller is responsible for eventually
5847// calling free on the returned pointer. That pointer is effectively a C++
5848// std::unique_ptr<T, decltype(&free)>.
5849
5850wuffs_gif__config_decoder*
5851wuffs_gif__config_decoder__alloc();
5852
5853static inline wuffs_base__image_decoder*
5854wuffs_gif__config_decoder__alloc_as__wuffs_base__image_decoder() {
5855 return (wuffs_base__image_decoder*)(wuffs_gif__config_decoder__alloc());
5856}
5857
5858wuffs_gif__decoder*
5859wuffs_gif__decoder__alloc();
5860
5861static inline wuffs_base__image_decoder*
5862wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder() {
5863 return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
5864}
5865
5866// ---------------- Upcasts
5867
5868static inline wuffs_base__image_decoder*
5869wuffs_gif__config_decoder__upcast_as__wuffs_base__image_decoder(
5870 wuffs_gif__config_decoder* p) {
5871 return (wuffs_base__image_decoder*)p;
5872}
5873
5874static inline wuffs_base__image_decoder*
5875wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
5876 wuffs_gif__decoder* p) {
5877 return (wuffs_base__image_decoder*)p;
5878}
5879
5880// ---------------- Public Function Prototypes
5881
5882WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5883wuffs_gif__config_decoder__set_quirk_enabled(
5884 wuffs_gif__config_decoder* self,
5885 uint32_t a_quirk,
5886 bool a_enabled);
5887
5888WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5889wuffs_gif__config_decoder__decode_image_config(
5890 wuffs_gif__config_decoder* self,
5891 wuffs_base__image_config* a_dst,
5892 wuffs_base__io_buffer* a_src);
5893
5894WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5895wuffs_gif__config_decoder__set_report_metadata(
5896 wuffs_gif__config_decoder* self,
5897 uint32_t a_fourcc,
5898 bool a_report);
5899
5900WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5901wuffs_gif__config_decoder__tell_me_more(
5902 wuffs_gif__config_decoder* self,
5903 wuffs_base__io_buffer* a_dst,
5904 wuffs_base__more_information* a_minfo,
5905 wuffs_base__io_buffer* a_src);
5906
5907WUFFS_BASE__MAYBE_STATIC uint32_t
5908wuffs_gif__config_decoder__num_animation_loops(
5909 const wuffs_gif__config_decoder* self);
5910
5911WUFFS_BASE__MAYBE_STATIC uint64_t
5912wuffs_gif__config_decoder__num_decoded_frame_configs(
5913 const wuffs_gif__config_decoder* self);
5914
5915WUFFS_BASE__MAYBE_STATIC uint64_t
5916wuffs_gif__config_decoder__num_decoded_frames(
5917 const wuffs_gif__config_decoder* self);
5918
5919WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
5920wuffs_gif__config_decoder__frame_dirty_rect(
5921 const wuffs_gif__config_decoder* self);
5922
5923WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
5924wuffs_gif__config_decoder__workbuf_len(
5925 const wuffs_gif__config_decoder* self);
5926
5927WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5928wuffs_gif__config_decoder__restart_frame(
5929 wuffs_gif__config_decoder* self,
5930 uint64_t a_index,
5931 uint64_t a_io_position);
5932
5933WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5934wuffs_gif__config_decoder__decode_frame_config(
5935 wuffs_gif__config_decoder* self,
5936 wuffs_base__frame_config* a_dst,
5937 wuffs_base__io_buffer* a_src);
5938
5939WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5940wuffs_gif__config_decoder__decode_frame(
5941 wuffs_gif__config_decoder* self,
5942 wuffs_base__pixel_buffer* a_dst,
5943 wuffs_base__io_buffer* a_src,
5944 wuffs_base__pixel_blend a_blend,
5945 wuffs_base__slice_u8 a_workbuf,
5946 wuffs_base__decode_frame_options* a_opts);
5947
5948WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5949wuffs_gif__decoder__set_quirk_enabled(
5950 wuffs_gif__decoder* self,
5951 uint32_t a_quirk,
5952 bool a_enabled);
5953
5954WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5955wuffs_gif__decoder__decode_image_config(
5956 wuffs_gif__decoder* self,
5957 wuffs_base__image_config* a_dst,
5958 wuffs_base__io_buffer* a_src);
5959
5960WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5961wuffs_gif__decoder__set_report_metadata(
5962 wuffs_gif__decoder* self,
5963 uint32_t a_fourcc,
5964 bool a_report);
5965
5966WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5967wuffs_gif__decoder__tell_me_more(
5968 wuffs_gif__decoder* self,
5969 wuffs_base__io_buffer* a_dst,
5970 wuffs_base__more_information* a_minfo,
5971 wuffs_base__io_buffer* a_src);
5972
5973WUFFS_BASE__MAYBE_STATIC uint32_t
5974wuffs_gif__decoder__num_animation_loops(
5975 const wuffs_gif__decoder* self);
5976
5977WUFFS_BASE__MAYBE_STATIC uint64_t
5978wuffs_gif__decoder__num_decoded_frame_configs(
5979 const wuffs_gif__decoder* self);
5980
5981WUFFS_BASE__MAYBE_STATIC uint64_t
5982wuffs_gif__decoder__num_decoded_frames(
5983 const wuffs_gif__decoder* self);
5984
5985WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
5986wuffs_gif__decoder__frame_dirty_rect(
5987 const wuffs_gif__decoder* self);
5988
5989WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
5990wuffs_gif__decoder__workbuf_len(
5991 const wuffs_gif__decoder* self);
5992
5993WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5994wuffs_gif__decoder__restart_frame(
5995 wuffs_gif__decoder* self,
5996 uint64_t a_index,
5997 uint64_t a_io_position);
5998
5999WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6000wuffs_gif__decoder__decode_frame_config(
6001 wuffs_gif__decoder* self,
6002 wuffs_base__frame_config* a_dst,
6003 wuffs_base__io_buffer* a_src);
6004
6005WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6006wuffs_gif__decoder__decode_frame(
6007 wuffs_gif__decoder* self,
6008 wuffs_base__pixel_buffer* a_dst,
6009 wuffs_base__io_buffer* a_src,
6010 wuffs_base__pixel_blend a_blend,
6011 wuffs_base__slice_u8 a_workbuf,
6012 wuffs_base__decode_frame_options* a_opts);
6013
6014// ---------------- Struct Definitions
6015
6016// These structs' fields, and the sizeof them, are private implementation
6017// details that aren't guaranteed to be stable across Wuffs versions.
6018//
6019// See https://en.wikipedia.org/wiki/Opaque_pointer#C
6020
6021#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6022
6023struct wuffs_gif__config_decoder__struct {
6024 // Do not access the private_impl's or private_data's fields directly. There
6025 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6026 // the wuffs_foo__bar__baz functions.
6027 //
6028 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6029 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6030
6031 struct {
6032 uint32_t magic;
6033 uint32_t active_coroutine;
6034 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
6035 wuffs_base__vtable null_vtable;
6036
6037 uint32_t f_width;
6038 uint32_t f_height;
6039 uint8_t f_call_sequence;
6040 bool f_ignore_metadata;
6041 bool f_report_metadata_iccp;
6042 bool f_report_metadata_xmp;
6043 uint32_t f_metadata_fourcc;
6044 uint64_t f_metadata_io_position;
6045 bool f_quirks[7];
6046 bool f_delayed_num_decoded_frames;
6047 bool f_end_of_data;
6048 bool f_restarted;
6049 bool f_previous_lzw_decode_ended_abruptly;
6050 bool f_has_global_palette;
6051 uint8_t f_interlace;
6052 bool f_seen_num_loops;
6053 uint32_t f_num_loops;
6054 uint32_t f_background_color_u32_argb_premul;
6055 uint32_t f_black_color_u32_argb_premul;
6056 bool f_gc_has_transparent_index;
6057 uint8_t f_gc_transparent_index;
6058 uint8_t f_gc_disposal;
6059 uint64_t f_gc_duration;
6060 uint64_t f_frame_config_io_position;
6061 uint64_t f_num_decoded_frame_configs_value;
6062 uint64_t f_num_decoded_frames_value;
6063 uint32_t f_frame_rect_x0;
6064 uint32_t f_frame_rect_y0;
6065 uint32_t f_frame_rect_x1;
6066 uint32_t f_frame_rect_y1;
6067
6068 uint32_t p_decode_image_config[1];
6069 uint32_t p_tell_me_more[1];
6070 uint32_t p_decode_frame_config[1];
6071 uint32_t p_skip_frame[1];
6072 uint32_t p_decode_up_to_id_part1[1];
6073 uint32_t p_decode_header[1];
6074 uint32_t p_decode_lsd[1];
6075 uint32_t p_decode_extension[1];
6076 uint32_t p_skip_blocks[1];
6077 uint32_t p_decode_ae[1];
6078 uint32_t p_decode_gc[1];
6079 uint32_t p_decode_id_part0[1];
6080 } private_impl;
6081
6082 struct {
6083 uint8_t f_palettes[1][1024];
6084
6085 struct {
6086 uint32_t v_background_color;
6087 } s_decode_frame_config[1];
6088 struct {
6089 uint64_t scratch;
6090 } s_skip_frame[1];
6091 struct {
6092 uint8_t v_c[6];
6093 uint32_t v_i;
6094 } s_decode_header[1];
6095 struct {
6096 uint8_t v_flags;
6097 uint8_t v_background_color_index;
6098 uint32_t v_num_palette_entries;
6099 uint32_t v_i;
6100 uint64_t scratch;
6101 } s_decode_lsd[1];
6102 struct {
6103 uint64_t scratch;
6104 } s_skip_blocks[1];
6105 struct {
6106 uint8_t v_block_size;
6107 bool v_is_animexts;
6108 bool v_is_netscape;
6109 bool v_is_iccp;
6110 bool v_is_xmp;
6111 uint64_t scratch;
6112 } s_decode_ae[1];
6113 struct {
6114 uint64_t scratch;
6115 } s_decode_gc[1];
6116 struct {
6117 uint64_t scratch;
6118 } s_decode_id_part0[1];
6119 } private_data;
6120
6121#ifdef __cplusplus
6122#if (__cplusplus >= 201103L)
6123 using unique_ptr = std::unique_ptr<wuffs_gif__config_decoder, decltype(&free)>;
6124
6125 // On failure, the alloc_etc functions return nullptr. They don't throw.
6126
6127 static inline unique_ptr
6128 alloc() {
6129 return unique_ptr(wuffs_gif__config_decoder__alloc(), &free);
6130 }
6131
6132 static inline wuffs_base__image_decoder::unique_ptr
6133 alloc_as__wuffs_base__image_decoder() {
6134 return wuffs_base__image_decoder::unique_ptr(
6135 wuffs_gif__config_decoder__alloc_as__wuffs_base__image_decoder(), &free);
6136 }
6137#endif // (__cplusplus >= 201103L)
6138
6139#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6140 // Disallow constructing or copying an object via standard C++ mechanisms,
6141 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6142 // size and field layout is not part of the public, stable, memory-safe API.
6143 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6144 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6145 // their first argument) rather than tweaking bar.private_impl.qux fields.
6146 //
6147 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6148 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6149 // order to provide convenience methods. These forward on "this", so that you
6150 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6151 wuffs_gif__config_decoder__struct() = delete;
6152 wuffs_gif__config_decoder__struct(const wuffs_gif__config_decoder__struct&) = delete;
6153 wuffs_gif__config_decoder__struct& operator=(
6154 const wuffs_gif__config_decoder__struct&) = delete;
6155
6156 // As above, the size of the struct is not part of the public API, and unless
6157 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6158 // allocated, not stack allocated. Its size is not intended to be known at
6159 // compile time, but it is unfortunately divulged as a side effect of
6160 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6161 // instead of "sizeof T", invoking the operator. To make the two values
6162 // different, so that passing the latter will be rejected by the initialize
6163 // function, we add an arbitrary amount of dead weight.
6164 uint8_t dead_weight[123000000]; // 123 MB.
6165#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6166
6167 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6168 initialize(
6169 size_t sizeof_star_self,
6170 uint64_t wuffs_version,
6171 uint32_t initialize_flags) {
6172 return wuffs_gif__config_decoder__initialize(
6173 this, sizeof_star_self, wuffs_version, initialize_flags);
6174 }
6175
6176 inline wuffs_base__image_decoder*
6177 upcast_as__wuffs_base__image_decoder() {
6178 return (wuffs_base__image_decoder*)this;
6179 }
6180
6181 inline wuffs_base__empty_struct
6182 set_quirk_enabled(
6183 uint32_t a_quirk,
6184 bool a_enabled) {
6185 return wuffs_gif__config_decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6186 }
6187
6188 inline wuffs_base__status
6189 decode_image_config(
6190 wuffs_base__image_config* a_dst,
6191 wuffs_base__io_buffer* a_src) {
6192 return wuffs_gif__config_decoder__decode_image_config(this, a_dst, a_src);
6193 }
6194
6195 inline wuffs_base__empty_struct
6196 set_report_metadata(
6197 uint32_t a_fourcc,
6198 bool a_report) {
6199 return wuffs_gif__config_decoder__set_report_metadata(this, a_fourcc, a_report);
6200 }
6201
6202 inline wuffs_base__status
6203 tell_me_more(
6204 wuffs_base__io_buffer* a_dst,
6205 wuffs_base__more_information* a_minfo,
6206 wuffs_base__io_buffer* a_src) {
6207 return wuffs_gif__config_decoder__tell_me_more(this, a_dst, a_minfo, a_src);
6208 }
6209
6210 inline uint32_t
6211 num_animation_loops() const {
6212 return wuffs_gif__config_decoder__num_animation_loops(this);
6213 }
6214
6215 inline uint64_t
6216 num_decoded_frame_configs() const {
6217 return wuffs_gif__config_decoder__num_decoded_frame_configs(this);
6218 }
6219
6220 inline uint64_t
6221 num_decoded_frames() const {
6222 return wuffs_gif__config_decoder__num_decoded_frames(this);
6223 }
6224
6225 inline wuffs_base__rect_ie_u32
6226 frame_dirty_rect() const {
6227 return wuffs_gif__config_decoder__frame_dirty_rect(this);
6228 }
6229
6230 inline wuffs_base__range_ii_u64
6231 workbuf_len() const {
6232 return wuffs_gif__config_decoder__workbuf_len(this);
6233 }
6234
6235 inline wuffs_base__status
6236 restart_frame(
6237 uint64_t a_index,
6238 uint64_t a_io_position) {
6239 return wuffs_gif__config_decoder__restart_frame(this, a_index, a_io_position);
6240 }
6241
6242 inline wuffs_base__status
6243 decode_frame_config(
6244 wuffs_base__frame_config* a_dst,
6245 wuffs_base__io_buffer* a_src) {
6246 return wuffs_gif__config_decoder__decode_frame_config(this, a_dst, a_src);
6247 }
6248
6249 inline wuffs_base__status
6250 decode_frame(
6251 wuffs_base__pixel_buffer* a_dst,
6252 wuffs_base__io_buffer* a_src,
6253 wuffs_base__pixel_blend a_blend,
6254 wuffs_base__slice_u8 a_workbuf,
6255 wuffs_base__decode_frame_options* a_opts) {
6256 return wuffs_gif__config_decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6257 }
6258
6259#endif // __cplusplus
6260}; // struct wuffs_gif__config_decoder__struct
6261
6262struct wuffs_gif__decoder__struct {
6263 // Do not access the private_impl's or private_data's fields directly. There
6264 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6265 // the wuffs_foo__bar__baz functions.
6266 //
6267 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6268 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6269
6270 struct {
6271 uint32_t magic;
6272 uint32_t active_coroutine;
6273 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
6274 wuffs_base__vtable null_vtable;
6275
6276 uint32_t f_width;
6277 uint32_t f_height;
6278 uint8_t f_call_sequence;
6279 bool f_ignore_metadata;
6280 bool f_report_metadata_iccp;
6281 bool f_report_metadata_xmp;
6282 uint32_t f_metadata_fourcc;
6283 uint64_t f_metadata_io_position;
6284 bool f_quirks[7];
6285 bool f_delayed_num_decoded_frames;
6286 bool f_end_of_data;
6287 bool f_restarted;
6288 bool f_previous_lzw_decode_ended_abruptly;
6289 bool f_has_global_palette;
6290 uint8_t f_interlace;
6291 bool f_seen_num_loops;
6292 uint32_t f_num_loops;
6293 uint32_t f_background_color_u32_argb_premul;
6294 uint32_t f_black_color_u32_argb_premul;
6295 bool f_gc_has_transparent_index;
6296 uint8_t f_gc_transparent_index;
6297 uint8_t f_gc_disposal;
6298 uint64_t f_gc_duration;
6299 uint64_t f_frame_config_io_position;
6300 uint64_t f_num_decoded_frame_configs_value;
6301 uint64_t f_num_decoded_frames_value;
6302 uint32_t f_frame_rect_x0;
6303 uint32_t f_frame_rect_y0;
6304 uint32_t f_frame_rect_x1;
6305 uint32_t f_frame_rect_y1;
6306 uint32_t f_dst_x;
6307 uint32_t f_dst_y;
6308 uint32_t f_dirty_max_excl_y;
6309 uint64_t f_compressed_ri;
6310 uint64_t f_compressed_wi;
6311 wuffs_base__pixel_swizzler f_swizzler;
6312
6313 uint32_t p_decode_image_config[1];
6314 uint32_t p_tell_me_more[1];
6315 uint32_t p_decode_frame_config[1];
6316 uint32_t p_skip_frame[1];
6317 uint32_t p_decode_frame[1];
6318 uint32_t p_decode_up_to_id_part1[1];
6319 uint32_t p_decode_header[1];
6320 uint32_t p_decode_lsd[1];
6321 uint32_t p_decode_extension[1];
6322 uint32_t p_skip_blocks[1];
6323 uint32_t p_decode_ae[1];
6324 uint32_t p_decode_gc[1];
6325 uint32_t p_decode_id_part0[1];
6326 uint32_t p_decode_id_part1[1];
6327 uint32_t p_decode_id_part2[1];
6328 } private_impl;
6329
6330 struct {
6331 uint8_t f_compressed[4096];
6332 uint8_t f_palettes[2][1024];
6333 uint8_t f_dst_palette[1024];
6334 wuffs_lzw__decoder f_lzw;
6335
6336 struct {
6337 uint32_t v_background_color;
6338 } s_decode_frame_config[1];
6339 struct {
6340 uint64_t scratch;
6341 } s_skip_frame[1];
6342 struct {
6343 uint8_t v_c[6];
6344 uint32_t v_i;
6345 } s_decode_header[1];
6346 struct {
6347 uint8_t v_flags;
6348 uint8_t v_background_color_index;
6349 uint32_t v_num_palette_entries;
6350 uint32_t v_i;
6351 uint64_t scratch;
6352 } s_decode_lsd[1];
6353 struct {
6354 uint64_t scratch;
6355 } s_skip_blocks[1];
6356 struct {
6357 uint8_t v_block_size;
6358 bool v_is_animexts;
6359 bool v_is_netscape;
6360 bool v_is_iccp;
6361 bool v_is_xmp;
6362 uint64_t scratch;
6363 } s_decode_ae[1];
6364 struct {
6365 uint64_t scratch;
6366 } s_decode_gc[1];
6367 struct {
6368 uint64_t scratch;
6369 } s_decode_id_part0[1];
6370 struct {
6371 uint8_t v_which_palette;
6372 uint32_t v_num_palette_entries;
6373 uint32_t v_i;
6374 uint64_t scratch;
6375 } s_decode_id_part1[1];
6376 struct {
6377 uint64_t v_block_size;
6378 bool v_need_block_size;
6379 wuffs_base__status v_lzw_status;
6380 uint64_t scratch;
6381 } s_decode_id_part2[1];
6382 } private_data;
6383
6384#ifdef __cplusplus
6385#if (__cplusplus >= 201103L)
6386 using unique_ptr = std::unique_ptr<wuffs_gif__decoder, decltype(&free)>;
6387
6388 // On failure, the alloc_etc functions return nullptr. They don't throw.
6389
6390 static inline unique_ptr
6391 alloc() {
6392 return unique_ptr(wuffs_gif__decoder__alloc(), &free);
6393 }
6394
6395 static inline wuffs_base__image_decoder::unique_ptr
6396 alloc_as__wuffs_base__image_decoder() {
6397 return wuffs_base__image_decoder::unique_ptr(
6398 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(), &free);
6399 }
6400#endif // (__cplusplus >= 201103L)
6401
6402#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6403 // Disallow constructing or copying an object via standard C++ mechanisms,
6404 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6405 // size and field layout is not part of the public, stable, memory-safe API.
6406 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6407 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6408 // their first argument) rather than tweaking bar.private_impl.qux fields.
6409 //
6410 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6411 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6412 // order to provide convenience methods. These forward on "this", so that you
6413 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6414 wuffs_gif__decoder__struct() = delete;
6415 wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
6416 wuffs_gif__decoder__struct& operator=(
6417 const wuffs_gif__decoder__struct&) = delete;
6418
6419 // As above, the size of the struct is not part of the public API, and unless
6420 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6421 // allocated, not stack allocated. Its size is not intended to be known at
6422 // compile time, but it is unfortunately divulged as a side effect of
6423 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6424 // instead of "sizeof T", invoking the operator. To make the two values
6425 // different, so that passing the latter will be rejected by the initialize
6426 // function, we add an arbitrary amount of dead weight.
6427 uint8_t dead_weight[123000000]; // 123 MB.
6428#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6429
6430 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6431 initialize(
6432 size_t sizeof_star_self,
6433 uint64_t wuffs_version,
6434 uint32_t initialize_flags) {
6435 return wuffs_gif__decoder__initialize(
6436 this, sizeof_star_self, wuffs_version, initialize_flags);
6437 }
6438
6439 inline wuffs_base__image_decoder*
6440 upcast_as__wuffs_base__image_decoder() {
6441 return (wuffs_base__image_decoder*)this;
6442 }
6443
6444 inline wuffs_base__empty_struct
6445 set_quirk_enabled(
6446 uint32_t a_quirk,
6447 bool a_enabled) {
6448 return wuffs_gif__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6449 }
6450
6451 inline wuffs_base__status
6452 decode_image_config(
6453 wuffs_base__image_config* a_dst,
6454 wuffs_base__io_buffer* a_src) {
6455 return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
6456 }
6457
6458 inline wuffs_base__empty_struct
6459 set_report_metadata(
6460 uint32_t a_fourcc,
6461 bool a_report) {
6462 return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
6463 }
6464
6465 inline wuffs_base__status
6466 tell_me_more(
6467 wuffs_base__io_buffer* a_dst,
6468 wuffs_base__more_information* a_minfo,
6469 wuffs_base__io_buffer* a_src) {
6470 return wuffs_gif__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
6471 }
6472
6473 inline uint32_t
6474 num_animation_loops() const {
6475 return wuffs_gif__decoder__num_animation_loops(this);
6476 }
6477
6478 inline uint64_t
6479 num_decoded_frame_configs() const {
6480 return wuffs_gif__decoder__num_decoded_frame_configs(this);
6481 }
6482
6483 inline uint64_t
6484 num_decoded_frames() const {
6485 return wuffs_gif__decoder__num_decoded_frames(this);
6486 }
6487
6488 inline wuffs_base__rect_ie_u32
6489 frame_dirty_rect() const {
6490 return wuffs_gif__decoder__frame_dirty_rect(this);
6491 }
6492
6493 inline wuffs_base__range_ii_u64
6494 workbuf_len() const {
6495 return wuffs_gif__decoder__workbuf_len(this);
6496 }
6497
6498 inline wuffs_base__status
6499 restart_frame(
6500 uint64_t a_index,
6501 uint64_t a_io_position) {
6502 return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
6503 }
6504
6505 inline wuffs_base__status
6506 decode_frame_config(
6507 wuffs_base__frame_config* a_dst,
6508 wuffs_base__io_buffer* a_src) {
6509 return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
6510 }
6511
6512 inline wuffs_base__status
6513 decode_frame(
6514 wuffs_base__pixel_buffer* a_dst,
6515 wuffs_base__io_buffer* a_src,
6516 wuffs_base__pixel_blend a_blend,
6517 wuffs_base__slice_u8 a_workbuf,
6518 wuffs_base__decode_frame_options* a_opts) {
6519 return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6520 }
6521
6522#endif // __cplusplus
6523}; // struct wuffs_gif__decoder__struct
6524
6525#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6526
6527#ifdef __cplusplus
6528} // extern "C"
6529#endif
6530
6531#ifdef __cplusplus
6532extern "C" {
6533#endif
6534
6535// ---------------- Status Codes
6536
6537extern const char* wuffs_gzip__error__bad_checksum;
6538extern const char* wuffs_gzip__error__bad_compression_method;
6539extern const char* wuffs_gzip__error__bad_encoding_flags;
6540extern const char* wuffs_gzip__error__bad_header;
6541
6542// ---------------- Public Consts
6543
6544#define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
6545
6546// ---------------- Struct Declarations
6547
6548typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
6549
6550// ---------------- Public Initializer Prototypes
6551
6552// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6553// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6554//
6555// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6556// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
6557
6558wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6559wuffs_gzip__decoder__initialize(
6560 wuffs_gzip__decoder* self,
6561 size_t sizeof_star_self,
6562 uint64_t wuffs_version,
6563 uint32_t initialize_flags);
6564
6565size_t
6566sizeof__wuffs_gzip__decoder();
6567
6568// ---------------- Allocs
6569
6570// These functions allocate and initialize Wuffs structs. They return NULL if
6571// memory allocation fails. If they return non-NULL, there is no need to call
6572// wuffs_foo__bar__initialize, but the caller is responsible for eventually
6573// calling free on the returned pointer. That pointer is effectively a C++
6574// std::unique_ptr<T, decltype(&free)>.
6575
6576wuffs_gzip__decoder*
6577wuffs_gzip__decoder__alloc();
6578
6579static inline wuffs_base__io_transformer*
6580wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer() {
6581 return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
6582}
6583
6584// ---------------- Upcasts
6585
6586static inline wuffs_base__io_transformer*
6587wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(
6588 wuffs_gzip__decoder* p) {
6589 return (wuffs_base__io_transformer*)p;
6590}
6591
6592// ---------------- Public Function Prototypes
6593
6594WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6595wuffs_gzip__decoder__set_ignore_checksum(
6596 wuffs_gzip__decoder* self,
6597 bool a_ic);
6598
6599WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6600wuffs_gzip__decoder__set_quirk_enabled(
6601 wuffs_gzip__decoder* self,
6602 uint32_t a_quirk,
6603 bool a_enabled);
6604
6605WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6606wuffs_gzip__decoder__workbuf_len(
6607 const wuffs_gzip__decoder* self);
6608
6609WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6610wuffs_gzip__decoder__transform_io(
6611 wuffs_gzip__decoder* self,
6612 wuffs_base__io_buffer* a_dst,
6613 wuffs_base__io_buffer* a_src,
6614 wuffs_base__slice_u8 a_workbuf);
6615
6616// ---------------- Struct Definitions
6617
6618// These structs' fields, and the sizeof them, are private implementation
6619// details that aren't guaranteed to be stable across Wuffs versions.
6620//
6621// See https://en.wikipedia.org/wiki/Opaque_pointer#C
6622
6623#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6624
6625struct wuffs_gzip__decoder__struct {
6626 // Do not access the private_impl's or private_data's fields directly. There
6627 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6628 // the wuffs_foo__bar__baz functions.
6629 //
6630 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6631 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6632
6633 struct {
6634 uint32_t magic;
6635 uint32_t active_coroutine;
6636 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
6637 wuffs_base__vtable null_vtable;
6638
6639 bool f_ignore_checksum;
6640
6641 uint32_t p_transform_io[1];
6642 } private_impl;
6643
6644 struct {
6645 wuffs_crc32__ieee_hasher f_checksum;
6646 wuffs_deflate__decoder f_flate;
6647
6648 struct {
6649 uint8_t v_flags;
6650 uint32_t v_checksum_got;
6651 uint32_t v_decoded_length_got;
6652 uint32_t v_checksum_want;
6653 uint64_t scratch;
6654 } s_transform_io[1];
6655 } private_data;
6656
6657#ifdef __cplusplus
6658#if (__cplusplus >= 201103L)
6659 using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, decltype(&free)>;
6660
6661 // On failure, the alloc_etc functions return nullptr. They don't throw.
6662
6663 static inline unique_ptr
6664 alloc() {
6665 return unique_ptr(wuffs_gzip__decoder__alloc(), &free);
6666 }
6667
6668 static inline wuffs_base__io_transformer::unique_ptr
6669 alloc_as__wuffs_base__io_transformer() {
6670 return wuffs_base__io_transformer::unique_ptr(
6671 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(), &free);
6672 }
6673#endif // (__cplusplus >= 201103L)
6674
6675#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6676 // Disallow constructing or copying an object via standard C++ mechanisms,
6677 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6678 // size and field layout is not part of the public, stable, memory-safe API.
6679 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6680 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6681 // their first argument) rather than tweaking bar.private_impl.qux fields.
6682 //
6683 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6684 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6685 // order to provide convenience methods. These forward on "this", so that you
6686 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6687 wuffs_gzip__decoder__struct() = delete;
6688 wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
6689 wuffs_gzip__decoder__struct& operator=(
6690 const wuffs_gzip__decoder__struct&) = delete;
6691
6692 // As above, the size of the struct is not part of the public API, and unless
6693 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6694 // allocated, not stack allocated. Its size is not intended to be known at
6695 // compile time, but it is unfortunately divulged as a side effect of
6696 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6697 // instead of "sizeof T", invoking the operator. To make the two values
6698 // different, so that passing the latter will be rejected by the initialize
6699 // function, we add an arbitrary amount of dead weight.
6700 uint8_t dead_weight[123000000]; // 123 MB.
6701#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6702
6703 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6704 initialize(
6705 size_t sizeof_star_self,
6706 uint64_t wuffs_version,
6707 uint32_t initialize_flags) {
6708 return wuffs_gzip__decoder__initialize(
6709 this, sizeof_star_self, wuffs_version, initialize_flags);
6710 }
6711
6712 inline wuffs_base__io_transformer*
6713 upcast_as__wuffs_base__io_transformer() {
6714 return (wuffs_base__io_transformer*)this;
6715 }
6716
6717 inline wuffs_base__empty_struct
6718 set_ignore_checksum(
6719 bool a_ic) {
6720 return wuffs_gzip__decoder__set_ignore_checksum(this, a_ic);
6721 }
6722
6723 inline wuffs_base__empty_struct
6724 set_quirk_enabled(
6725 uint32_t a_quirk,
6726 bool a_enabled) {
6727 return wuffs_gzip__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6728 }
6729
6730 inline wuffs_base__range_ii_u64
6731 workbuf_len() const {
6732 return wuffs_gzip__decoder__workbuf_len(this);
6733 }
6734
6735 inline wuffs_base__status
6736 transform_io(
6737 wuffs_base__io_buffer* a_dst,
6738 wuffs_base__io_buffer* a_src,
6739 wuffs_base__slice_u8 a_workbuf) {
6740 return wuffs_gzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
6741 }
6742
6743#endif // __cplusplus
6744}; // struct wuffs_gzip__decoder__struct
6745
6746#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6747
6748#ifdef __cplusplus
6749} // extern "C"
6750#endif
6751
6752#ifdef __cplusplus
6753extern "C" {
6754#endif
6755
6756// ---------------- Status Codes
6757
6758extern const char* wuffs_json__error__bad_c0_control_code;
6759extern const char* wuffs_json__error__bad_utf_8;
6760extern const char* wuffs_json__error__bad_backslash_escape;
6761extern const char* wuffs_json__error__bad_input;
6762extern const char* wuffs_json__error__unsupported_number_length;
6763extern const char* wuffs_json__error__unsupported_recursion_depth;
6764
6765// ---------------- Public Consts
6766
6767#define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6768
6769#define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024
6770
6771#define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1
6772
6773#define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100
6774
6775#define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480
6776
6777#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481
6778
6779#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482
6780
6781#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483
6782
6783#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484
6784
6785#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485
6786
6787#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486
6788
6789#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487
6790
6791#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X 1225364488
6792
6793#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364489
6794
6795#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364490
6796
6797#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364491
6798
6799#define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364492
6800
6801#define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364493
6802
6803#define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364494
6804
6805#define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364495
6806
6807#define WUFFS_JSON__QUIRK_ALLOW_TRAILING_NEW_LINE 1225364496
6808
6809#define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364497
6810
6811// ---------------- Struct Declarations
6812
6813typedef struct wuffs_json__decoder__struct wuffs_json__decoder;
6814
6815// ---------------- Public Initializer Prototypes
6816
6817// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6818// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6819//
6820// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6821// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
6822
6823wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6824wuffs_json__decoder__initialize(
6825 wuffs_json__decoder* self,
6826 size_t sizeof_star_self,
6827 uint64_t wuffs_version,
6828 uint32_t initialize_flags);
6829
6830size_t
6831sizeof__wuffs_json__decoder();
6832
6833// ---------------- Allocs
6834
6835// These functions allocate and initialize Wuffs structs. They return NULL if
6836// memory allocation fails. If they return non-NULL, there is no need to call
6837// wuffs_foo__bar__initialize, but the caller is responsible for eventually
6838// calling free on the returned pointer. That pointer is effectively a C++
6839// std::unique_ptr<T, decltype(&free)>.
6840
6841wuffs_json__decoder*
6842wuffs_json__decoder__alloc();
6843
6844static inline wuffs_base__token_decoder*
6845wuffs_json__decoder__alloc_as__wuffs_base__token_decoder() {
6846 return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
6847}
6848
6849// ---------------- Upcasts
6850
6851static inline wuffs_base__token_decoder*
6852wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
6853 wuffs_json__decoder* p) {
6854 return (wuffs_base__token_decoder*)p;
6855}
6856
6857// ---------------- Public Function Prototypes
6858
6859WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6860wuffs_json__decoder__set_quirk_enabled(
6861 wuffs_json__decoder* self,
6862 uint32_t a_quirk,
6863 bool a_enabled);
6864
6865WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6866wuffs_json__decoder__workbuf_len(
6867 const wuffs_json__decoder* self);
6868
6869WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6870wuffs_json__decoder__decode_tokens(
6871 wuffs_json__decoder* self,
6872 wuffs_base__token_buffer* a_dst,
6873 wuffs_base__io_buffer* a_src,
6874 wuffs_base__slice_u8 a_workbuf);
6875
6876// ---------------- Struct Definitions
6877
6878// These structs' fields, and the sizeof them, are private implementation
6879// details that aren't guaranteed to be stable across Wuffs versions.
6880//
6881// See https://en.wikipedia.org/wiki/Opaque_pointer#C
6882
6883#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6884
6885struct wuffs_json__decoder__struct {
6886 // Do not access the private_impl's or private_data's fields directly. There
6887 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6888 // the wuffs_foo__bar__baz functions.
6889 //
6890 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6891 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6892
6893 struct {
6894 uint32_t magic;
6895 uint32_t active_coroutine;
6896 wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
6897 wuffs_base__vtable null_vtable;
6898
6899 bool f_quirks[18];
6900 bool f_allow_leading_ars;
6901 bool f_allow_leading_ubom;
6902 bool f_end_of_data;
6903
6904 uint32_t p_decode_tokens[1];
6905 uint32_t p_decode_leading[1];
6906 uint32_t p_decode_comment[1];
6907 uint32_t p_decode_inf_nan[1];
6908 uint32_t p_decode_trailing_new_line[1];
6909 } private_impl;
6910
6911 struct {
6912 uint32_t f_stack[32];
6913
6914 struct {
6915 uint32_t v_depth;
6916 uint32_t v_expect;
6917 uint32_t v_expect_after_value;
6918 } s_decode_tokens[1];
6919 struct {
6920 uint32_t v_neg;
6921 } s_decode_inf_nan[1];
6922 } private_data;
6923
6924#ifdef __cplusplus
6925#if (__cplusplus >= 201103L)
6926 using unique_ptr = std::unique_ptr<wuffs_json__decoder, decltype(&free)>;
6927
6928 // On failure, the alloc_etc functions return nullptr. They don't throw.
6929
6930 static inline unique_ptr
6931 alloc() {
6932 return unique_ptr(wuffs_json__decoder__alloc(), &free);
6933 }
6934
6935 static inline wuffs_base__token_decoder::unique_ptr
6936 alloc_as__wuffs_base__token_decoder() {
6937 return wuffs_base__token_decoder::unique_ptr(
6938 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(), &free);
6939 }
6940#endif // (__cplusplus >= 201103L)
6941
6942#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6943 // Disallow constructing or copying an object via standard C++ mechanisms,
6944 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6945 // size and field layout is not part of the public, stable, memory-safe API.
6946 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6947 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6948 // their first argument) rather than tweaking bar.private_impl.qux fields.
6949 //
6950 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6951 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6952 // order to provide convenience methods. These forward on "this", so that you
6953 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6954 wuffs_json__decoder__struct() = delete;
6955 wuffs_json__decoder__struct(const wuffs_json__decoder__struct&) = delete;
6956 wuffs_json__decoder__struct& operator=(
6957 const wuffs_json__decoder__struct&) = delete;
6958
6959 // As above, the size of the struct is not part of the public API, and unless
6960 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6961 // allocated, not stack allocated. Its size is not intended to be known at
6962 // compile time, but it is unfortunately divulged as a side effect of
6963 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6964 // instead of "sizeof T", invoking the operator. To make the two values
6965 // different, so that passing the latter will be rejected by the initialize
6966 // function, we add an arbitrary amount of dead weight.
6967 uint8_t dead_weight[123000000]; // 123 MB.
6968#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
6969
6970 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6971 initialize(
6972 size_t sizeof_star_self,
6973 uint64_t wuffs_version,
6974 uint32_t initialize_flags) {
6975 return wuffs_json__decoder__initialize(
6976 this, sizeof_star_self, wuffs_version, initialize_flags);
6977 }
6978
6979 inline wuffs_base__token_decoder*
6980 upcast_as__wuffs_base__token_decoder() {
6981 return (wuffs_base__token_decoder*)this;
6982 }
6983
6984 inline wuffs_base__empty_struct
6985 set_quirk_enabled(
6986 uint32_t a_quirk,
6987 bool a_enabled) {
6988 return wuffs_json__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6989 }
6990
6991 inline wuffs_base__range_ii_u64
6992 workbuf_len() const {
6993 return wuffs_json__decoder__workbuf_len(this);
6994 }
6995
6996 inline wuffs_base__status
6997 decode_tokens(
6998 wuffs_base__token_buffer* a_dst,
6999 wuffs_base__io_buffer* a_src,
7000 wuffs_base__slice_u8 a_workbuf) {
7001 return wuffs_json__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
7002 }
7003
7004#endif // __cplusplus
7005}; // struct wuffs_json__decoder__struct
7006
7007#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7008
7009#ifdef __cplusplus
7010} // extern "C"
7011#endif
7012
7013#ifdef __cplusplus
7014extern "C" {
7015#endif
7016
7017// ---------------- Status Codes
7018
7019extern const char* wuffs_wbmp__error__bad_header;
7020
7021// ---------------- Public Consts
7022
7023#define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7024
7025// ---------------- Struct Declarations
7026
7027typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder;
7028
7029// ---------------- Public Initializer Prototypes
7030
7031// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7032// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7033//
7034// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7035// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
7036
7037wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7038wuffs_wbmp__decoder__initialize(
7039 wuffs_wbmp__decoder* self,
7040 size_t sizeof_star_self,
7041 uint64_t wuffs_version,
7042 uint32_t initialize_flags);
7043
7044size_t
7045sizeof__wuffs_wbmp__decoder();
7046
7047// ---------------- Allocs
7048
7049// These functions allocate and initialize Wuffs structs. They return NULL if
7050// memory allocation fails. If they return non-NULL, there is no need to call
7051// wuffs_foo__bar__initialize, but the caller is responsible for eventually
7052// calling free on the returned pointer. That pointer is effectively a C++
7053// std::unique_ptr<T, decltype(&free)>.
7054
7055wuffs_wbmp__decoder*
7056wuffs_wbmp__decoder__alloc();
7057
7058static inline wuffs_base__image_decoder*
7059wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder() {
7060 return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
7061}
7062
7063// ---------------- Upcasts
7064
7065static inline wuffs_base__image_decoder*
7066wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
7067 wuffs_wbmp__decoder* p) {
7068 return (wuffs_base__image_decoder*)p;
7069}
7070
7071// ---------------- Public Function Prototypes
7072
7073WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7074wuffs_wbmp__decoder__set_quirk_enabled(
7075 wuffs_wbmp__decoder* self,
7076 uint32_t a_quirk,
7077 bool a_enabled);
7078
7079WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7080wuffs_wbmp__decoder__decode_image_config(
7081 wuffs_wbmp__decoder* self,
7082 wuffs_base__image_config* a_dst,
7083 wuffs_base__io_buffer* a_src);
7084
7085WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7086wuffs_wbmp__decoder__decode_frame_config(
7087 wuffs_wbmp__decoder* self,
7088 wuffs_base__frame_config* a_dst,
7089 wuffs_base__io_buffer* a_src);
7090
7091WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7092wuffs_wbmp__decoder__decode_frame(
7093 wuffs_wbmp__decoder* self,
7094 wuffs_base__pixel_buffer* a_dst,
7095 wuffs_base__io_buffer* a_src,
7096 wuffs_base__pixel_blend a_blend,
7097 wuffs_base__slice_u8 a_workbuf,
7098 wuffs_base__decode_frame_options* a_opts);
7099
7100WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
7101wuffs_wbmp__decoder__frame_dirty_rect(
7102 const wuffs_wbmp__decoder* self);
7103
7104WUFFS_BASE__MAYBE_STATIC uint32_t
7105wuffs_wbmp__decoder__num_animation_loops(
7106 const wuffs_wbmp__decoder* self);
7107
7108WUFFS_BASE__MAYBE_STATIC uint64_t
7109wuffs_wbmp__decoder__num_decoded_frame_configs(
7110 const wuffs_wbmp__decoder* self);
7111
7112WUFFS_BASE__MAYBE_STATIC uint64_t
7113wuffs_wbmp__decoder__num_decoded_frames(
7114 const wuffs_wbmp__decoder* self);
7115
7116WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7117wuffs_wbmp__decoder__restart_frame(
7118 wuffs_wbmp__decoder* self,
7119 uint64_t a_index,
7120 uint64_t a_io_position);
7121
7122WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7123wuffs_wbmp__decoder__set_report_metadata(
7124 wuffs_wbmp__decoder* self,
7125 uint32_t a_fourcc,
7126 bool a_report);
7127
7128WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7129wuffs_wbmp__decoder__tell_me_more(
7130 wuffs_wbmp__decoder* self,
7131 wuffs_base__io_buffer* a_dst,
7132 wuffs_base__more_information* a_minfo,
7133 wuffs_base__io_buffer* a_src);
7134
7135WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7136wuffs_wbmp__decoder__workbuf_len(
7137 const wuffs_wbmp__decoder* self);
7138
7139// ---------------- Struct Definitions
7140
7141// These structs' fields, and the sizeof them, are private implementation
7142// details that aren't guaranteed to be stable across Wuffs versions.
7143//
7144// See https://en.wikipedia.org/wiki/Opaque_pointer#C
7145
7146#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7147
7148struct wuffs_wbmp__decoder__struct {
7149 // Do not access the private_impl's or private_data's fields directly. There
7150 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7151 // the wuffs_foo__bar__baz functions.
7152 //
7153 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7154 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7155
7156 struct {
7157 uint32_t magic;
7158 uint32_t active_coroutine;
7159 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
7160 wuffs_base__vtable null_vtable;
7161
7162 uint32_t f_width;
7163 uint32_t f_height;
7164 uint8_t f_call_sequence;
7165 uint64_t f_frame_config_io_position;
7166 wuffs_base__pixel_swizzler f_swizzler;
7167
7168 uint32_t p_decode_image_config[1];
7169 uint32_t p_decode_frame_config[1];
7170 uint32_t p_decode_frame[1];
7171 uint32_t p_skip_frame[1];
7172 } private_impl;
7173
7174 struct {
7175 struct {
7176 uint32_t v_i;
7177 uint32_t v_x32;
7178 } s_decode_image_config[1];
7179 struct {
7180 uint64_t v_dst_bytes_per_pixel;
7181 uint32_t v_dst_x;
7182 uint32_t v_dst_y;
7183 uint8_t v_src[1];
7184 uint8_t v_c;
7185 } s_decode_frame[1];
7186 struct {
7187 uint64_t scratch;
7188 } s_skip_frame[1];
7189 } private_data;
7190
7191#ifdef __cplusplus
7192#if (__cplusplus >= 201103L)
7193 using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, decltype(&free)>;
7194
7195 // On failure, the alloc_etc functions return nullptr. They don't throw.
7196
7197 static inline unique_ptr
7198 alloc() {
7199 return unique_ptr(wuffs_wbmp__decoder__alloc(), &free);
7200 }
7201
7202 static inline wuffs_base__image_decoder::unique_ptr
7203 alloc_as__wuffs_base__image_decoder() {
7204 return wuffs_base__image_decoder::unique_ptr(
7205 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
7206 }
7207#endif // (__cplusplus >= 201103L)
7208
7209#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
7210 // Disallow constructing or copying an object via standard C++ mechanisms,
7211 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7212 // size and field layout is not part of the public, stable, memory-safe API.
7213 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7214 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7215 // their first argument) rather than tweaking bar.private_impl.qux fields.
7216 //
7217 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7218 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7219 // order to provide convenience methods. These forward on "this", so that you
7220 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7221 wuffs_wbmp__decoder__struct() = delete;
7222 wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete;
7223 wuffs_wbmp__decoder__struct& operator=(
7224 const wuffs_wbmp__decoder__struct&) = delete;
7225
7226 // As above, the size of the struct is not part of the public API, and unless
7227 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7228 // allocated, not stack allocated. Its size is not intended to be known at
7229 // compile time, but it is unfortunately divulged as a side effect of
7230 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7231 // instead of "sizeof T", invoking the operator. To make the two values
7232 // different, so that passing the latter will be rejected by the initialize
7233 // function, we add an arbitrary amount of dead weight.
7234 uint8_t dead_weight[123000000]; // 123 MB.
7235#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
7236
7237 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7238 initialize(
7239 size_t sizeof_star_self,
7240 uint64_t wuffs_version,
7241 uint32_t initialize_flags) {
7242 return wuffs_wbmp__decoder__initialize(
7243 this, sizeof_star_self, wuffs_version, initialize_flags);
7244 }
7245
7246 inline wuffs_base__image_decoder*
7247 upcast_as__wuffs_base__image_decoder() {
7248 return (wuffs_base__image_decoder*)this;
7249 }
7250
7251 inline wuffs_base__empty_struct
7252 set_quirk_enabled(
7253 uint32_t a_quirk,
7254 bool a_enabled) {
7255 return wuffs_wbmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7256 }
7257
7258 inline wuffs_base__status
7259 decode_image_config(
7260 wuffs_base__image_config* a_dst,
7261 wuffs_base__io_buffer* a_src) {
7262 return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src);
7263 }
7264
7265 inline wuffs_base__status
7266 decode_frame_config(
7267 wuffs_base__frame_config* a_dst,
7268 wuffs_base__io_buffer* a_src) {
7269 return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src);
7270 }
7271
7272 inline wuffs_base__status
7273 decode_frame(
7274 wuffs_base__pixel_buffer* a_dst,
7275 wuffs_base__io_buffer* a_src,
7276 wuffs_base__pixel_blend a_blend,
7277 wuffs_base__slice_u8 a_workbuf,
7278 wuffs_base__decode_frame_options* a_opts) {
7279 return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
7280 }
7281
7282 inline wuffs_base__rect_ie_u32
7283 frame_dirty_rect() const {
7284 return wuffs_wbmp__decoder__frame_dirty_rect(this);
7285 }
7286
7287 inline uint32_t
7288 num_animation_loops() const {
7289 return wuffs_wbmp__decoder__num_animation_loops(this);
7290 }
7291
7292 inline uint64_t
7293 num_decoded_frame_configs() const {
7294 return wuffs_wbmp__decoder__num_decoded_frame_configs(this);
7295 }
7296
7297 inline uint64_t
7298 num_decoded_frames() const {
7299 return wuffs_wbmp__decoder__num_decoded_frames(this);
7300 }
7301
7302 inline wuffs_base__status
7303 restart_frame(
7304 uint64_t a_index,
7305 uint64_t a_io_position) {
7306 return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position);
7307 }
7308
7309 inline wuffs_base__empty_struct
7310 set_report_metadata(
7311 uint32_t a_fourcc,
7312 bool a_report) {
7313 return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report);
7314 }
7315
7316 inline wuffs_base__status
7317 tell_me_more(
7318 wuffs_base__io_buffer* a_dst,
7319 wuffs_base__more_information* a_minfo,
7320 wuffs_base__io_buffer* a_src) {
7321 return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
7322 }
7323
7324 inline wuffs_base__range_ii_u64
7325 workbuf_len() const {
7326 return wuffs_wbmp__decoder__workbuf_len(this);
7327 }
7328
7329#endif // __cplusplus
7330}; // struct wuffs_wbmp__decoder__struct
7331
7332#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7333
7334#ifdef __cplusplus
7335} // extern "C"
7336#endif
7337
7338#ifdef __cplusplus
7339extern "C" {
7340#endif
7341
7342// ---------------- Status Codes
7343
7344extern const char* wuffs_zlib__note__dictionary_required;
7345extern const char* wuffs_zlib__error__bad_checksum;
7346extern const char* wuffs_zlib__error__bad_compression_method;
7347extern const char* wuffs_zlib__error__bad_compression_window_size;
7348extern const char* wuffs_zlib__error__bad_parity_check;
7349extern const char* wuffs_zlib__error__incorrect_dictionary;
7350
7351// ---------------- Public Consts
7352
7353#define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
7354
7355// ---------------- Struct Declarations
7356
7357typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
7358
7359// ---------------- Public Initializer Prototypes
7360
7361// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7362// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7363//
7364// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7365// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags.
7366
7367wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7368wuffs_zlib__decoder__initialize(
7369 wuffs_zlib__decoder* self,
7370 size_t sizeof_star_self,
7371 uint64_t wuffs_version,
7372 uint32_t initialize_flags);
7373
7374size_t
7375sizeof__wuffs_zlib__decoder();
7376
7377// ---------------- Allocs
7378
7379// These functions allocate and initialize Wuffs structs. They return NULL if
7380// memory allocation fails. If they return non-NULL, there is no need to call
7381// wuffs_foo__bar__initialize, but the caller is responsible for eventually
7382// calling free on the returned pointer. That pointer is effectively a C++
7383// std::unique_ptr<T, decltype(&free)>.
7384
7385wuffs_zlib__decoder*
7386wuffs_zlib__decoder__alloc();
7387
7388static inline wuffs_base__io_transformer*
7389wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer() {
7390 return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
7391}
7392
7393// ---------------- Upcasts
7394
7395static inline wuffs_base__io_transformer*
7396wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(
7397 wuffs_zlib__decoder* p) {
7398 return (wuffs_base__io_transformer*)p;
7399}
7400
7401// ---------------- Public Function Prototypes
7402
7403WUFFS_BASE__MAYBE_STATIC uint32_t
7404wuffs_zlib__decoder__dictionary_id(
7405 const wuffs_zlib__decoder* self);
7406
7407WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7408wuffs_zlib__decoder__add_dictionary(
7409 wuffs_zlib__decoder* self,
7410 wuffs_base__slice_u8 a_dict);
7411
7412WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7413wuffs_zlib__decoder__set_ignore_checksum(
7414 wuffs_zlib__decoder* self,
7415 bool a_ic);
7416
7417WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7418wuffs_zlib__decoder__set_quirk_enabled(
7419 wuffs_zlib__decoder* self,
7420 uint32_t a_quirk,
7421 bool a_enabled);
7422
7423WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7424wuffs_zlib__decoder__workbuf_len(
7425 const wuffs_zlib__decoder* self);
7426
7427WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7428wuffs_zlib__decoder__transform_io(
7429 wuffs_zlib__decoder* self,
7430 wuffs_base__io_buffer* a_dst,
7431 wuffs_base__io_buffer* a_src,
7432 wuffs_base__slice_u8 a_workbuf);
7433
7434// ---------------- Struct Definitions
7435
7436// These structs' fields, and the sizeof them, are private implementation
7437// details that aren't guaranteed to be stable across Wuffs versions.
7438//
7439// See https://en.wikipedia.org/wiki/Opaque_pointer#C
7440
7441#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7442
7443struct wuffs_zlib__decoder__struct {
7444 // Do not access the private_impl's or private_data's fields directly. There
7445 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7446 // the wuffs_foo__bar__baz functions.
7447 //
7448 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7449 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7450
7451 struct {
7452 uint32_t magic;
7453 uint32_t active_coroutine;
7454 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7455 wuffs_base__vtable null_vtable;
7456
7457 bool f_bad_call_sequence;
7458 bool f_header_complete;
7459 bool f_got_dictionary;
7460 bool f_want_dictionary;
7461 bool f_ignore_checksum;
7462 uint32_t f_dict_id_got;
7463 uint32_t f_dict_id_want;
7464
7465 uint32_t p_transform_io[1];
7466 } private_impl;
7467
7468 struct {
7469 wuffs_adler32__hasher f_checksum;
7470 wuffs_adler32__hasher f_dict_id_hasher;
7471 wuffs_deflate__decoder f_flate;
7472
7473 struct {
7474 uint32_t v_checksum_got;
7475 uint64_t scratch;
7476 } s_transform_io[1];
7477 } private_data;
7478
7479#ifdef __cplusplus
7480#if (__cplusplus >= 201103L)
7481 using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, decltype(&free)>;
7482
7483 // On failure, the alloc_etc functions return nullptr. They don't throw.
7484
7485 static inline unique_ptr
7486 alloc() {
7487 return unique_ptr(wuffs_zlib__decoder__alloc(), &free);
7488 }
7489
7490 static inline wuffs_base__io_transformer::unique_ptr
7491 alloc_as__wuffs_base__io_transformer() {
7492 return wuffs_base__io_transformer::unique_ptr(
7493 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(), &free);
7494 }
7495#endif // (__cplusplus >= 201103L)
7496
7497#if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
7498 // Disallow constructing or copying an object via standard C++ mechanisms,
7499 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7500 // size and field layout is not part of the public, stable, memory-safe API.
7501 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7502 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7503 // their first argument) rather than tweaking bar.private_impl.qux fields.
7504 //
7505 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7506 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7507 // order to provide convenience methods. These forward on "this", so that you
7508 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7509 wuffs_zlib__decoder__struct() = delete;
7510 wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
7511 wuffs_zlib__decoder__struct& operator=(
7512 const wuffs_zlib__decoder__struct&) = delete;
7513
7514 // As above, the size of the struct is not part of the public API, and unless
7515 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7516 // allocated, not stack allocated. Its size is not intended to be known at
7517 // compile time, but it is unfortunately divulged as a side effect of
7518 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7519 // instead of "sizeof T", invoking the operator. To make the two values
7520 // different, so that passing the latter will be rejected by the initialize
7521 // function, we add an arbitrary amount of dead weight.
7522 uint8_t dead_weight[123000000]; // 123 MB.
7523#endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION)
7524
7525 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7526 initialize(
7527 size_t sizeof_star_self,
7528 uint64_t wuffs_version,
7529 uint32_t initialize_flags) {
7530 return wuffs_zlib__decoder__initialize(
7531 this, sizeof_star_self, wuffs_version, initialize_flags);
7532 }
7533
7534 inline wuffs_base__io_transformer*
7535 upcast_as__wuffs_base__io_transformer() {
7536 return (wuffs_base__io_transformer*)this;
7537 }
7538
7539 inline uint32_t
7540 dictionary_id() const {
7541 return wuffs_zlib__decoder__dictionary_id(this);
7542 }
7543
7544 inline wuffs_base__empty_struct
7545 add_dictionary(
7546 wuffs_base__slice_u8 a_dict) {
7547 return wuffs_zlib__decoder__add_dictionary(this, a_dict);
7548 }
7549
7550 inline wuffs_base__empty_struct
7551 set_ignore_checksum(
7552 bool a_ic) {
7553 return wuffs_zlib__decoder__set_ignore_checksum(this, a_ic);
7554 }
7555
7556 inline wuffs_base__empty_struct
7557 set_quirk_enabled(
7558 uint32_t a_quirk,
7559 bool a_enabled) {
7560 return wuffs_zlib__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7561 }
7562
7563 inline wuffs_base__range_ii_u64
7564 workbuf_len() const {
7565 return wuffs_zlib__decoder__workbuf_len(this);
7566 }
7567
7568 inline wuffs_base__status
7569 transform_io(
7570 wuffs_base__io_buffer* a_dst,
7571 wuffs_base__io_buffer* a_src,
7572 wuffs_base__slice_u8 a_workbuf) {
7573 return wuffs_zlib__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7574 }
7575
7576#endif // __cplusplus
7577}; // struct wuffs_zlib__decoder__struct
7578
7579#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7580
7581#ifdef __cplusplus
7582} // extern "C"
7583#endif
7584
7585// WUFFS C HEADER ENDS HERE.
7586#ifdef WUFFS_IMPLEMENTATION
7587
7588#ifdef __cplusplus
7589extern "C" {
7590#endif
7591
7592// ---------------- Fundamentals
7593
7594// WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
7595// It's not foolproof, given C doesn't automatically zero memory before use,
7596// but it should catch 99.99% of cases.
7597//
7598// Its (non-zero) value is arbitrary, based on md5sum("wuffs").
7599#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
7600
7601// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
7602// error was previously encountered.
7603//
7604// Its (non-zero) value is arbitrary, based on md5sum("disabled").
7605#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
7606
7607// Denote intentional fallthroughs for -Wimplicit-fallthrough.
7608//
7609// The order matters here. Clang also defines "__GNUC__".
7610#if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)
7611#define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]
7612#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)
7613#define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))
7614#else
7615#define WUFFS_BASE__FALLTHROUGH
7616#endif
7617
7618// Use switch cases for coroutine suspension points, similar to the technique
7619// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
7620//
7621// We use trivial macros instead of an explicit assignment and case statement
7622// so that clang-format doesn't get confused by the unusual "case"s.
7623#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
7624#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
7625 coro_susp_point = n; \
7626 WUFFS_BASE__FALLTHROUGH; \
7627 case n:;
7628
7629#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
7630 if (!status.repr) { \
7631 goto ok; \
7632 } else if (*status.repr != '$') { \
7633 goto exit; \
7634 } \
7635 coro_susp_point = n; \
7636 goto suspend; \
7637 case n:;
7638
7639// Clang also defines "__GNUC__".
7640#if defined(__GNUC__)
7641#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
7642#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
7643#else
7644#define WUFFS_BASE__LIKELY(expr) (expr)
7645#define WUFFS_BASE__UNLIKELY(expr) (expr)
7646#endif
7647
7648// --------
7649
7650static inline wuffs_base__empty_struct //
7651wuffs_base__ignore_status(wuffs_base__status z) {
7652 return wuffs_base__make_empty_struct();
7653}
7654
7655static inline wuffs_base__status //
7656wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
7657 if (z.repr && (*z.repr == '$')) {
7658 z.repr = wuffs_base__error__cannot_return_a_suspension;
7659 }
7660 return z;
7661}
7662
7663// ---------------- Numeric Types
7664
7665extern const uint8_t wuffs_base__low_bits_mask__u8[9];
7666extern const uint16_t wuffs_base__low_bits_mask__u16[17];
7667extern const uint32_t wuffs_base__low_bits_mask__u32[33];
7668extern const uint64_t wuffs_base__low_bits_mask__u64[65];
7669
7670#define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
7671#define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
7672#define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
7673#define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
7674
7675// --------
7676
7677static inline void //
7678wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
7679 *x = wuffs_base__u8__sat_add(*x, y);
7680}
7681
7682static inline void //
7683wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
7684 *x = wuffs_base__u8__sat_sub(*x, y);
7685}
7686
7687static inline void //
7688wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
7689 *x = wuffs_base__u16__sat_add(*x, y);
7690}
7691
7692static inline void //
7693wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
7694 *x = wuffs_base__u16__sat_sub(*x, y);
7695}
7696
7697static inline void //
7698wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
7699 *x = wuffs_base__u32__sat_add(*x, y);
7700}
7701
7702static inline void //
7703wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
7704 *x = wuffs_base__u32__sat_sub(*x, y);
7705}
7706
7707static inline void //
7708wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
7709 *x = wuffs_base__u64__sat_add(*x, y);
7710}
7711
7712static inline void //
7713wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
7714 *x = wuffs_base__u64__sat_sub(*x, y);
7715}
7716
7717// ---------------- Slices and Tables
7718
7719// wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
7720static inline wuffs_base__slice_u8 //
7721wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
7722 if ((uint64_t)(s.len) > up_to) {
7723 s.len = up_to;
7724 }
7725 return s;
7726}
7727
7728// wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
7729static inline wuffs_base__slice_u8 //
7730wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
7731 if ((uint64_t)(s.len) > up_to) {
7732 s.ptr += (uint64_t)(s.len) - up_to;
7733 s.len = up_to;
7734 }
7735 return s;
7736}
7737
7738// wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
7739// where len is the minimum of dst.len and src.len.
7740//
7741// Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
7742// slice) is valid and results in a no-op.
7743static inline uint64_t //
7744wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
7745 wuffs_base__slice_u8 src) {
7746 size_t len = dst.len < src.len ? dst.len : src.len;
7747 if (len > 0) {
7748 memmove(dst.ptr, src.ptr, len);
7749 }
7750 return len;
7751}
7752
7753// --------
7754
7755static inline wuffs_base__slice_u8 //
7756wuffs_base__table_u8__row(wuffs_base__table_u8 t, uint32_t y) {
7757 if (y < t.height) {
7758 return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
7759 }
7760 return wuffs_base__make_slice_u8(NULL, 0);
7761}
7762
7763// ---------------- Slices and Tables (Utility)
7764
7765#define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
7766
7767// ---------------- Ranges and Rects
7768
7769static inline uint32_t //
7770wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) {
7771 return r->min_incl;
7772}
7773
7774static inline uint32_t //
7775wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) {
7776 return r->max_incl;
7777}
7778
7779static inline uint32_t //
7780wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) {
7781 return r->min_incl;
7782}
7783
7784static inline uint32_t //
7785wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) {
7786 return r->max_excl;
7787}
7788
7789static inline uint64_t //
7790wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) {
7791 return r->min_incl;
7792}
7793
7794static inline uint64_t //
7795wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) {
7796 return r->max_incl;
7797}
7798
7799static inline uint64_t //
7800wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) {
7801 return r->min_incl;
7802}
7803
7804static inline uint64_t //
7805wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) {
7806 return r->max_excl;
7807}
7808
7809// ---------------- Ranges and Rects (Utility)
7810
7811#define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32
7812#define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32
7813#define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64
7814#define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64
7815#define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32
7816#define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32
7817#define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
7818#define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
7819#define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
7820#define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
7821#define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
7822#define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
7823
7824// ---------------- I/O
7825
7826static inline uint64_t //
7827wuffs_base__io__count_since(uint64_t mark, uint64_t index) {
7828 if (index >= mark) {
7829 return index - mark;
7830 }
7831 return 0;
7832}
7833
7834static inline wuffs_base__slice_u8 //
7835wuffs_base__io__since(uint64_t mark, uint64_t index, uint8_t* ptr) {
7836 if (index >= mark) {
7837 return wuffs_base__make_slice_u8(ptr + mark, index - mark);
7838 }
7839 return wuffs_base__make_slice_u8(NULL, 0);
7840}
7841
7842// --------
7843
7844static inline uint32_t //
7845wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r,
7846 const uint8_t* io2_r,
7847 uint32_t length,
7848 wuffs_base__slice_u8 dst) {
7849 const uint8_t* iop_r = *ptr_iop_r;
7850 size_t n = dst.len;
7851 if (n > length) {
7852 n = length;
7853 }
7854 if (n > ((size_t)(io2_r - iop_r))) {
7855 n = (size_t)(io2_r - iop_r);
7856 }
7857 if (n > 0) {
7858 memmove(dst.ptr, iop_r, n);
7859 *ptr_iop_r += n;
7860 }
7861 return (uint32_t)(n);
7862}
7863
7864// wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes
7865// start with the given prefix (up to 7 bytes long). It is peek-like, not
7866// read-like, in that there are no side-effects.
7867//
7868// The low 3 bits of a hold the prefix length, n.
7869//
7870// The high 56 bits of a hold the prefix itself, in little-endian order. The
7871// first prefix byte is in bits 8..=15, the second prefix byte is in bits
7872// 16..=23, etc. The high (8 * (7 - n)) bits are ignored.
7873//
7874// There are three possible return values:
7875// - 0 means success.
7876// - 1 means inconclusive, equivalent to "$short read".
7877// - 2 means failure.
7878static inline uint32_t //
7879wuffs_base__io_reader__match7(const uint8_t* iop_r,
7880 const uint8_t* io2_r,
7881 wuffs_base__io_buffer* r,
7882 uint64_t a) {
7883 uint32_t n = a & 7;
7884 a >>= 8;
7885 if ((io2_r - iop_r) >= 8) {
7886 uint64_t x = wuffs_base__load_u64le__no_bounds_check(iop_r);
7887 uint32_t shift = 8 * (8 - n);
7888 return ((a << shift) == (x << shift)) ? 0 : 2;
7889 }
7890 for (; n > 0; n--) {
7891 if (iop_r >= io2_r) {
7892 return (r && r->meta.closed) ? 2 : 1;
7893 } else if (*iop_r != ((uint8_t)(a))) {
7894 return 2;
7895 }
7896 iop_r++;
7897 a >>= 8;
7898 }
7899 return 0;
7900}
7901
7902static inline wuffs_base__io_buffer* //
7903wuffs_base__io_reader__set(wuffs_base__io_buffer* b,
7904 const uint8_t** ptr_iop_r,
7905 const uint8_t** ptr_io0_r,
7906 const uint8_t** ptr_io1_r,
7907 const uint8_t** ptr_io2_r,
7908 wuffs_base__slice_u8 data) {
7909 b->data = data;
7910 b->meta.wi = data.len;
7911 b->meta.ri = 0;
7912 b->meta.pos = 0;
7913 b->meta.closed = false;
7914
7915 *ptr_iop_r = data.ptr;
7916 *ptr_io0_r = data.ptr;
7917 *ptr_io1_r = data.ptr;
7918 *ptr_io2_r = data.ptr + data.len;
7919
7920 return b;
7921}
7922
7923// --------
7924
7925static inline uint64_t //
7926wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
7927 uint8_t* io2_w,
7928 wuffs_base__slice_u8 src) {
7929 uint8_t* iop_w = *ptr_iop_w;
7930 size_t n = src.len;
7931 if (n > ((size_t)(io2_w - iop_w))) {
7932 n = (size_t)(io2_w - iop_w);
7933 }
7934 if (n > 0) {
7935 memmove(iop_w, src.ptr, n);
7936 *ptr_iop_w += n;
7937 }
7938 return (uint64_t)(n);
7939}
7940
7941static inline uint32_t //
7942wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w,
7943 uint8_t* io1_w,
7944 uint8_t* io2_w,
7945 uint32_t length,
7946 uint32_t distance) {
7947 if (!distance) {
7948 return 0;
7949 }
7950 uint8_t* p = *ptr_iop_w;
7951 if ((size_t)(p - io1_w) < (size_t)(distance)) {
7952 return 0;
7953 }
7954 uint8_t* q = p - distance;
7955 size_t n = (size_t)(io2_w - p);
7956 if ((size_t)(length) > n) {
7957 length = (uint32_t)(n);
7958 } else {
7959 n = (size_t)(length);
7960 }
7961 // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
7962 // is mostly because 3 is the minimum length for the deflate format. This
7963 // function implementation shouldn't overfit to that one format. Perhaps the
7964 // limited_copy_u32_from_history Wuffs method should also take an unroll hint
7965 // argument, and the cgen can look if that argument is the constant
7966 // expression '3'.
7967 //
7968 // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below.
7969 //
7970 // Alternatively or additionally, have a sloppy_limited_copy_u32_from_history
7971 // method that copies 8 bytes at a time, which can more than length bytes?
7972 for (; n >= 3; n -= 3) {
7973 *p++ = *q++;
7974 *p++ = *q++;
7975 *p++ = *q++;
7976 }
7977 for (; n; n--) {
7978 *p++ = *q++;
7979 }
7980 *ptr_iop_w = p;
7981 return length;
7982}
7983
7984// wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the
7985// wuffs_base__io_writer__limited_copy_u32_from_history function above, but has
7986// stronger pre-conditions. The caller needs to prove that:
7987// - distance > 0
7988// - distance <= (*ptr_iop_w - io1_w)
7989// - length <= (io2_w - *ptr_iop_w)
7990static inline uint32_t //
7991wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t** ptr_iop_w,
7992 uint8_t* io1_w,
7993 uint8_t* io2_w,
7994 uint32_t length,
7995 uint32_t distance) {
7996 uint8_t* p = *ptr_iop_w;
7997 uint8_t* q = p - distance;
7998 uint32_t n = length;
7999 for (; n >= 3; n -= 3) {
8000 *p++ = *q++;
8001 *p++ = *q++;
8002 *p++ = *q++;
8003 }
8004 for (; n; n--) {
8005 *p++ = *q++;
8006 }
8007 *ptr_iop_w = p;
8008 return length;
8009}
8010
8011static inline uint32_t //
8012wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t** ptr_iop_w,
8013 uint8_t* io2_w,
8014 uint32_t length,
8015 const uint8_t** ptr_iop_r,
8016 const uint8_t* io2_r) {
8017 uint8_t* iop_w = *ptr_iop_w;
8018 size_t n = length;
8019 if (n > ((size_t)(io2_w - iop_w))) {
8020 n = (size_t)(io2_w - iop_w);
8021 }
8022 const uint8_t* iop_r = *ptr_iop_r;
8023 if (n > ((size_t)(io2_r - iop_r))) {
8024 n = (size_t)(io2_r - iop_r);
8025 }
8026 if (n > 0) {
8027 memmove(iop_w, iop_r, n);
8028 *ptr_iop_w += n;
8029 *ptr_iop_r += n;
8030 }
8031 return (uint32_t)(n);
8032}
8033
8034static inline uint32_t //
8035wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t** ptr_iop_w,
8036 uint8_t* io2_w,
8037 uint32_t length,
8038 wuffs_base__slice_u8 src) {
8039 uint8_t* iop_w = *ptr_iop_w;
8040 size_t n = src.len;
8041 if (n > length) {
8042 n = length;
8043 }
8044 if (n > ((size_t)(io2_w - iop_w))) {
8045 n = (size_t)(io2_w - iop_w);
8046 }
8047 if (n > 0) {
8048 memmove(iop_w, src.ptr, n);
8049 *ptr_iop_w += n;
8050 }
8051 return (uint32_t)(n);
8052}
8053
8054static inline wuffs_base__io_buffer* //
8055wuffs_base__io_writer__set(wuffs_base__io_buffer* b,
8056 uint8_t** ptr_iop_w,
8057 uint8_t** ptr_io0_w,
8058 uint8_t** ptr_io1_w,
8059 uint8_t** ptr_io2_w,
8060 wuffs_base__slice_u8 data) {
8061 b->data = data;
8062 b->meta.wi = 0;
8063 b->meta.ri = 0;
8064 b->meta.pos = 0;
8065 b->meta.closed = false;
8066
8067 *ptr_iop_w = data.ptr;
8068 *ptr_io0_w = data.ptr;
8069 *ptr_io1_w = data.ptr;
8070 *ptr_io2_w = data.ptr + data.len;
8071
8072 return b;
8073}
8074
8075// ---------------- I/O (Utility)
8076
8077#define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader
8078#define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer
8079
8080// ---------------- Tokens
8081
8082// ---------------- Tokens (Utility)
8083
8084// ---------------- Memory Allocation
8085
8086// ---------------- Images
8087
8088WUFFS_BASE__MAYBE_STATIC uint64_t //
8089wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
8090 const wuffs_base__pixel_swizzler* p,
8091 wuffs_base__slice_u8 dst,
8092 wuffs_base__slice_u8 dst_palette,
8093 const uint8_t** ptr_iop_r,
8094 const uint8_t* io2_r);
8095
8096// ---------------- Images (Utility)
8097
8098#define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format
8099
8100// ---------------- String Conversions
8101
8102// ---------------- Unicode and UTF-8
8103
8104// ----------------
8105
8106#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
8107 defined(WUFFS_CONFIG__MODULE__BASE__CORE)
8108
8109const uint8_t wuffs_base__low_bits_mask__u8[9] = {
8110 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF,
8111};
8112
8113const uint16_t wuffs_base__low_bits_mask__u16[17] = {
8114 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
8115 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
8116};
8117
8118const uint32_t wuffs_base__low_bits_mask__u32[33] = {
8119 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
8120 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
8121 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
8122 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
8123 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
8124 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
8125};
8126
8127const uint64_t wuffs_base__low_bits_mask__u64[65] = {
8128 0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
8129 0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
8130 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
8131 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
8132 0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
8133 0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
8134 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
8135 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
8136 0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
8137 0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
8138 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
8139 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
8140 0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
8141 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
8142 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
8143 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
8144 0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
8145 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
8146 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
8147 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
8148 0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
8149 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
8150};
8151
8152const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
8153 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
8154 0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
8155};
8156
8157const char* wuffs_base__note__i_o_redirect = "@base: I/O redirect";
8158const char* wuffs_base__note__end_of_data = "@base: end of data";
8159const char* wuffs_base__note__metadata_reported = "@base: metadata reported";
8160const char* wuffs_base__suspension__even_more_information = "$base: even more information";
8161const char* wuffs_base__suspension__mispositioned_read = "$base: mispositioned read";
8162const char* wuffs_base__suspension__mispositioned_write = "$base: mispositioned write";
8163const char* wuffs_base__suspension__short_read = "$base: short read";
8164const char* wuffs_base__suspension__short_write = "$base: short write";
8165const char* wuffs_base__error__bad_i_o_position = "#base: bad I/O position";
8166const char* wuffs_base__error__bad_argument_length_too_short = "#base: bad argument (length too short)";
8167const char* wuffs_base__error__bad_argument = "#base: bad argument";
8168const char* wuffs_base__error__bad_call_sequence = "#base: bad call sequence";
8169const char* wuffs_base__error__bad_receiver = "#base: bad receiver";
8170const char* wuffs_base__error__bad_restart = "#base: bad restart";
8171const char* wuffs_base__error__bad_sizeof_receiver = "#base: bad sizeof receiver";
8172const char* wuffs_base__error__bad_vtable = "#base: bad vtable";
8173const char* wuffs_base__error__bad_workbuf_length = "#base: bad workbuf length";
8174const char* wuffs_base__error__bad_wuffs_version = "#base: bad wuffs version";
8175const char* wuffs_base__error__cannot_return_a_suspension = "#base: cannot return a suspension";
8176const char* wuffs_base__error__disabled_by_previous_error = "#base: disabled by previous error";
8177const char* wuffs_base__error__initialize_falsely_claimed_already_zeroed = "#base: initialize falsely claimed already zeroed";
8178const char* wuffs_base__error__initialize_not_called = "#base: initialize not called";
8179const char* wuffs_base__error__interleaved_coroutine_calls = "#base: interleaved coroutine calls";
8180const char* wuffs_base__error__no_more_information = "#base: no more information";
8181const char* wuffs_base__error__not_enough_data = "#base: not enough data";
8182const char* wuffs_base__error__out_of_bounds = "#base: out of bounds";
8183const char* wuffs_base__error__unsupported_method = "#base: unsupported method";
8184const char* wuffs_base__error__unsupported_option = "#base: unsupported option";
8185const char* wuffs_base__error__unsupported_pixel_swizzler_option = "#base: unsupported pixel swizzler option";
8186const char* wuffs_base__error__too_much_data = "#base: too much data";
8187
8188const char* wuffs_base__hasher_u32__vtable_name = "{vtable}wuffs_base__hasher_u32";
8189const char* wuffs_base__image_decoder__vtable_name = "{vtable}wuffs_base__image_decoder";
8190const char* wuffs_base__io_transformer__vtable_name = "{vtable}wuffs_base__io_transformer";
8191const char* wuffs_base__token_decoder__vtable_name = "{vtable}wuffs_base__token_decoder";
8192
8193// ---------------- String Conversions
8194
8195// wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits,
8196// and (0x80 | v) for valid digits, where v is the 4 bit value.
8197
8198static const uint8_t wuffs_base__parse_number__decimal_digits[256] = {
8199 // 0 1 2 3 4 5 6 7
8200 // 8 9 A B C D E F
8201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
8202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
8203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
8204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
8205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
8206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
8207 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
8208 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
8209
8210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
8211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
8212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
8213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
8214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
8215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
8216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
8217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
8218
8219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
8220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
8221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
8222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
8223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
8224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
8225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
8226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
8227
8228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
8229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
8230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
8231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
8232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
8233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
8234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
8235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
8236 // 0 1 2 3 4 5 6 7
8237 // 8 9 A B C D E F
8238};
8239
8240static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = {
8241 // 0 1 2 3 4 5 6 7
8242 // 8 9 A B C D E F
8243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
8244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
8245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
8246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
8247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
8248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
8249 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
8250 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
8251
8252 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x40 ..= 0x47. 'A'-'F'.
8253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
8254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
8255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
8256 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x60 ..= 0x67. 'a'-'f'.
8257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
8258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
8259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
8260
8261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
8262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
8263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
8264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
8265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
8266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
8267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
8268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
8269
8270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
8271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
8272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
8273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
8274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
8275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
8276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
8277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
8278 // 0 1 2 3 4 5 6 7
8279 // 8 9 A B C D E F
8280};
8281
8282// --------
8283
8284WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
8285wuffs_base__parse_number_i64(wuffs_base__slice_u8 s) {
8286 uint8_t* p = s.ptr;
8287 uint8_t* q = s.ptr + s.len;
8288
8289 for (; (p < q) && (*p == '_'); p++) {
8290 }
8291
8292 bool negative = false;
8293 if (p >= q) {
8294 goto fail_bad_argument;
8295 } else if (*p == '-') {
8296 p++;
8297 negative = true;
8298 } else if (*p == '+') {
8299 p++;
8300 }
8301
8302 do {
8303 wuffs_base__result_u64 r = wuffs_base__parse_number_u64(
8304 wuffs_base__make_slice_u8(p, (size_t)(q - p)));
8305 if (r.status.repr != NULL) {
8306 wuffs_base__result_i64 ret;
8307 ret.status.repr = r.status.repr;
8308 ret.value = 0;
8309 return ret;
8310 } else if (negative) {
8311 if (r.value > 0x8000000000000000) {
8312 goto fail_out_of_bounds;
8313 }
8314 wuffs_base__result_i64 ret;
8315 ret.status.repr = NULL;
8316 ret.value = -(int64_t)(r.value);
8317 return ret;
8318 } else if (r.value > 0x7FFFFFFFFFFFFFFF) {
8319 goto fail_out_of_bounds;
8320 } else {
8321 wuffs_base__result_i64 ret;
8322 ret.status.repr = NULL;
8323 ret.value = +(int64_t)(r.value);
8324 return ret;
8325 }
8326 } while (0);
8327
8328fail_bad_argument:
8329 do {
8330 wuffs_base__result_i64 ret;
8331 ret.status.repr = wuffs_base__error__bad_argument;
8332 ret.value = 0;
8333 return ret;
8334 } while (0);
8335
8336fail_out_of_bounds:
8337 do {
8338 wuffs_base__result_i64 ret;
8339 ret.status.repr = wuffs_base__error__out_of_bounds;
8340 ret.value = 0;
8341 return ret;
8342 } while (0);
8343}
8344
8345WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
8346wuffs_base__parse_number_u64(wuffs_base__slice_u8 s) {
8347 uint8_t* p = s.ptr;
8348 uint8_t* q = s.ptr + s.len;
8349
8350 for (; (p < q) && (*p == '_'); p++) {
8351 }
8352
8353 if (p >= q) {
8354 goto fail_bad_argument;
8355
8356 } else if (*p == '0') {
8357 p++;
8358 if (p >= q) {
8359 goto ok_zero;
8360 }
8361 if (*p == '_') {
8362 p++;
8363 for (; p < q; p++) {
8364 if (*p != '_') {
8365 goto fail_bad_argument;
8366 }
8367 }
8368 goto ok_zero;
8369 }
8370
8371 if ((*p == 'x') || (*p == 'X')) {
8372 p++;
8373 for (; (p < q) && (*p == '_'); p++) {
8374 }
8375 if (p < q) {
8376 goto hexadecimal;
8377 }
8378
8379 } else if ((*p == 'd') || (*p == 'D')) {
8380 p++;
8381 for (; (p < q) && (*p == '_'); p++) {
8382 }
8383 if (p < q) {
8384 goto decimal;
8385 }
8386 }
8387
8388 goto fail_bad_argument;
8389 }
8390
8391decimal:
8392 do {
8393 uint64_t v = wuffs_base__parse_number__decimal_digits[*p++];
8394 if (v == 0) {
8395 goto fail_bad_argument;
8396 }
8397 v &= 0x0F;
8398
8399 // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1).
8400 const uint64_t max10 = 1844674407370955161u;
8401 const uint8_t max1 = 5;
8402
8403 for (; p < q; p++) {
8404 if (*p == '_') {
8405 continue;
8406 }
8407 uint8_t digit = wuffs_base__parse_number__decimal_digits[*p];
8408 if (digit == 0) {
8409 goto fail_bad_argument;
8410 }
8411 digit &= 0x0F;
8412 if ((v > max10) || ((v == max10) && (digit > max1))) {
8413 goto fail_out_of_bounds;
8414 }
8415 v = (10 * v) + ((uint64_t)(digit));
8416 }
8417
8418 wuffs_base__result_u64 ret;
8419 ret.status.repr = NULL;
8420 ret.value = v;
8421 return ret;
8422 } while (0);
8423
8424hexadecimal:
8425 do {
8426 uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++];
8427 if (v == 0) {
8428 goto fail_bad_argument;
8429 }
8430 v &= 0x0F;
8431
8432 for (; p < q; p++) {
8433 if (*p == '_') {
8434 continue;
8435 }
8436 uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p];
8437 if (digit == 0) {
8438 goto fail_bad_argument;
8439 }
8440 digit &= 0x0F;
8441 if ((v >> 60) != 0) {
8442 goto fail_out_of_bounds;
8443 }
8444 v = (v << 4) | ((uint64_t)(digit));
8445 }
8446
8447 wuffs_base__result_u64 ret;
8448 ret.status.repr = NULL;
8449 ret.value = v;
8450 return ret;
8451 } while (0);
8452
8453ok_zero:
8454 do {
8455 wuffs_base__result_u64 ret;
8456 ret.status.repr = NULL;
8457 ret.value = 0;
8458 return ret;
8459 } while (0);
8460
8461fail_bad_argument:
8462 do {
8463 wuffs_base__result_u64 ret;
8464 ret.status.repr = wuffs_base__error__bad_argument;
8465 ret.value = 0;
8466 return ret;
8467 } while (0);
8468
8469fail_out_of_bounds:
8470 do {
8471 wuffs_base__result_u64 ret;
8472 ret.status.repr = wuffs_base__error__out_of_bounds;
8473 ret.value = 0;
8474 return ret;
8475 } while (0);
8476}
8477
8478// ---------------- Hexadecimal
8479
8480WUFFS_BASE__MAYBE_STATIC size_t //
8481wuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,
8482 wuffs_base__slice_u8 src) {
8483 size_t src_len2 = src.len / 2;
8484 size_t len = dst.len < src_len2 ? dst.len : src_len2;
8485 uint8_t* d = dst.ptr;
8486 uint8_t* s = src.ptr;
8487 size_t n = len;
8488
8489 while (n--) {
8490 *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
8491 (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F));
8492 d += 1;
8493 s += 2;
8494 }
8495
8496 return len;
8497}
8498
8499WUFFS_BASE__MAYBE_STATIC size_t //
8500wuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,
8501 wuffs_base__slice_u8 src) {
8502 size_t src_len4 = src.len / 4;
8503 size_t len = dst.len < src_len4 ? dst.len : src_len4;
8504 uint8_t* d = dst.ptr;
8505 uint8_t* s = src.ptr;
8506 size_t n = len;
8507
8508 while (n--) {
8509 *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
8510 (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F));
8511 d += 1;
8512 s += 4;
8513 }
8514
8515 return len;
8516}
8517
8518// ---------------- Unicode and UTF-8
8519
8520WUFFS_BASE__MAYBE_STATIC size_t //
8521wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {
8522 if (code_point <= 0x7F) {
8523 if (dst.len >= 1) {
8524 dst.ptr[0] = (uint8_t)(code_point);
8525 return 1;
8526 }
8527
8528 } else if (code_point <= 0x07FF) {
8529 if (dst.len >= 2) {
8530 dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));
8531 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
8532 return 2;
8533 }
8534
8535 } else if (code_point <= 0xFFFF) {
8536 if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {
8537 dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));
8538 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
8539 dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
8540 return 3;
8541 }
8542
8543 } else if (code_point <= 0x10FFFF) {
8544 if (dst.len >= 4) {
8545 dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));
8546 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
8547 dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
8548 dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
8549 return 4;
8550 }
8551 }
8552
8553 return 0;
8554}
8555
8556// wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a
8557// UTF-8 encoded code point, based on the encoding's initial byte.
8558// - 0x00 is 1-byte UTF-8 (ASCII).
8559// - 0x01 is the start of 2-byte UTF-8.
8560// - 0x02 is the start of 3-byte UTF-8.
8561// - 0x03 is the start of 4-byte UTF-8.
8562// - 0x40 is a UTF-8 tail byte.
8563// - 0x80 is invalid UTF-8.
8564//
8565// RFC 3629 (UTF-8) gives this grammar for valid UTF-8:
8566// UTF8-1 = %x00-7F
8567// UTF8-2 = %xC2-DF UTF8-tail
8568// UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
8569// %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
8570// UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
8571// %xF4 %x80-8F 2( UTF8-tail )
8572// UTF8-tail = %x80-BF
8573static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {
8574 // 0 1 2 3 4 5 6 7
8575 // 8 9 A B C D E F
8576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
8577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
8578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
8579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
8580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
8581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
8582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 ..= 0x37.
8583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F.
8584
8585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
8586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
8587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
8588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
8589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
8590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
8591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
8592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
8593
8594 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x80 ..= 0x87.
8595 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x88 ..= 0x8F.
8596 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x90 ..= 0x97.
8597 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x98 ..= 0x9F.
8598 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA0 ..= 0xA7.
8599 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA8 ..= 0xAF.
8600 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB0 ..= 0xB7.
8601 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB8 ..= 0xBF.
8602
8603 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC0 ..= 0xC7.
8604 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC8 ..= 0xCF.
8605 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD0 ..= 0xD7.
8606 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD8 ..= 0xDF.
8607 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE0 ..= 0xE7.
8608 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE8 ..= 0xEF.
8609 0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
8610 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
8611 // 0 1 2 3 4 5 6 7
8612 // 8 9 A B C D E F
8613};
8614
8615WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
8616wuffs_base__utf_8__next(wuffs_base__slice_u8 s) {
8617 if (s.len == 0) {
8618 return wuffs_base__make_utf_8__next__output(0, 0);
8619 }
8620 uint32_t c = s.ptr[0];
8621 switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) {
8622 case 0:
8623 return wuffs_base__make_utf_8__next__output(c, 1);
8624
8625 case 1:
8626 if (s.len < 2) {
8627 break;
8628 }
8629 c = wuffs_base__load_u16le__no_bounds_check(s.ptr);
8630 if ((c & 0xC000) != 0x8000) {
8631 break;
8632 }
8633 c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8));
8634 return wuffs_base__make_utf_8__next__output(c, 2);
8635
8636 case 2:
8637 if (s.len < 3) {
8638 break;
8639 }
8640 c = wuffs_base__load_u24le__no_bounds_check(s.ptr);
8641 if ((c & 0xC0C000) != 0x808000) {
8642 break;
8643 }
8644 c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) |
8645 (0x00003F & (c >> 16));
8646 if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) {
8647 break;
8648 }
8649 return wuffs_base__make_utf_8__next__output(c, 3);
8650
8651 case 3:
8652 if (s.len < 4) {
8653 break;
8654 }
8655 c = wuffs_base__load_u32le__no_bounds_check(s.ptr);
8656 if ((c & 0xC0C0C000) != 0x80808000) {
8657 break;
8658 }
8659 c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) |
8660 (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24));
8661 if ((c <= 0xFFFF) || (0x110000 <= c)) {
8662 break;
8663 }
8664 return wuffs_base__make_utf_8__next__output(c, 4);
8665 }
8666
8667 return wuffs_base__make_utf_8__next__output(
8668 WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
8669}
8670
8671WUFFS_BASE__MAYBE_STATIC size_t //
8672wuffs_base__utf_8__longest_valid_prefix(wuffs_base__slice_u8 s) {
8673 // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time).
8674 //
8675 // TODO: possibly optimize this by manually inlining the
8676 // wuffs_base__utf_8__next calls.
8677 size_t original_len = s.len;
8678 while (s.len > 0) {
8679 wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s);
8680 if ((o.code_point > 0x7F) && (o.byte_length == 1)) {
8681 break;
8682 }
8683 s.ptr += o.byte_length;
8684 s.len -= o.byte_length;
8685 }
8686 return original_len - s.len;
8687}
8688
8689WUFFS_BASE__MAYBE_STATIC size_t //
8690wuffs_base__ascii__longest_valid_prefix(wuffs_base__slice_u8 s) {
8691 // TODO: possibly optimize this by checking 4 or 8 bytes at a time.
8692 uint8_t* original_ptr = s.ptr;
8693 uint8_t* p = s.ptr;
8694 uint8_t* q = s.ptr + s.len;
8695 for (; (p != q) && ((*p & 0x80) == 0); p++) {
8696 }
8697 return (size_t)(p - original_ptr);
8698}
8699
8700#endif // !defined(WUFFS_CONFIG__MODULES) ||
8701 // defined(WUFFS_CONFIG__MODULE__BASE) ||
8702 // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
8703
8704#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
8705 defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
8706
8707// ---------------- Interface Definitions.
8708
8709WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8710wuffs_base__hasher_u32__set_quirk_enabled(
8711 wuffs_base__hasher_u32* self,
8712 uint32_t a_quirk,
8713 bool a_enabled) {
8714 if (!self) {
8715 return wuffs_base__make_empty_struct();
8716 }
8717 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8718 return wuffs_base__make_empty_struct();
8719 }
8720
8721 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8722 int i;
8723 for (i = 0; i < 63; i++) {
8724 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
8725 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
8726 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
8727 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
8728 } else if (v->vtable_name == NULL) {
8729 break;
8730 }
8731 v++;
8732 }
8733
8734 return wuffs_base__make_empty_struct();
8735}
8736
8737WUFFS_BASE__MAYBE_STATIC uint32_t
8738wuffs_base__hasher_u32__update_u32(
8739 wuffs_base__hasher_u32* self,
8740 wuffs_base__slice_u8 a_x) {
8741 if (!self) {
8742 return 0;
8743 }
8744 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8745 return 0;
8746 }
8747
8748 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8749 int i;
8750 for (i = 0; i < 63; i++) {
8751 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
8752 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
8753 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
8754 return (*func_ptrs->update_u32)(self, a_x);
8755 } else if (v->vtable_name == NULL) {
8756 break;
8757 }
8758 v++;
8759 }
8760
8761 return 0;
8762}
8763
8764// --------
8765
8766WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8767wuffs_base__image_decoder__decode_frame(
8768 wuffs_base__image_decoder* self,
8769 wuffs_base__pixel_buffer* a_dst,
8770 wuffs_base__io_buffer* a_src,
8771 wuffs_base__pixel_blend a_blend,
8772 wuffs_base__slice_u8 a_workbuf,
8773 wuffs_base__decode_frame_options* a_opts) {
8774 if (!self) {
8775 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
8776 }
8777 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8778 return wuffs_base__make_status(
8779 (self->private_impl.magic == WUFFS_BASE__DISABLED)
8780 ? wuffs_base__error__disabled_by_previous_error
8781 : wuffs_base__error__initialize_not_called);
8782 }
8783
8784 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8785 int i;
8786 for (i = 0; i < 63; i++) {
8787 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8788 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8789 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8790 return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts);
8791 } else if (v->vtable_name == NULL) {
8792 break;
8793 }
8794 v++;
8795 }
8796
8797 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
8798}
8799
8800WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8801wuffs_base__image_decoder__decode_frame_config(
8802 wuffs_base__image_decoder* self,
8803 wuffs_base__frame_config* a_dst,
8804 wuffs_base__io_buffer* a_src) {
8805 if (!self) {
8806 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
8807 }
8808 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8809 return wuffs_base__make_status(
8810 (self->private_impl.magic == WUFFS_BASE__DISABLED)
8811 ? wuffs_base__error__disabled_by_previous_error
8812 : wuffs_base__error__initialize_not_called);
8813 }
8814
8815 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8816 int i;
8817 for (i = 0; i < 63; i++) {
8818 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8819 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8820 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8821 return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
8822 } else if (v->vtable_name == NULL) {
8823 break;
8824 }
8825 v++;
8826 }
8827
8828 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
8829}
8830
8831WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8832wuffs_base__image_decoder__decode_image_config(
8833 wuffs_base__image_decoder* self,
8834 wuffs_base__image_config* a_dst,
8835 wuffs_base__io_buffer* a_src) {
8836 if (!self) {
8837 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
8838 }
8839 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8840 return wuffs_base__make_status(
8841 (self->private_impl.magic == WUFFS_BASE__DISABLED)
8842 ? wuffs_base__error__disabled_by_previous_error
8843 : wuffs_base__error__initialize_not_called);
8844 }
8845
8846 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8847 int i;
8848 for (i = 0; i < 63; i++) {
8849 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8850 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8851 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8852 return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
8853 } else if (v->vtable_name == NULL) {
8854 break;
8855 }
8856 v++;
8857 }
8858
8859 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
8860}
8861
8862WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
8863wuffs_base__image_decoder__frame_dirty_rect(
8864 const wuffs_base__image_decoder* self) {
8865 if (!self) {
8866 return wuffs_base__utility__empty_rect_ie_u32();
8867 }
8868 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
8869 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
8870 return wuffs_base__utility__empty_rect_ie_u32();
8871 }
8872
8873 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8874 int i;
8875 for (i = 0; i < 63; i++) {
8876 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8877 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8878 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8879 return (*func_ptrs->frame_dirty_rect)(self);
8880 } else if (v->vtable_name == NULL) {
8881 break;
8882 }
8883 v++;
8884 }
8885
8886 return wuffs_base__utility__empty_rect_ie_u32();
8887}
8888
8889WUFFS_BASE__MAYBE_STATIC uint32_t
8890wuffs_base__image_decoder__num_animation_loops(
8891 const wuffs_base__image_decoder* self) {
8892 if (!self) {
8893 return 0;
8894 }
8895 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
8896 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
8897 return 0;
8898 }
8899
8900 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8901 int i;
8902 for (i = 0; i < 63; i++) {
8903 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8904 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8905 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8906 return (*func_ptrs->num_animation_loops)(self);
8907 } else if (v->vtable_name == NULL) {
8908 break;
8909 }
8910 v++;
8911 }
8912
8913 return 0;
8914}
8915
8916WUFFS_BASE__MAYBE_STATIC uint64_t
8917wuffs_base__image_decoder__num_decoded_frame_configs(
8918 const wuffs_base__image_decoder* self) {
8919 if (!self) {
8920 return 0;
8921 }
8922 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
8923 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
8924 return 0;
8925 }
8926
8927 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8928 int i;
8929 for (i = 0; i < 63; i++) {
8930 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8931 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8932 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8933 return (*func_ptrs->num_decoded_frame_configs)(self);
8934 } else if (v->vtable_name == NULL) {
8935 break;
8936 }
8937 v++;
8938 }
8939
8940 return 0;
8941}
8942
8943WUFFS_BASE__MAYBE_STATIC uint64_t
8944wuffs_base__image_decoder__num_decoded_frames(
8945 const wuffs_base__image_decoder* self) {
8946 if (!self) {
8947 return 0;
8948 }
8949 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
8950 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
8951 return 0;
8952 }
8953
8954 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8955 int i;
8956 for (i = 0; i < 63; i++) {
8957 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8958 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8959 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8960 return (*func_ptrs->num_decoded_frames)(self);
8961 } else if (v->vtable_name == NULL) {
8962 break;
8963 }
8964 v++;
8965 }
8966
8967 return 0;
8968}
8969
8970WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8971wuffs_base__image_decoder__restart_frame(
8972 wuffs_base__image_decoder* self,
8973 uint64_t a_index,
8974 uint64_t a_io_position) {
8975 if (!self) {
8976 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
8977 }
8978 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
8979 return wuffs_base__make_status(
8980 (self->private_impl.magic == WUFFS_BASE__DISABLED)
8981 ? wuffs_base__error__disabled_by_previous_error
8982 : wuffs_base__error__initialize_not_called);
8983 }
8984
8985 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
8986 int i;
8987 for (i = 0; i < 63; i++) {
8988 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
8989 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
8990 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
8991 return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
8992 } else if (v->vtable_name == NULL) {
8993 break;
8994 }
8995 v++;
8996 }
8997
8998 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
8999}
9000
9001WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9002wuffs_base__image_decoder__set_quirk_enabled(
9003 wuffs_base__image_decoder* self,
9004 uint32_t a_quirk,
9005 bool a_enabled) {
9006 if (!self) {
9007 return wuffs_base__make_empty_struct();
9008 }
9009 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9010 return wuffs_base__make_empty_struct();
9011 }
9012
9013 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9014 int i;
9015 for (i = 0; i < 63; i++) {
9016 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
9017 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
9018 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
9019 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
9020 } else if (v->vtable_name == NULL) {
9021 break;
9022 }
9023 v++;
9024 }
9025
9026 return wuffs_base__make_empty_struct();
9027}
9028
9029WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9030wuffs_base__image_decoder__set_report_metadata(
9031 wuffs_base__image_decoder* self,
9032 uint32_t a_fourcc,
9033 bool a_report) {
9034 if (!self) {
9035 return wuffs_base__make_empty_struct();
9036 }
9037 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9038 return wuffs_base__make_empty_struct();
9039 }
9040
9041 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9042 int i;
9043 for (i = 0; i < 63; i++) {
9044 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
9045 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
9046 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
9047 return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
9048 } else if (v->vtable_name == NULL) {
9049 break;
9050 }
9051 v++;
9052 }
9053
9054 return wuffs_base__make_empty_struct();
9055}
9056
9057WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9058wuffs_base__image_decoder__tell_me_more(
9059 wuffs_base__image_decoder* self,
9060 wuffs_base__io_buffer* a_dst,
9061 wuffs_base__more_information* a_minfo,
9062 wuffs_base__io_buffer* a_src) {
9063 if (!self) {
9064 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
9065 }
9066 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9067 return wuffs_base__make_status(
9068 (self->private_impl.magic == WUFFS_BASE__DISABLED)
9069 ? wuffs_base__error__disabled_by_previous_error
9070 : wuffs_base__error__initialize_not_called);
9071 }
9072
9073 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9074 int i;
9075 for (i = 0; i < 63; i++) {
9076 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
9077 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
9078 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
9079 return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
9080 } else if (v->vtable_name == NULL) {
9081 break;
9082 }
9083 v++;
9084 }
9085
9086 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
9087}
9088
9089WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9090wuffs_base__image_decoder__workbuf_len(
9091 const wuffs_base__image_decoder* self) {
9092 if (!self) {
9093 return wuffs_base__utility__empty_range_ii_u64();
9094 }
9095 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9096 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9097 return wuffs_base__utility__empty_range_ii_u64();
9098 }
9099
9100 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9101 int i;
9102 for (i = 0; i < 63; i++) {
9103 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
9104 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
9105 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
9106 return (*func_ptrs->workbuf_len)(self);
9107 } else if (v->vtable_name == NULL) {
9108 break;
9109 }
9110 v++;
9111 }
9112
9113 return wuffs_base__utility__empty_range_ii_u64();
9114}
9115
9116// --------
9117
9118WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9119wuffs_base__io_transformer__set_quirk_enabled(
9120 wuffs_base__io_transformer* self,
9121 uint32_t a_quirk,
9122 bool a_enabled) {
9123 if (!self) {
9124 return wuffs_base__make_empty_struct();
9125 }
9126 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9127 return wuffs_base__make_empty_struct();
9128 }
9129
9130 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9131 int i;
9132 for (i = 0; i < 63; i++) {
9133 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
9134 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
9135 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
9136 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
9137 } else if (v->vtable_name == NULL) {
9138 break;
9139 }
9140 v++;
9141 }
9142
9143 return wuffs_base__make_empty_struct();
9144}
9145
9146WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9147wuffs_base__io_transformer__transform_io(
9148 wuffs_base__io_transformer* self,
9149 wuffs_base__io_buffer* a_dst,
9150 wuffs_base__io_buffer* a_src,
9151 wuffs_base__slice_u8 a_workbuf) {
9152 if (!self) {
9153 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
9154 }
9155 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9156 return wuffs_base__make_status(
9157 (self->private_impl.magic == WUFFS_BASE__DISABLED)
9158 ? wuffs_base__error__disabled_by_previous_error
9159 : wuffs_base__error__initialize_not_called);
9160 }
9161
9162 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9163 int i;
9164 for (i = 0; i < 63; i++) {
9165 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
9166 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
9167 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
9168 return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
9169 } else if (v->vtable_name == NULL) {
9170 break;
9171 }
9172 v++;
9173 }
9174
9175 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
9176}
9177
9178WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9179wuffs_base__io_transformer__workbuf_len(
9180 const wuffs_base__io_transformer* self) {
9181 if (!self) {
9182 return wuffs_base__utility__empty_range_ii_u64();
9183 }
9184 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9185 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9186 return wuffs_base__utility__empty_range_ii_u64();
9187 }
9188
9189 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9190 int i;
9191 for (i = 0; i < 63; i++) {
9192 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
9193 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
9194 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
9195 return (*func_ptrs->workbuf_len)(self);
9196 } else if (v->vtable_name == NULL) {
9197 break;
9198 }
9199 v++;
9200 }
9201
9202 return wuffs_base__utility__empty_range_ii_u64();
9203}
9204
9205// --------
9206
9207WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9208wuffs_base__token_decoder__decode_tokens(
9209 wuffs_base__token_decoder* self,
9210 wuffs_base__token_buffer* a_dst,
9211 wuffs_base__io_buffer* a_src,
9212 wuffs_base__slice_u8 a_workbuf) {
9213 if (!self) {
9214 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
9215 }
9216 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9217 return wuffs_base__make_status(
9218 (self->private_impl.magic == WUFFS_BASE__DISABLED)
9219 ? wuffs_base__error__disabled_by_previous_error
9220 : wuffs_base__error__initialize_not_called);
9221 }
9222
9223 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9224 int i;
9225 for (i = 0; i < 63; i++) {
9226 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
9227 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
9228 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
9229 return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
9230 } else if (v->vtable_name == NULL) {
9231 break;
9232 }
9233 v++;
9234 }
9235
9236 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
9237}
9238
9239WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9240wuffs_base__token_decoder__set_quirk_enabled(
9241 wuffs_base__token_decoder* self,
9242 uint32_t a_quirk,
9243 bool a_enabled) {
9244 if (!self) {
9245 return wuffs_base__make_empty_struct();
9246 }
9247 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
9248 return wuffs_base__make_empty_struct();
9249 }
9250
9251 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9252 int i;
9253 for (i = 0; i < 63; i++) {
9254 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
9255 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
9256 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
9257 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
9258 } else if (v->vtable_name == NULL) {
9259 break;
9260 }
9261 v++;
9262 }
9263
9264 return wuffs_base__make_empty_struct();
9265}
9266
9267WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9268wuffs_base__token_decoder__workbuf_len(
9269 const wuffs_base__token_decoder* self) {
9270 if (!self) {
9271 return wuffs_base__utility__empty_range_ii_u64();
9272 }
9273 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
9274 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
9275 return wuffs_base__utility__empty_range_ii_u64();
9276 }
9277
9278 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
9279 int i;
9280 for (i = 0; i < 63; i++) {
9281 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
9282 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
9283 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
9284 return (*func_ptrs->workbuf_len)(self);
9285 } else if (v->vtable_name == NULL) {
9286 break;
9287 }
9288 v++;
9289 }
9290
9291 return wuffs_base__utility__empty_range_ii_u64();
9292}
9293
9294#endif // !defined(WUFFS_CONFIG__MODULES) ||
9295 // defined(WUFFS_CONFIG__MODULE__BASE) ||
9296 // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
9297
9298#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
9299 defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)
9300
9301// ---------------- IEEE 754 Floating Point
9302
9303#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE 1023
9304#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION 500
9305
9306// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL is the largest N
9307// such that ((10 << N) < (1 << 64)).
9308#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL 60
9309
9310// wuffs_base__private_implementation__high_prec_dec (abbreviated as HPD) is a
9311// fixed precision floating point decimal number, augmented with ±infinity
9312// values, but it cannot represent NaN (Not a Number).
9313//
9314// "High precision" means that the mantissa holds 500 decimal digits. 500 is
9315// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION.
9316//
9317// An HPD isn't for general purpose arithmetic, only for conversions to and
9318// from IEEE 754 double-precision floating point, where the largest and
9319// smallest positive, finite values are approximately 1.8e+308 and 4.9e-324.
9320// HPD exponents above +1023 mean infinity, below -1023 mean zero. The ±1023
9321// bounds are further away from zero than ±(324 + 500), where 500 and 1023 is
9322// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION and
9323// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
9324//
9325// digits[.. num_digits] are the number's digits in big-endian order. The
9326// uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7'
9327// is the ASCII value 0x37.
9328//
9329// decimal_point is the index (within digits) of the decimal point. It may be
9330// negative or be larger than num_digits, in which case the explicit digits are
9331// padded with implicit zeroes.
9332//
9333// For example, if num_digits is 3 and digits is "\x07\x08\x09":
9334// - A decimal_point of -2 means ".00789"
9335// - A decimal_point of -1 means ".0789"
9336// - A decimal_point of +0 means ".789"
9337// - A decimal_point of +1 means "7.89"
9338// - A decimal_point of +2 means "78.9"
9339// - A decimal_point of +3 means "789."
9340// - A decimal_point of +4 means "7890."
9341// - A decimal_point of +5 means "78900."
9342//
9343// As above, a decimal_point higher than +1023 means that the overall value is
9344// infinity, lower than -1023 means zero.
9345//
9346// negative is a sign bit. An HPD can distinguish positive and negative zero.
9347//
9348// truncated is whether there are more than
9349// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION digits, and at
9350// least one of those extra digits are non-zero. The existence of long-tail
9351// digits can affect rounding.
9352//
9353// The "all fields are zero" value is valid, and represents the number +0.
9354typedef struct {
9355 uint32_t num_digits;
9356 int32_t decimal_point;
9357 bool negative;
9358 bool truncated;
9359 uint8_t digits[WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION];
9360} wuffs_base__private_implementation__high_prec_dec;
9361
9362// wuffs_base__private_implementation__high_prec_dec__trim trims trailing
9363// zeroes from the h->digits[.. h->num_digits] slice. They have no benefit,
9364// since we explicitly track h->decimal_point.
9365//
9366// Preconditions:
9367// - h is non-NULL.
9368static inline void //
9369wuffs_base__private_implementation__high_prec_dec__trim(
9370 wuffs_base__private_implementation__high_prec_dec* h) {
9371 while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) {
9372 h->num_digits--;
9373 }
9374}
9375
9376static wuffs_base__status //
9377wuffs_base__private_implementation__high_prec_dec__parse(
9378 wuffs_base__private_implementation__high_prec_dec* h,
9379 wuffs_base__slice_u8 s) {
9380 if (!h) {
9381 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
9382 }
9383 h->num_digits = 0;
9384 h->decimal_point = 0;
9385 h->negative = false;
9386 h->truncated = false;
9387
9388 uint8_t* p = s.ptr;
9389 uint8_t* q = s.ptr + s.len;
9390
9391 for (; (p < q) && (*p == '_'); p++) {
9392 }
9393 if (p >= q) {
9394 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9395 }
9396
9397 // Parse sign.
9398 do {
9399 if (*p == '+') {
9400 p++;
9401 } else if (*p == '-') {
9402 h->negative = true;
9403 p++;
9404 } else {
9405 break;
9406 }
9407 for (; (p < q) && (*p == '_'); p++) {
9408 }
9409 } while (0);
9410
9411 // Parse digits.
9412 uint32_t nd = 0;
9413 int32_t dp = 0;
9414 bool saw_digits = false;
9415 bool saw_non_zero_digits = false;
9416 bool saw_dot = false;
9417 for (; p < q; p++) {
9418 if (*p == '_') {
9419 // No-op.
9420
9421 } else if ((*p == '.') || (*p == ',')) {
9422 // As per https://en.wikipedia.org/wiki/Decimal_separator, both '.' or
9423 // ',' are commonly used. We just parse either, regardless of LOCALE.
9424 if (saw_dot) {
9425 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9426 }
9427 saw_dot = true;
9428 dp = (int32_t)nd;
9429
9430 } else if ('0' == *p) {
9431 if (!saw_dot && !saw_non_zero_digits && saw_digits) {
9432 // We don't allow unnecessary leading zeroes: "000123" or "0644".
9433 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9434 }
9435 saw_digits = true;
9436 if (nd == 0) {
9437 // Track leading zeroes implicitly.
9438 dp--;
9439 } else if (nd <
9440 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
9441 h->digits[nd++] = 0;
9442 } else {
9443 // Long-tail zeroes are ignored.
9444 }
9445
9446 } else if (('0' < *p) && (*p <= '9')) {
9447 if (!saw_dot && !saw_non_zero_digits && saw_digits) {
9448 // We don't allow unnecessary leading zeroes: "000123" or "0644".
9449 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9450 }
9451 saw_digits = true;
9452 saw_non_zero_digits = true;
9453 if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
9454 h->digits[nd++] = (uint8_t)(*p - '0');
9455 } else {
9456 // Long-tail non-zeroes set the truncated bit.
9457 h->truncated = true;
9458 }
9459
9460 } else {
9461 break;
9462 }
9463 }
9464
9465 if (!saw_digits) {
9466 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9467 }
9468 if (!saw_dot) {
9469 dp = (int32_t)nd;
9470 }
9471
9472 // Parse exponent.
9473 if ((p < q) && ((*p == 'E') || (*p == 'e'))) {
9474 p++;
9475 for (; (p < q) && (*p == '_'); p++) {
9476 }
9477 if (p >= q) {
9478 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9479 }
9480
9481 int32_t exp_sign = +1;
9482 if (*p == '+') {
9483 p++;
9484 } else if (*p == '-') {
9485 exp_sign = -1;
9486 p++;
9487 }
9488
9489 int32_t exp = 0;
9490 const int32_t exp_large =
9491 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE +
9492 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
9493 bool saw_exp_digits = false;
9494 for (; p < q; p++) {
9495 if (*p == '_') {
9496 // No-op.
9497 } else if (('0' <= *p) && (*p <= '9')) {
9498 saw_exp_digits = true;
9499 if (exp < exp_large) {
9500 exp = (10 * exp) + ((int32_t)(*p - '0'));
9501 }
9502 } else {
9503 break;
9504 }
9505 }
9506 if (!saw_exp_digits) {
9507 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9508 }
9509 dp += exp_sign * exp;
9510 }
9511
9512 // Finish.
9513 if (p != q) {
9514 return wuffs_base__make_status(wuffs_base__error__bad_argument);
9515 }
9516 h->num_digits = nd;
9517 if (nd == 0) {
9518 h->decimal_point = 0;
9519 } else if (dp <
9520 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
9521 h->decimal_point =
9522 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE - 1;
9523 } else if (dp >
9524 +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
9525 h->decimal_point =
9526 +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + 1;
9527 } else {
9528 h->decimal_point = dp;
9529 }
9530 wuffs_base__private_implementation__high_prec_dec__trim(h);
9531 return wuffs_base__make_status(NULL);
9532}
9533
9534// --------
9535
9536// The etc__hpd_left_shift and etc__powers_of_5 tables were printed by
9537// script/print-hpd-left-shift.go. That script has an optional -comments flag,
9538// whose output is not copied here, which prints further detail.
9539//
9540// These tables are used in
9541// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits.
9542
9543// wuffs_base__private_implementation__hpd_left_shift[i] encodes the number of
9544// new digits created after multiplying a positive integer by (1 << i): the
9545// additional length in the decimal representation. For example, shifting "234"
9546// by 3 (equivalent to multiplying by 8) will produce "1872". Going from a
9547// 3-length string to a 4-length string means that 1 new digit was added (and
9548// existing digits may have changed).
9549//
9550// Shifting by i can add either N or N-1 new digits, depending on whether the
9551// original positive integer compares >= or < to the i'th power of 5 (as 10
9552// equals 2 * 5). Comparison is lexicographic, not numerical.
9553//
9554// For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new
9555// digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625":
9556// - ("1" << 4) is "16", which adds 1 new digit.
9557// - ("5678" << 4) is "90848", which adds 1 new digit.
9558// - ("624" << 4) is "9984", which adds 1 new digit.
9559// - ("62498" << 4) is "999968", which adds 1 new digit.
9560// - ("625" << 4) is "10000", which adds 2 new digits.
9561// - ("625001" << 4) is "10000016", which adds 2 new digits.
9562// - ("7008" << 4) is "112128", which adds 2 new digits.
9563// - ("99" << 4) is "1584", which adds 2 new digits.
9564//
9565// Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift
9566// array encodes this as:
9567// - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006.
9568// - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009.
9569// where the ? isn't relevant for i == 4.
9570//
9571// The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two
9572// possible number of new digits. The low 11 bits are an offset into the
9573// etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i
9574// is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9]
9575// is the string "\x06\x02\x05", so the relevant power of 5 is "625".
9576//
9577// Thanks to Ken Thompson for the original idea.
9578static const uint16_t wuffs_base__private_implementation__hpd_left_shift[65] = {
9579 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
9580 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
9581 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
9582 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
9583 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
9584 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
9585 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
9586 0x051C, 0x051C,
9587};
9588
9589// wuffs_base__private_implementation__powers_of_5 contains the powers of 5,
9590// concatenated together: "5", "25", "125", "625", "3125", etc.
9591static const uint8_t wuffs_base__private_implementation__powers_of_5[0x051C] = {
9592 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9,
9593 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2,
9594 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5,
9595 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8, 7, 8, 9, 0,
9596 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6, 9, 7, 2, 6, 5,
9597 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1,
9598 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4,
9599 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7,
9600 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0,
9601 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3,
9602 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1,
9603 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6,
9604 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5,
9605 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0,
9606 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6,
9607 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8,
9608 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7,
9609 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6,
9610 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8,
9611 0, 6, 6, 4, 0, 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9,
9612 0, 3, 3, 2, 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2,
9613 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8,
9614 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7,
9615 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5,
9616 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3,
9617 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2,
9618 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9,
9619 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8, 0, 1, 4, 8,
9620 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4,
9621 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0,
9622 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5,
9623 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1,
9624 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5,
9625 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3,
9626 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4,
9627 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3,
9628 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8,
9629 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2,
9630 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6,
9631 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2,
9632 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2,
9633 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5,
9634 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5,
9635 6, 2, 8, 9, 1, 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8,
9636 1, 2, 5, 1, 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9,
9637 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3,
9638 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6,
9639 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1,
9640 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1,
9641 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4,
9642 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7,
9643 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3,
9644 6, 9, 1, 4, 0, 6, 2, 5,
9645};
9646
9647// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
9648// returns the number of additional decimal digits when left-shifting by shift.
9649//
9650// See below for preconditions.
9651static uint32_t //
9652wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
9653 wuffs_base__private_implementation__high_prec_dec* h,
9654 uint32_t shift) {
9655 // Masking with 0x3F should be unnecessary (assuming the preconditions) but
9656 // it's cheap and ensures that we don't overflow the
9657 // wuffs_base__private_implementation__hpd_left_shift array.
9658 shift &= 63;
9659
9660 uint32_t x_a = wuffs_base__private_implementation__hpd_left_shift[shift];
9661 uint32_t x_b = wuffs_base__private_implementation__hpd_left_shift[shift + 1];
9662 uint32_t num_new_digits = x_a >> 11;
9663 uint32_t pow5_a = 0x7FF & x_a;
9664 uint32_t pow5_b = 0x7FF & x_b;
9665
9666 const uint8_t* pow5 =
9667 &wuffs_base__private_implementation__powers_of_5[pow5_a];
9668 uint32_t i = 0;
9669 uint32_t n = pow5_b - pow5_a;
9670 for (; i < n; i++) {
9671 if (i >= h->num_digits) {
9672 return num_new_digits - 1;
9673 } else if (h->digits[i] == pow5[i]) {
9674 continue;
9675 } else if (h->digits[i] < pow5[i]) {
9676 return num_new_digits - 1;
9677 } else {
9678 return num_new_digits;
9679 }
9680 }
9681 return num_new_digits;
9682}
9683
9684// --------
9685
9686// wuffs_base__private_implementation__high_prec_dec__rounded_integer returns
9687// the integral (non-fractional) part of h, provided that it is 18 or fewer
9688// decimal digits. For 19 or more digits, it returns UINT64_MAX. Note that:
9689// - (1 << 53) is 9007199254740992, which has 16 decimal digits.
9690// - (1 << 56) is 72057594037927936, which has 17 decimal digits.
9691// - (1 << 59) is 576460752303423488, which has 18 decimal digits.
9692// - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
9693// and that IEEE 754 double precision has 52 mantissa bits.
9694//
9695// That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8.
9696//
9697// h's negative bit is ignored: rounding -8.6 returns 9.
9698//
9699// See below for preconditions.
9700static uint64_t //
9701wuffs_base__private_implementation__high_prec_dec__rounded_integer(
9702 wuffs_base__private_implementation__high_prec_dec* h) {
9703 if ((h->num_digits == 0) || (h->decimal_point < 0)) {
9704 return 0;
9705 } else if (h->decimal_point > 18) {
9706 return UINT64_MAX;
9707 }
9708
9709 uint32_t dp = (uint32_t)(h->decimal_point);
9710 uint64_t n = 0;
9711 uint32_t i = 0;
9712 for (; i < dp; i++) {
9713 n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);
9714 }
9715
9716 bool round_up = false;
9717 if (dp < h->num_digits) {
9718 round_up = h->digits[dp] >= 5;
9719 if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {
9720 // We are exactly halfway. If we're truncated, round up, otherwise round
9721 // to even.
9722 round_up = h->truncated || //
9723 ((dp > 0) && (1 & h->digits[dp - 1]));
9724 }
9725 }
9726 if (round_up) {
9727 n++;
9728 }
9729
9730 return n;
9731}
9732
9733// wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's
9734// number (where 'x' is 'l' or 'r' for left or right) by a small shift value.
9735//
9736// Preconditions:
9737// - h is non-NULL.
9738// - h->decimal_point is "not extreme".
9739// - shift is non-zero.
9740// - shift is "a small shift".
9741//
9742// "Not extreme" means within
9743// ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
9744//
9745// "A small shift" means not more than
9746// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
9747//
9748// wuffs_base__private_implementation__high_prec_dec__rounded_integer and
9749// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
9750// have the same preconditions.
9751
9752static void //
9753wuffs_base__private_implementation__high_prec_dec__small_lshift(
9754 wuffs_base__private_implementation__high_prec_dec* h,
9755 uint32_t shift) {
9756 if (h->num_digits == 0) {
9757 return;
9758 }
9759 uint32_t num_new_digits =
9760 wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
9761 h, shift);
9762 uint32_t rx = h->num_digits - 1; // Read index.
9763 uint32_t wx = h->num_digits - 1 + num_new_digits; // Write index.
9764 uint64_t n = 0;
9765
9766 // Repeat: pick up a digit, put down a digit, right to left.
9767 while (((int32_t)rx) >= 0) {
9768 n += ((uint64_t)(h->digits[rx])) << shift;
9769 uint64_t quo = n / 10;
9770 uint64_t rem = n - (10 * quo);
9771 if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
9772 h->digits[wx] = (uint8_t)rem;
9773 } else if (rem > 0) {
9774 h->truncated = true;
9775 }
9776 n = quo;
9777 wx--;
9778 rx--;
9779 }
9780
9781 // Put down leading digits, right to left.
9782 while (n > 0) {
9783 uint64_t quo = n / 10;
9784 uint64_t rem = n - (10 * quo);
9785 if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
9786 h->digits[wx] = (uint8_t)rem;
9787 } else if (rem > 0) {
9788 h->truncated = true;
9789 }
9790 n = quo;
9791 wx--;
9792 }
9793
9794 // Finish.
9795 h->num_digits += num_new_digits;
9796 if (h->num_digits >
9797 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
9798 h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
9799 }
9800 h->decimal_point += (int32_t)num_new_digits;
9801 wuffs_base__private_implementation__high_prec_dec__trim(h);
9802}
9803
9804static void //
9805wuffs_base__private_implementation__high_prec_dec__small_rshift(
9806 wuffs_base__private_implementation__high_prec_dec* h,
9807 uint32_t shift) {
9808 uint32_t rx = 0; // Read index.
9809 uint32_t wx = 0; // Write index.
9810 uint64_t n = 0;
9811
9812 // Pick up enough leading digits to cover the first shift.
9813 while ((n >> shift) == 0) {
9814 if (rx < h->num_digits) {
9815 // Read a digit.
9816 n = (10 * n) + h->digits[rx++];
9817 } else if (n == 0) {
9818 // h's number used to be zero and remains zero.
9819 return;
9820 } else {
9821 // Read sufficient implicit trailing zeroes.
9822 while ((n >> shift) == 0) {
9823 n = 10 * n;
9824 rx++;
9825 }
9826 break;
9827 }
9828 }
9829 h->decimal_point -= ((int32_t)(rx - 1));
9830 if (h->decimal_point <
9831 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
9832 // After the shift, h's number is effectively zero.
9833 h->num_digits = 0;
9834 h->decimal_point = 0;
9835 h->negative = false;
9836 h->truncated = false;
9837 return;
9838 }
9839
9840 // Repeat: pick up a digit, put down a digit, left to right.
9841 uint64_t mask = (((uint64_t)(1)) << shift) - 1;
9842 while (rx < h->num_digits) {
9843 uint8_t new_digit = ((uint8_t)(n >> shift));
9844 n = (10 * (n & mask)) + h->digits[rx++];
9845 h->digits[wx++] = new_digit;
9846 }
9847
9848 // Put down trailing digits, left to right.
9849 while (n > 0) {
9850 uint8_t new_digit = ((uint8_t)(n >> shift));
9851 n = 10 * (n & mask);
9852 if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
9853 h->digits[wx++] = new_digit;
9854 } else if (new_digit > 0) {
9855 h->truncated = true;
9856 }
9857 }
9858
9859 // Finish.
9860 h->num_digits = wx;
9861 wuffs_base__private_implementation__high_prec_dec__trim(h);
9862}
9863
9864// --------
9865
9866// The wuffs_base__private_implementation__etc_powers_of_10 tables were printed
9867// by script/print-mpb-powers-of-10.go. That script has an optional -comments
9868// flag, whose output is not copied here, which prints further detail.
9869//
9870// These tables are used in
9871// wuffs_base__private_implementation__medium_prec_bin__assign_from_hpd.
9872
9873// wuffs_base__private_implementation__big_powers_of_10 contains approximations
9874// to the powers of 10, ranging from 1e-348 to 1e+340, with the exponent
9875// stepping by 8: -348, -340, -332, ..., -12, -4, +4, +12, ..., +340. Each step
9876// consists of three uint32_t elements. There are 87 triples, 87 * 3 = 261.
9877//
9878// For example, the third approximation, for 1e-332, consists of the uint32_t
9879// triple (0x3055AC76, 0x8B16FB20, 0xFFFFFB72). The first two of that triple
9880// are a little-endian uint64_t value: 0x8B16FB203055AC76. The last one is an
9881// int32_t value: -1166. Together, they represent the approximation:
9882// 1e-332 ≈ 0x8B16FB203055AC76 * (2 ** -1166)
9883// Similarly, the (0x00000000, 0x9C400000, 0xFFFFFFCE) uint32_t triple means:
9884// 1e+4 ≈ 0x9C40000000000000 * (2 ** -50) // This approx'n is exact.
9885// Similarly, the (0xD4C4FB27, 0xED63A231, 0x000000A2) uint32_t triple means:
9886// 1e+68 ≈ 0xED63A231D4C4FB27 * (2 ** 162)
9887static const uint32_t
9888 wuffs_base__private_implementation__big_powers_of_10[261] = {
9889 0x081C0288, 0xFA8FD5A0, 0xFFFFFB3C, 0xA23EBF76, 0xBAAEE17F, 0xFFFFFB57,
9890 0x3055AC76, 0x8B16FB20, 0xFFFFFB72, 0x5DCE35EA, 0xCF42894A, 0xFFFFFB8C,
9891 0x55653B2D, 0x9A6BB0AA, 0xFFFFFBA7, 0x3D1A45DF, 0xE61ACF03, 0xFFFFFBC1,
9892 0xC79AC6CA, 0xAB70FE17, 0xFFFFFBDC, 0xBEBCDC4F, 0xFF77B1FC, 0xFFFFFBF6,
9893 0x416BD60C, 0xBE5691EF, 0xFFFFFC11, 0x907FFC3C, 0x8DD01FAD, 0xFFFFFC2C,
9894 0x31559A83, 0xD3515C28, 0xFFFFFC46, 0xADA6C9B5, 0x9D71AC8F, 0xFFFFFC61,
9895 0x23EE8BCB, 0xEA9C2277, 0xFFFFFC7B, 0x4078536D, 0xAECC4991, 0xFFFFFC96,
9896 0x5DB6CE57, 0x823C1279, 0xFFFFFCB1, 0x4DFB5637, 0xC2109436, 0xFFFFFCCB,
9897 0x3848984F, 0x9096EA6F, 0xFFFFFCE6, 0x25823AC7, 0xD77485CB, 0xFFFFFD00,
9898 0x97BF97F4, 0xA086CFCD, 0xFFFFFD1B, 0x172AACE5, 0xEF340A98, 0xFFFFFD35,
9899 0x2A35B28E, 0xB23867FB, 0xFFFFFD50, 0xD2C63F3B, 0x84C8D4DF, 0xFFFFFD6B,
9900 0x1AD3CDBA, 0xC5DD4427, 0xFFFFFD85, 0xBB25C996, 0x936B9FCE, 0xFFFFFDA0,
9901 0x7D62A584, 0xDBAC6C24, 0xFFFFFDBA, 0x0D5FDAF6, 0xA3AB6658, 0xFFFFFDD5,
9902 0xDEC3F126, 0xF3E2F893, 0xFFFFFDEF, 0xAAFF80B8, 0xB5B5ADA8, 0xFFFFFE0A,
9903 0x6C7C4A8B, 0x87625F05, 0xFFFFFE25, 0x34C13053, 0xC9BCFF60, 0xFFFFFE3F,
9904 0x91BA2655, 0x964E858C, 0xFFFFFE5A, 0x70297EBD, 0xDFF97724, 0xFFFFFE74,
9905 0xB8E5B88F, 0xA6DFBD9F, 0xFFFFFE8F, 0x88747D94, 0xF8A95FCF, 0xFFFFFEA9,
9906 0x8FA89BCF, 0xB9447093, 0xFFFFFEC4, 0xBF0F156B, 0x8A08F0F8, 0xFFFFFEDF,
9907 0x653131B6, 0xCDB02555, 0xFFFFFEF9, 0xD07B7FAC, 0x993FE2C6, 0xFFFFFF14,
9908 0x2A2B3B06, 0xE45C10C4, 0xFFFFFF2E, 0x697392D3, 0xAA242499, 0xFFFFFF49,
9909 0x8300CA0E, 0xFD87B5F2, 0xFFFFFF63, 0x92111AEB, 0xBCE50864, 0xFFFFFF7E,
9910 0x6F5088CC, 0x8CBCCC09, 0xFFFFFF99, 0xE219652C, 0xD1B71758, 0xFFFFFFB3,
9911 0x00000000, 0x9C400000, 0xFFFFFFCE, 0x00000000, 0xE8D4A510, 0xFFFFFFE8,
9912 0xAC620000, 0xAD78EBC5, 0x00000003, 0xF8940984, 0x813F3978, 0x0000001E,
9913 0xC90715B3, 0xC097CE7B, 0x00000038, 0x7BEA5C70, 0x8F7E32CE, 0x00000053,
9914 0xABE98068, 0xD5D238A4, 0x0000006D, 0x179A2245, 0x9F4F2726, 0x00000088,
9915 0xD4C4FB27, 0xED63A231, 0x000000A2, 0x8CC8ADA8, 0xB0DE6538, 0x000000BD,
9916 0x1AAB65DB, 0x83C7088E, 0x000000D8, 0x42711D9A, 0xC45D1DF9, 0x000000F2,
9917 0xA61BE758, 0x924D692C, 0x0000010D, 0x1A708DEA, 0xDA01EE64, 0x00000127,
9918 0x9AEF774A, 0xA26DA399, 0x00000142, 0xB47D6B85, 0xF209787B, 0x0000015C,
9919 0x79DD1877, 0xB454E4A1, 0x00000177, 0x5B9BC5C2, 0x865B8692, 0x00000192,
9920 0xC8965D3D, 0xC83553C5, 0x000001AC, 0xFA97A0B3, 0x952AB45C, 0x000001C7,
9921 0x99A05FE3, 0xDE469FBD, 0x000001E1, 0xDB398C25, 0xA59BC234, 0x000001FC,
9922 0xA3989F5C, 0xF6C69A72, 0x00000216, 0x54E9BECE, 0xB7DCBF53, 0x00000231,
9923 0xF22241E2, 0x88FCF317, 0x0000024C, 0xD35C78A5, 0xCC20CE9B, 0x00000266,
9924 0x7B2153DF, 0x98165AF3, 0x00000281, 0x971F303A, 0xE2A0B5DC, 0x0000029B,
9925 0x5CE3B396, 0xA8D9D153, 0x000002B6, 0xA4A7443C, 0xFB9B7CD9, 0x000002D0,
9926 0xA7A44410, 0xBB764C4C, 0x000002EB, 0xB6409C1A, 0x8BAB8EEF, 0x00000306,
9927 0xA657842C, 0xD01FEF10, 0x00000320, 0xE9913129, 0x9B10A4E5, 0x0000033B,
9928 0xA19C0C9D, 0xE7109BFB, 0x00000355, 0x623BF429, 0xAC2820D9, 0x00000370,
9929 0x7AA7CF85, 0x80444B5E, 0x0000038B, 0x03ACDD2D, 0xBF21E440, 0x000003A5,
9930 0x5E44FF8F, 0x8E679C2F, 0x000003C0, 0x9C8CB841, 0xD433179D, 0x000003DA,
9931 0xB4E31BA9, 0x9E19DB92, 0x000003F5, 0xBADF77D9, 0xEB96BF6E, 0x0000040F,
9932 0x9BF0EE6B, 0xAF87023B, 0x0000042A,
9933};
9934
9935// wuffs_base__private_implementation__small_powers_of_10 contains
9936// approximations to the powers of 10, ranging from 1e+0 to 1e+7, with the
9937// exponent stepping by 1. Each step consists of three uint32_t elements.
9938//
9939// For example, the third approximation, for 1e+2, consists of the uint32_t
9940// triple (0x00000000, 0xC8000000, 0xFFFFFFC7). The first two of that triple
9941// are a little-endian uint64_t value: 0xC800000000000000. The last one is an
9942// int32_t value: -57. Together, they represent the approximation:
9943// 1e+2 ≈ 0xC800000000000000 * (2 ** -57) // This approx'n is exact.
9944// Similarly, the (0x00000000, 0x9C400000, 0xFFFFFFCE) uint32_t triple means:
9945// 1e+4 ≈ 0x9C40000000000000 * (2 ** -50) // This approx'n is exact.
9946static const uint32_t
9947 wuffs_base__private_implementation__small_powers_of_10[24] = {
9948 0x00000000, 0x80000000, 0xFFFFFFC1, 0x00000000, 0xA0000000, 0xFFFFFFC4,
9949 0x00000000, 0xC8000000, 0xFFFFFFC7, 0x00000000, 0xFA000000, 0xFFFFFFCA,
9950 0x00000000, 0x9C400000, 0xFFFFFFCE, 0x00000000, 0xC3500000, 0xFFFFFFD1,
9951 0x00000000, 0xF4240000, 0xFFFFFFD4, 0x00000000, 0x98968000, 0xFFFFFFD8,
9952};
9953
9954// wuffs_base__private_implementation__f64_powers_of_10 holds powers of 10 that
9955// can be exactly represented by a float64 (what C calls a double).
9956static const double wuffs_base__private_implementation__f64_powers_of_10[23] = {
9957 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
9958 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
9959};
9960
9961// --------
9962
9963// wuffs_base__private_implementation__medium_prec_bin (abbreviated as MPB) is
9964// a fixed precision floating point binary number. Unlike IEEE 754 Floating
9965// Point, it cannot represent infinity or NaN (Not a Number).
9966//
9967// "Medium precision" means that the mantissa holds 64 binary digits, a little
9968// more than "double precision", and sizeof(MPB) > sizeof(double). 64 is
9969// obviously the number of bits in a uint64_t.
9970//
9971// An MPB isn't for general purpose arithmetic, only for conversions to and
9972// from IEEE 754 double-precision floating point.
9973//
9974// There is no implicit mantissa bit. The mantissa field is zero if and only if
9975// the overall floating point value is ±0. An MPB is normalized if the mantissa
9976// is zero or its high bit (the 1<<63 bit) is set.
9977//
9978// There is no negative bit. An MPB can only represent non-negative numbers.
9979//
9980// The "all fields are zero" value is valid, and represents the number +0.
9981//
9982// This is the "Do It Yourself Floating Point" data structure from Loitsch,
9983// "Printing Floating-Point Numbers Quickly and Accurately with Integers"
9984// (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).
9985//
9986// Florian Loitsch is also the primary contributor to
9987// https://github.com/google/double-conversion
9988typedef struct {
9989 uint64_t mantissa;
9990 int32_t exp2;
9991} wuffs_base__private_implementation__medium_prec_bin;
9992
9993static uint32_t //
9994wuffs_base__private_implementation__medium_prec_bin__normalize(
9995 wuffs_base__private_implementation__medium_prec_bin* m) {
9996 if (m->mantissa == 0) {
9997 return 0;
9998 }
9999 uint32_t shift = wuffs_base__count_leading_zeroes_u64(m->mantissa);
10000 m->mantissa <<= shift;
10001 m->exp2 -= (int32_t)shift;
10002 return shift;
10003}
10004
10005// wuffs_base__private_implementation__medium_prec_bin__mul_pow_10 sets m to be
10006// (m * pow), where pow comes from an etc_powers_of_10 triple starting at p.
10007//
10008// The result is rounded, but not necessarily normalized.
10009//
10010// Preconditions:
10011// - m is non-NULL.
10012// - m->mantissa is non-zero.
10013// - m->mantissa's high bit is set (i.e. m is normalized).
10014//
10015// The etc_powers_of_10 triple is already normalized.
10016static void //
10017wuffs_base__private_implementation__medium_prec_bin__mul_pow_10(
10018 wuffs_base__private_implementation__medium_prec_bin* m,
10019 const uint32_t* p) {
10020 uint64_t p_mantissa = ((uint64_t)p[0]) | (((uint64_t)p[1]) << 32);
10021 int32_t p_exp2 = (int32_t)p[2];
10022
10023 wuffs_base__multiply_u64__output o =
10024 wuffs_base__multiply_u64(m->mantissa, p_mantissa);
10025 // Round the mantissa up. It cannot overflow because the maximum possible
10026 // value of o.hi is 0xFFFFFFFFFFFFFFFE.
10027 m->mantissa = o.hi + (o.lo >> 63);
10028 m->exp2 = m->exp2 + p_exp2 + 64;
10029}
10030
10031// wuffs_base__private_implementation__medium_prec_bin__as_f64 converts m to a
10032// double (what C calls a double-precision float64).
10033//
10034// Preconditions:
10035// - m is non-NULL.
10036// - m->mantissa is non-zero.
10037// - m->mantissa's high bit is set (i.e. m is normalized).
10038static double //
10039wuffs_base__private_implementation__medium_prec_bin__as_f64(
10040 const wuffs_base__private_implementation__medium_prec_bin* m,
10041 bool negative) {
10042 uint64_t mantissa64 = m->mantissa;
10043 // An mpb's mantissa has the implicit (binary) decimal point at the right
10044 // hand end of the mantissa's explicit digits. A double-precision's mantissa
10045 // has that decimal point near the left hand end. There's also an explicit
10046 // versus implicit leading 1 bit (binary digit). Together, the difference in
10047 // semantics corresponds to adding 63.
10048 int32_t exp2 = m->exp2 + 63;
10049
10050 // Ensure that exp2 is at least -1022, the minimum double-precision exponent
10051 // for normal (as opposed to subnormal) numbers.
10052 if (-1022 > exp2) {
10053 uint32_t n = (uint32_t)(-1022 - exp2);
10054 mantissa64 >>= n;
10055 exp2 += (int32_t)n;
10056 }
10057
10058 // Extract the (1 + 52) bits from the 64-bit mantissa64. 52 is the number of
10059 // explicit mantissa bits in a double-precision f64.
10060 //
10061 // Before, we have 64 bits and due to normalization, the high bit 'H' is 1.
10062 // 63 55 47 etc 15 7
10063 // H210_9876_5432_1098_7654_etc_etc_etc_5432_1098_7654_3210
10064 // ++++_++++_++++_++++_++++_etc_etc_etc_++++_+..._...._.... Kept bits.
10065 // ...._...._...H_2109_8765_etc_etc_etc_6543_2109_8765_4321 After shifting.
10066 // After, we have 53 bits (and bit #52 is this 'H' bit).
10067 uint64_t mantissa53 = mantissa64 >> 11;
10068
10069 // Round up if the old bit #10 (the highest bit dropped by shifting) was set.
10070 // We also fix any overflow from rounding up.
10071 if (mantissa64 & 1024) {
10072 mantissa53++;
10073 if ((mantissa53 >> 53) != 0) {
10074 mantissa53 >>= 1;
10075 exp2++;
10076 }
10077 }
10078
10079 // Handle double-precision infinity (a nominal exponent of 1024) and
10080 // subnormals (an exponent of -1023 and no implicit mantissa bit, bit #52).
10081 if (exp2 >= 1024) {
10082 mantissa53 = 0;
10083 exp2 = 1024;
10084 } else if ((mantissa53 >> 52) == 0) {
10085 exp2 = -1023;
10086 }
10087
10088 // Pack the bits and return.
10089 const int32_t f64_bias = -1023;
10090 uint64_t exp2_bits =
10091 (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
10092 uint64_t bits = (mantissa53 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
10093 (exp2_bits << 52) | //
10094 (negative ? 0x8000000000000000 : 0); // (1 << 63).
10095 return wuffs_base__ieee_754_bit_representation__to_f64(bits);
10096}
10097
10098// wuffs_base__private_implementation__medium_prec_bin__parse_number_f64
10099// converts from an HPD to a double, using an MPB as scratch space. It returns
10100// a NULL status.repr if there is no ambiguity in the truncation or rounding to
10101// a float64 (an IEEE 754 double-precision floating point value).
10102//
10103// It may modify m even if it returns a non-NULL status.repr.
10104static wuffs_base__result_f64 //
10105wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(
10106 wuffs_base__private_implementation__medium_prec_bin* m,
10107 const wuffs_base__private_implementation__high_prec_dec* h,
10108 bool skip_fast_path_for_tests) {
10109 do {
10110 // m->mantissa is a uint64_t, which is an integer approximation to a
10111 // rational value - h's underlying digits after m's normalization. This
10112 // error is an upper bound on the difference between the approximate and
10113 // actual value.
10114 //
10115 // The DiyFpStrtod function in https://github.com/google/double-conversion
10116 // uses a finer grain (1/8th of the ULP, Unit in the Last Place) when
10117 // tracking error. This implementation is coarser (1 ULP) but simpler.
10118 //
10119 // It is an error in the "numerical approximation" sense, not in the
10120 // typical programming sense (as in "bad input" or "a result type").
10121 uint64_t error = 0;
10122
10123 // Convert up to 19 decimal digits (in h->digits) to 64 binary digits (in
10124 // m->mantissa): (1e19 < (1<<64)) and ((1<<64) < 1e20). If we have more
10125 // than 19 digits, we're truncating (with error).
10126 uint32_t i;
10127 uint32_t i_end = h->num_digits;
10128 if (i_end > 19) {
10129 i_end = 19;
10130 error = 1;
10131 }
10132 uint64_t mantissa = 0;
10133 for (i = 0; i < i_end; i++) {
10134 mantissa = (10 * mantissa) + h->digits[i];
10135 }
10136 m->mantissa = mantissa;
10137 m->exp2 = 0;
10138
10139 // Check that exp10 lies in the (big_powers_of_10 + small_powers_of_10)
10140 // range, -348 ..= +347, stepping big_powers_of_10 by 8 (which is 87
10141 // triples) and small_powers_of_10 by 1 (which is 8 triples).
10142 int32_t exp10 = h->decimal_point - ((int32_t)(i_end));
10143 if (exp10 < -348) {
10144 goto fail;
10145 }
10146 uint32_t bpo10 = ((uint32_t)(exp10 + 348)) / 8;
10147 uint32_t spo10 = ((uint32_t)(exp10 + 348)) % 8;
10148 if (bpo10 >= 87) {
10149 goto fail;
10150 }
10151
10152 // Try a fast path, if float64 math would be exact.
10153 //
10154 // 15 is such that 1e15 can be losslessly represented in a float64
10155 // mantissa: (1e15 < (1<<53)) and ((1<<53) < 1e16).
10156 //
10157 // 22 is the maximum valid index for the
10158 // wuffs_base__private_implementation__f64_powers_of_10 array.
10159 do {
10160 if (skip_fast_path_for_tests || ((mantissa >> 52) != 0)) {
10161 break;
10162 }
10163 double d = (double)mantissa;
10164
10165 if (exp10 == 0) {
10166 wuffs_base__result_f64 ret;
10167 ret.status.repr = NULL;
10168 ret.value = h->negative ? -d : +d;
10169 return ret;
10170
10171 } else if (exp10 > 0) {
10172 if (exp10 > 22) {
10173 if (exp10 > (15 + 22)) {
10174 break;
10175 }
10176 // If exp10 is in the range 23 ..= 37, try moving a few of the zeroes
10177 // from the exponent to the mantissa. If we're still under 1e15, we
10178 // haven't truncated any mantissa bits.
10179 if (exp10 > 22) {
10180 d *= wuffs_base__private_implementation__f64_powers_of_10[exp10 -
10181 22];
10182 exp10 = 22;
10183 if (d >= 1e15) {
10184 break;
10185 }
10186 }
10187 }
10188 d *= wuffs_base__private_implementation__f64_powers_of_10[exp10];
10189 wuffs_base__result_f64 ret;
10190 ret.status.repr = NULL;
10191 ret.value = h->negative ? -d : +d;
10192 return ret;
10193
10194 } else { // "if (exp10 < 0)" is effectively "if (true)" here.
10195 if (exp10 < -22) {
10196 break;
10197 }
10198 d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];
10199 wuffs_base__result_f64 ret;
10200 ret.status.repr = NULL;
10201 ret.value = h->negative ? -d : +d;
10202 return ret;
10203 }
10204 } while (0);
10205
10206 // Normalize (and scale the error).
10207 error <<= wuffs_base__private_implementation__medium_prec_bin__normalize(m);
10208
10209 // Multiplying two MPB values nominally multiplies two mantissas, call them
10210 // A and B, which are integer approximations to the precise values (A+a)
10211 // and (B+b) for some error terms a and b.
10212 //
10213 // MPB multiplication calculates (((A+a) * (B+b)) >> 64) to be ((A*B) >>
10214 // 64). Shifting (truncating) and rounding introduces further error. The
10215 // difference between the calculated result:
10216 // ((A*B ) >> 64)
10217 // and the true result:
10218 // ((A*B + A*b + a*B + a*b) >> 64) + rounding_error
10219 // is:
10220 // (( A*b + a*B + a*b) >> 64) + rounding_error
10221 // which can be re-grouped as:
10222 // ((A*b) >> 64) + ((a*(B+b)) >> 64) + rounding_error
10223 //
10224 // Now, let A and a be "m->mantissa" and "error", and B and b be the
10225 // pre-calculated power of 10. A and B are both less than (1 << 64), a is
10226 // the "error" local variable and b is less than 1.
10227 //
10228 // An upper bound (in absolute value) on ((A*b) >> 64) is therefore 1.
10229 //
10230 // An upper bound on ((a*(B+b)) >> 64) is a, also known as error.
10231 //
10232 // Finally, the rounding_error is at most 1.
10233 //
10234 // In total, calling mpb__mul_pow_10 will raise the worst-case error by 2.
10235 // The subsequent re-normalization can multiply that by a further factor.
10236
10237 // Multiply by small_powers_of_10[etc].
10238 wuffs_base__private_implementation__medium_prec_bin__mul_pow_10(
10239 m, &wuffs_base__private_implementation__small_powers_of_10[3 * spo10]);
10240 error += 2;
10241 error <<= wuffs_base__private_implementation__medium_prec_bin__normalize(m);
10242
10243 // Multiply by big_powers_of_10[etc].
10244 wuffs_base__private_implementation__medium_prec_bin__mul_pow_10(
10245 m, &wuffs_base__private_implementation__big_powers_of_10[3 * bpo10]);
10246 error += 2;
10247 error <<= wuffs_base__private_implementation__medium_prec_bin__normalize(m);
10248
10249 // We have a good approximation of h, but we still have to check whether
10250 // the error is small enough. Equivalently, whether the number of surplus
10251 // mantissa bits (the bits dropped when going from m's 64 mantissa bits to
10252 // the smaller number of double-precision mantissa bits) would always round
10253 // up or down, even when perturbed by ±error. We start at 11 surplus bits
10254 // (m has 64, double-precision has 1+52), but it can be higher for
10255 // subnormals.
10256 //
10257 // In many cases, the error is small enough and we return true.
10258 const int32_t f64_bias = -1023;
10259 int32_t subnormal_exp2 = f64_bias - 63;
10260 uint32_t surplus_bits = 11;
10261 if (subnormal_exp2 >= m->exp2) {
10262 surplus_bits += 1 + ((uint32_t)(subnormal_exp2 - m->exp2));
10263 }
10264
10265 uint64_t surplus_mask =
10266 (((uint64_t)1) << surplus_bits) - 1; // e.g. 0x07FF.
10267 uint64_t surplus = m->mantissa & surplus_mask;
10268 uint64_t halfway = ((uint64_t)1) << (surplus_bits - 1); // e.g. 0x0400.
10269
10270 // Do the final calculation in *signed* arithmetic.
10271 int64_t i_surplus = (int64_t)surplus;
10272 int64_t i_halfway = (int64_t)halfway;
10273 int64_t i_error = (int64_t)error;
10274
10275 if ((i_surplus > (i_halfway - i_error)) &&
10276 (i_surplus < (i_halfway + i_error))) {
10277 goto fail;
10278 }
10279
10280 wuffs_base__result_f64 ret;
10281 ret.status.repr = NULL;
10282 ret.value = wuffs_base__private_implementation__medium_prec_bin__as_f64(
10283 m, h->negative);
10284 return ret;
10285 } while (0);
10286
10287fail:
10288 do {
10289 wuffs_base__result_f64 ret;
10290 ret.status.repr = "#base: mpb__parse_number_f64 failed";
10291 ret.value = 0;
10292 return ret;
10293 } while (0);
10294}
10295
10296// --------
10297
10298static wuffs_base__result_f64 //
10299wuffs_base__parse_number_f64_special(wuffs_base__slice_u8 s,
10300 const char* fallback_status_repr) {
10301 do {
10302 uint8_t* p = s.ptr;
10303 uint8_t* q = s.ptr + s.len;
10304
10305 for (; (p < q) && (*p == '_'); p++) {
10306 }
10307 if (p >= q) {
10308 goto fallback;
10309 }
10310
10311 // Parse sign.
10312 bool negative = false;
10313 do {
10314 if (*p == '+') {
10315 p++;
10316 } else if (*p == '-') {
10317 negative = true;
10318 p++;
10319 } else {
10320 break;
10321 }
10322 for (; (p < q) && (*p == '_'); p++) {
10323 }
10324 } while (0);
10325 if (p >= q) {
10326 goto fallback;
10327 }
10328
10329 bool nan = false;
10330 switch (p[0]) {
10331 case 'I':
10332 case 'i':
10333 if (((q - p) < 3) || //
10334 ((p[1] != 'N') && (p[1] != 'n')) || //
10335 ((p[2] != 'F') && (p[2] != 'f'))) {
10336 goto fallback;
10337 }
10338 p += 3;
10339
10340 if ((p >= q) || (*p == '_')) {
10341 break;
10342 } else if (((q - p) < 5) || //
10343 ((p[0] != 'I') && (p[0] != 'i')) || //
10344 ((p[1] != 'N') && (p[1] != 'n')) || //
10345 ((p[2] != 'I') && (p[2] != 'i')) || //
10346 ((p[3] != 'T') && (p[3] != 't')) || //
10347 ((p[4] != 'Y') && (p[4] != 'y'))) {
10348 goto fallback;
10349 }
10350 p += 5;
10351
10352 if ((p >= q) || (*p == '_')) {
10353 break;
10354 }
10355 goto fallback;
10356
10357 case 'N':
10358 case 'n':
10359 if (((q - p) < 3) || //
10360 ((p[1] != 'A') && (p[1] != 'a')) || //
10361 ((p[2] != 'N') && (p[2] != 'n'))) {
10362 goto fallback;
10363 }
10364 p += 3;
10365
10366 if ((p >= q) || (*p == '_')) {
10367 nan = true;
10368 break;
10369 }
10370 goto fallback;
10371
10372 default:
10373 goto fallback;
10374 }
10375
10376 // Finish.
10377 for (; (p < q) && (*p == '_'); p++) {
10378 }
10379 if (p != q) {
10380 goto fallback;
10381 }
10382 wuffs_base__result_f64 ret;
10383 ret.status.repr = NULL;
10384 ret.value = wuffs_base__ieee_754_bit_representation__to_f64(
10385 (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |
10386 (negative ? 0x8000000000000000 : 0));
10387 return ret;
10388 } while (0);
10389
10390fallback:
10391 do {
10392 wuffs_base__result_f64 ret;
10393 ret.status.repr = fallback_status_repr;
10394 ret.value = 0;
10395 return ret;
10396 } while (0);
10397}
10398
10399WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
10400wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
10401 wuffs_base__private_implementation__medium_prec_bin m;
10402 wuffs_base__private_implementation__high_prec_dec h;
10403
10404 do {
10405 // powers converts decimal powers of 10 to binary powers of 2. For example,
10406 // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
10407 // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
10408 static const uint32_t num_powers = 19;
10409 static const uint8_t powers[19] = {
10410 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, //
10411 33, 36, 39, 43, 46, 49, 53, 56, 59, //
10412 };
10413
10414 wuffs_base__status status =
10415 wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
10416 if (status.repr) {
10417 return wuffs_base__parse_number_f64_special(s, status.repr);
10418 }
10419
10420 // Handle zero and obvious extremes. The largest and smallest positive
10421 // finite f64 values are approximately 1.8e+308 and 4.9e-324.
10422 if ((h.num_digits == 0) || (h.decimal_point < -326)) {
10423 goto zero;
10424 } else if (h.decimal_point > 310) {
10425 goto infinity;
10426 }
10427
10428 wuffs_base__result_f64 mpb_result =
10429 wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(
10430 &m, &h, false);
10431 if (mpb_result.status.repr == NULL) {
10432 return mpb_result;
10433 }
10434
10435 // Scale by powers of 2 until we're in the range [½ .. 1], which gives us
10436 // our exponent (in base-2). First we shift right, possibly a little too
10437 // far, ending with a value certainly below 1 and possibly below ½...
10438 const int32_t f64_bias = -1023;
10439 int32_t exp2 = 0;
10440 while (h.decimal_point > 0) {
10441 uint32_t n = (uint32_t)(+h.decimal_point);
10442 uint32_t shift =
10443 (n < num_powers)
10444 ? powers[n]
10445 : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
10446
10447 wuffs_base__private_implementation__high_prec_dec__small_rshift(&h,
10448 shift);
10449 if (h.decimal_point <
10450 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
10451 goto zero;
10452 }
10453 exp2 += (int32_t)shift;
10454 }
10455 // ...then we shift left, putting us in [½ .. 1].
10456 while (h.decimal_point <= 0) {
10457 uint32_t shift;
10458 if (h.decimal_point == 0) {
10459 if (h.digits[0] >= 5) {
10460 break;
10461 }
10462 shift = (h.digits[0] <= 2) ? 2 : 1;
10463 } else {
10464 uint32_t n = (uint32_t)(-h.decimal_point);
10465 shift = (n < num_powers)
10466 ? powers[n]
10467 : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
10468 }
10469
10470 wuffs_base__private_implementation__high_prec_dec__small_lshift(&h,
10471 shift);
10472 if (h.decimal_point >
10473 +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
10474 goto infinity;
10475 }
10476 exp2 -= (int32_t)shift;
10477 }
10478
10479 // We're in the range [½ .. 1] but f64 uses [1 .. 2].
10480 exp2--;
10481
10482 // The minimum normal exponent is (f64_bias + 1).
10483 while ((f64_bias + 1) > exp2) {
10484 uint32_t n = (uint32_t)((f64_bias + 1) - exp2);
10485 if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
10486 n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
10487 }
10488 wuffs_base__private_implementation__high_prec_dec__small_rshift(&h, n);
10489 exp2 += (int32_t)n;
10490 }
10491
10492 // Check for overflow.
10493 if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
10494 goto infinity;
10495 }
10496
10497 // Extract 53 bits for the mantissa (in base-2).
10498 wuffs_base__private_implementation__high_prec_dec__small_lshift(&h, 53);
10499 uint64_t man2 =
10500 wuffs_base__private_implementation__high_prec_dec__rounded_integer(&h);
10501
10502 // Rounding might have added one bit. If so, shift and re-check overflow.
10503 if ((man2 >> 53) != 0) {
10504 man2 >>= 1;
10505 exp2++;
10506 if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
10507 goto infinity;
10508 }
10509 }
10510
10511 // Handle subnormal numbers.
10512 if ((man2 >> 52) == 0) {
10513 exp2 = f64_bias;
10514 }
10515
10516 // Pack the bits and return.
10517 uint64_t exp2_bits =
10518 (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
10519 uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
10520 (exp2_bits << 52) | //
10521 (h.negative ? 0x8000000000000000 : 0); // (1 << 63).
10522
10523 wuffs_base__result_f64 ret;
10524 ret.status.repr = NULL;
10525 ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);
10526 return ret;
10527 } while (0);
10528
10529zero:
10530 do {
10531 uint64_t bits = h.negative ? 0x8000000000000000 : 0;
10532
10533 wuffs_base__result_f64 ret;
10534 ret.status.repr = NULL;
10535 ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);
10536 return ret;
10537 } while (0);
10538
10539infinity:
10540 do {
10541 uint64_t bits = h.negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
10542
10543 wuffs_base__result_f64 ret;
10544 ret.status.repr = NULL;
10545 ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);
10546 return ret;
10547 } while (0);
10548}
10549
10550#endif // !defined(WUFFS_CONFIG__MODULES) ||
10551 // defined(WUFFS_CONFIG__MODULE__BASE) ||
10552 // defined(WUFFS_CONFIG__MODULE__BASE__F64CONV)
10553
10554#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
10555 defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
10556
10557// ---------------- Pixel Swizzler
10558
10559static inline uint32_t //
10560wuffs_base__swap_u32_argb_abgr(uint32_t u) {
10561 uint32_t o = u & 0xFF00FF00;
10562 uint32_t r = u & 0x00FF0000;
10563 uint32_t b = u & 0x000000FF;
10564 return o | (r >> 16) | (b << 16);
10565}
10566
10567// --------
10568
10569WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
10570wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
10571 uint32_t x,
10572 uint32_t y) {
10573 if (!pb || (x >= pb->pixcfg.private_impl.width) ||
10574 (y >= pb->pixcfg.private_impl.height)) {
10575 return 0;
10576 }
10577
10578 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
10579 // TODO: support planar formats.
10580 return 0;
10581 }
10582
10583 size_t stride = pb->private_impl.planes[0].stride;
10584 const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
10585
10586 switch (pb->pixcfg.private_impl.pixfmt.repr) {
10587 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
10588 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
10589 return wuffs_base__load_u32le__no_bounds_check(row + (4 * ((size_t)x)));
10590
10591 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
10592 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
10593 uint8_t* palette = pb->private_impl.planes[3].ptr;
10594 return wuffs_base__load_u32le__no_bounds_check(palette +
10595 (4 * ((size_t)row[x])));
10596 }
10597
10598 // Common formats above. Rarer formats below.
10599
10600 case WUFFS_BASE__PIXEL_FORMAT__Y:
10601 return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x])));
10602
10603 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: {
10604 uint8_t* palette = pb->private_impl.planes[3].ptr;
10605 return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
10606 wuffs_base__load_u32le__no_bounds_check(palette +
10607 (4 * ((size_t)row[x]))));
10608 }
10609
10610 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
10611 return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
10612 wuffs_base__load_u16le__no_bounds_check(row + (2 * ((size_t)x))));
10613 case WUFFS_BASE__PIXEL_FORMAT__BGR:
10614 return 0xFF000000 |
10615 wuffs_base__load_u24le__no_bounds_check(row + (3 * ((size_t)x)));
10616 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
10617 return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
10618 wuffs_base__load_u32le__no_bounds_check(row + (4 * ((size_t)x))));
10619 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
10620 return 0xFF000000 |
10621 wuffs_base__load_u32le__no_bounds_check(row + (4 * ((size_t)x)));
10622
10623 case WUFFS_BASE__PIXEL_FORMAT__RGB:
10624 return wuffs_base__swap_u32_argb_abgr(
10625 0xFF000000 |
10626 wuffs_base__load_u24le__no_bounds_check(row + (3 * ((size_t)x))));
10627 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
10628 return wuffs_base__swap_u32_argb_abgr(
10629 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
10630 wuffs_base__load_u32le__no_bounds_check(row +
10631 (4 * ((size_t)x)))));
10632 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
10633 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
10634 return wuffs_base__swap_u32_argb_abgr(
10635 wuffs_base__load_u32le__no_bounds_check(row + (4 * ((size_t)x))));
10636 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
10637 return wuffs_base__swap_u32_argb_abgr(
10638 0xFF000000 |
10639 wuffs_base__load_u32le__no_bounds_check(row + (4 * ((size_t)x))));
10640
10641 default:
10642 // TODO: support more formats.
10643 break;
10644 }
10645
10646 return 0;
10647}
10648
10649WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
10650wuffs_base__pixel_buffer__set_color_u32_at(
10651 wuffs_base__pixel_buffer* pb,
10652 uint32_t x,
10653 uint32_t y,
10654 wuffs_base__color_u32_argb_premul color) {
10655 if (!pb) {
10656 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
10657 }
10658 if ((x >= pb->pixcfg.private_impl.width) ||
10659 (y >= pb->pixcfg.private_impl.height)) {
10660 return wuffs_base__make_status(wuffs_base__error__bad_argument);
10661 }
10662
10663 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
10664 // TODO: support planar formats.
10665 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
10666 }
10667
10668 size_t stride = pb->private_impl.planes[0].stride;
10669 uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
10670
10671 switch (pb->pixcfg.private_impl.pixfmt.repr) {
10672 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
10673 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
10674 wuffs_base__store_u32le__no_bounds_check(row + (4 * ((size_t)x)), color);
10675 break;
10676
10677 // Common formats above. Rarer formats below.
10678
10679 case WUFFS_BASE__PIXEL_FORMAT__Y:
10680 wuffs_base__store_u8__no_bounds_check(
10681 row + ((size_t)x),
10682 wuffs_base__color_u32_argb_premul__as__color_u8_gray(color));
10683 break;
10684
10685 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
10686 wuffs_base__store_u8__no_bounds_check(
10687 row + ((size_t)x), wuffs_base__pixel_palette__closest_element(
10688 wuffs_base__pixel_buffer__palette(pb),
10689 pb->pixcfg.private_impl.pixfmt, color));
10690 break;
10691
10692 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
10693 wuffs_base__store_u16le__no_bounds_check(
10694 row + (2 * ((size_t)x)),
10695 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
10696 break;
10697 case WUFFS_BASE__PIXEL_FORMAT__BGR:
10698 wuffs_base__store_u24le__no_bounds_check(row + (3 * ((size_t)x)), color);
10699 break;
10700 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
10701 wuffs_base__store_u32le__no_bounds_check(
10702 row + (4 * ((size_t)x)),
10703 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
10704 color));
10705 break;
10706
10707 case WUFFS_BASE__PIXEL_FORMAT__RGB:
10708 wuffs_base__store_u24le__no_bounds_check(
10709 row + (3 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
10710 break;
10711 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
10712 wuffs_base__store_u32le__no_bounds_check(
10713 row + (4 * ((size_t)x)),
10714 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
10715 wuffs_base__swap_u32_argb_abgr(color)));
10716 break;
10717 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
10718 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
10719 wuffs_base__store_u32le__no_bounds_check(
10720 row + (4 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
10721 break;
10722
10723 default:
10724 // TODO: support more formats.
10725 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
10726 }
10727
10728 return wuffs_base__make_status(NULL);
10729}
10730
10731// --------
10732
10733WUFFS_BASE__MAYBE_STATIC uint8_t //
10734wuffs_base__pixel_palette__closest_element(
10735 wuffs_base__slice_u8 palette_slice,
10736 wuffs_base__pixel_format palette_format,
10737 wuffs_base__color_u32_argb_premul c) {
10738 size_t n = palette_slice.len / 4;
10739 if (n > 256) {
10740 n = 256;
10741 }
10742 size_t best_index = 0;
10743 uint64_t best_score = 0xFFFFFFFFFFFFFFFF;
10744
10745 // Work in 16-bit color.
10746 uint32_t ca = 0x101 * (0xFF & (c >> 24));
10747 uint32_t cr = 0x101 * (0xFF & (c >> 16));
10748 uint32_t cg = 0x101 * (0xFF & (c >> 8));
10749 uint32_t cb = 0x101 * (0xFF & (c >> 0));
10750
10751 switch (palette_format.repr) {
10752 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
10753 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
10754 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
10755 bool nonpremul = palette_format.repr ==
10756 WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL;
10757
10758 size_t i;
10759 for (i = 0; i < n; i++) {
10760 // Work in 16-bit color.
10761 uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0]));
10762 uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1]));
10763 uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2]));
10764 uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3]));
10765
10766 // Convert to premultiplied alpha.
10767 if (nonpremul && (pa != 0xFFFF)) {
10768 pb = (pb * pa) / 0xFFFF;
10769 pg = (pg * pa) / 0xFFFF;
10770 pr = (pr * pa) / 0xFFFF;
10771 }
10772
10773 // These deltas are conceptually int32_t (signed) but after squaring,
10774 // it's equivalent to work in uint32_t (unsigned).
10775 pb -= cb;
10776 pg -= cg;
10777 pr -= cr;
10778 pa -= ca;
10779 uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) +
10780 ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa));
10781 if (best_score > score) {
10782 best_score = score;
10783 best_index = i;
10784 }
10785 }
10786 break;
10787 }
10788 }
10789
10790 return (uint8_t)best_index;
10791}
10792
10793// --------
10794
10795static inline uint32_t //
10796wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,
10797 uint32_t src_nonpremul) {
10798 // Convert from 8-bit color to 16-bit color.
10799 uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
10800 uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
10801 uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
10802 uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
10803 uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
10804 uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
10805 uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
10806 uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
10807
10808 // Convert dst from nonpremul to premul.
10809 dr = (dr * da) / 0xFFFF;
10810 dg = (dg * da) / 0xFFFF;
10811 db = (db * da) / 0xFFFF;
10812
10813 // Calculate the inverse of the src-alpha: how much of the dst to keep.
10814 uint32_t ia = 0xFFFF - sa;
10815
10816 // Composite src (nonpremul) over dst (premul).
10817 da = sa + ((da * ia) / 0xFFFF);
10818 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
10819 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
10820 db = ((sb * sa) + (db * ia)) / 0xFFFF;
10821
10822 // Convert dst from premul to nonpremul.
10823 if (da != 0) {
10824 dr = (dr * 0xFFFF) / da;
10825 dg = (dg * 0xFFFF) / da;
10826 db = (db * 0xFFFF) / da;
10827 }
10828
10829 // Convert from 16-bit color to 8-bit color and combine the components.
10830 da >>= 8;
10831 dr >>= 8;
10832 dg >>= 8;
10833 db >>= 8;
10834 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
10835}
10836
10837static inline uint32_t //
10838wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,
10839 uint32_t src_premul) {
10840 // Convert from 8-bit color to 16-bit color.
10841 uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
10842 uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
10843 uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
10844 uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
10845 uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
10846 uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
10847 uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
10848 uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
10849
10850 // Convert dst from nonpremul to premul.
10851 dr = (dr * da) / 0xFFFF;
10852 dg = (dg * da) / 0xFFFF;
10853 db = (db * da) / 0xFFFF;
10854
10855 // Calculate the inverse of the src-alpha: how much of the dst to keep.
10856 uint32_t ia = 0xFFFF - sa;
10857
10858 // Composite src (premul) over dst (premul).
10859 da = sa + ((da * ia) / 0xFFFF);
10860 dr = sr + ((dr * ia) / 0xFFFF);
10861 dg = sg + ((dg * ia) / 0xFFFF);
10862 db = sb + ((db * ia) / 0xFFFF);
10863
10864 // Convert dst from premul to nonpremul.
10865 if (da != 0) {
10866 dr = (dr * 0xFFFF) / da;
10867 dg = (dg * 0xFFFF) / da;
10868 db = (db * 0xFFFF) / da;
10869 }
10870
10871 // Convert from 16-bit color to 8-bit color and combine the components.
10872 da >>= 8;
10873 dr >>= 8;
10874 dg >>= 8;
10875 db >>= 8;
10876 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
10877}
10878
10879static inline uint32_t //
10880wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,
10881 uint32_t src_nonpremul) {
10882 // Convert from 8-bit color to 16-bit color.
10883 uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
10884 uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
10885 uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
10886 uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
10887 uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
10888 uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
10889 uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
10890 uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
10891
10892 // Calculate the inverse of the src-alpha: how much of the dst to keep.
10893 uint32_t ia = 0xFFFF - sa;
10894
10895 // Composite src (nonpremul) over dst (premul).
10896 da = sa + ((da * ia) / 0xFFFF);
10897 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
10898 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
10899 db = ((sb * sa) + (db * ia)) / 0xFFFF;
10900
10901 // Convert from 16-bit color to 8-bit color and combine the components.
10902 da >>= 8;
10903 dr >>= 8;
10904 dg >>= 8;
10905 db >>= 8;
10906 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
10907}
10908
10909static inline uint32_t //
10910wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,
10911 uint32_t src_premul) {
10912 // Convert from 8-bit color to 16-bit color.
10913 uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
10914 uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
10915 uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
10916 uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
10917 uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
10918 uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
10919 uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
10920 uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
10921
10922 // Calculate the inverse of the src-alpha: how much of the dst to keep.
10923 uint32_t ia = 0xFFFF - sa;
10924
10925 // Composite src (premul) over dst (premul).
10926 da = sa + ((da * ia) / 0xFFFF);
10927 dr = sr + ((dr * ia) / 0xFFFF);
10928 dg = sg + ((dg * ia) / 0xFFFF);
10929 db = sb + ((db * ia) / 0xFFFF);
10930
10931 // Convert from 16-bit color to 8-bit color and combine the components.
10932 da >>= 8;
10933 dr >>= 8;
10934 dg >>= 8;
10935 db >>= 8;
10936 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
10937}
10938
10939// --------
10940
10941static uint64_t //
10942wuffs_base__pixel_swizzler__squash_bgr_565_888(wuffs_base__slice_u8 dst,
10943 wuffs_base__slice_u8 src) {
10944 size_t len4 = (dst.len < src.len ? dst.len : src.len) / 4;
10945 uint8_t* d = dst.ptr;
10946 const uint8_t* s = src.ptr;
10947
10948 size_t n = len4;
10949 while (n--) {
10950 uint32_t argb = wuffs_base__load_u32le__no_bounds_check(s);
10951 uint32_t b5 = 0x1F & (argb >> (8 - 5));
10952 uint32_t g6 = 0x3F & (argb >> (16 - 6));
10953 uint32_t r5 = 0x1F & (argb >> (24 - 5));
10954 uint32_t alpha = argb & 0xFF000000;
10955 wuffs_base__store_u32le__no_bounds_check(
10956 d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0));
10957 s += 4;
10958 d += 4;
10959 }
10960 return len4 * 4;
10961}
10962
10963static uint64_t //
10964wuffs_base__pixel_swizzler__swap_rgbx_bgrx(wuffs_base__slice_u8 dst,
10965 wuffs_base__slice_u8 src) {
10966 size_t len4 = (dst.len < src.len ? dst.len : src.len) / 4;
10967 uint8_t* d = dst.ptr;
10968 const uint8_t* s = src.ptr;
10969
10970 size_t n = len4;
10971 while (n--) {
10972 uint8_t b0 = s[0];
10973 uint8_t b1 = s[1];
10974 uint8_t b2 = s[2];
10975 uint8_t b3 = s[3];
10976 d[0] = b2;
10977 d[1] = b1;
10978 d[2] = b0;
10979 d[3] = b3;
10980 s += 4;
10981 d += 4;
10982 }
10983 return len4 * 4;
10984}
10985
10986// --------
10987
10988static uint64_t //
10989wuffs_base__pixel_swizzler__copy_1_1(uint8_t* dst_ptr,
10990 size_t dst_len,
10991 uint8_t* dst_palette_ptr,
10992 size_t dst_palette_len,
10993 const uint8_t* src_ptr,
10994 size_t src_len) {
10995 size_t len = (dst_len < src_len) ? dst_len : src_len;
10996 if (len > 0) {
10997 memmove(dst_ptr, src_ptr, len);
10998 }
10999 return len;
11000}
11001
11002static uint64_t //
11003wuffs_base__pixel_swizzler__copy_3_3(uint8_t* dst_ptr,
11004 size_t dst_len,
11005 uint8_t* dst_palette_ptr,
11006 size_t dst_palette_len,
11007 const uint8_t* src_ptr,
11008 size_t src_len) {
11009 size_t dst_len3 = dst_len / 3;
11010 size_t src_len3 = src_len / 3;
11011 size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3;
11012 if (len > 0) {
11013 memmove(dst_ptr, src_ptr, len * 3);
11014 }
11015 return len;
11016}
11017
11018static uint64_t //
11019wuffs_base__pixel_swizzler__copy_4_4(uint8_t* dst_ptr,
11020 size_t dst_len,
11021 uint8_t* dst_palette_ptr,
11022 size_t dst_palette_len,
11023 const uint8_t* src_ptr,
11024 size_t src_len) {
11025 size_t dst_len4 = dst_len / 4;
11026 size_t src_len4 = src_len / 4;
11027 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
11028 if (len > 0) {
11029 memmove(dst_ptr, src_ptr, len * 4);
11030 }
11031 return len;
11032}
11033
11034// --------
11035
11036static uint64_t //
11037wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t* dst_ptr,
11038 size_t dst_len,
11039 uint8_t* dst_palette_ptr,
11040 size_t dst_palette_len,
11041 const uint8_t* src_ptr,
11042 size_t src_len) {
11043 size_t dst_len2 = dst_len / 2;
11044 size_t src_len3 = src_len / 3;
11045 size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
11046 uint8_t* d = dst_ptr;
11047 const uint8_t* s = src_ptr;
11048 size_t n = len;
11049
11050 // TODO: unroll.
11051
11052 while (n >= 1) {
11053 uint32_t b5 = s[0] >> 3;
11054 uint32_t g6 = s[1] >> 2;
11055 uint32_t r5 = s[2] >> 3;
11056 uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
11057 wuffs_base__store_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
11058
11059 s += 1 * 3;
11060 d += 1 * 2;
11061 n -= 1;
11062 }
11063
11064 return len;
11065}
11066
11067static uint64_t //
11068wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(
11069 uint8_t* dst_ptr,
11070 size_t dst_len,
11071 uint8_t* dst_palette_ptr,
11072 size_t dst_palette_len,
11073 const uint8_t* src_ptr,
11074 size_t src_len) {
11075 size_t dst_len2 = dst_len / 2;
11076 size_t src_len4 = src_len / 4;
11077 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
11078 uint8_t* d = dst_ptr;
11079 const uint8_t* s = src_ptr;
11080 size_t n = len;
11081
11082 // TODO: unroll.
11083
11084 while (n >= 1) {
11085 wuffs_base__store_u16le__no_bounds_check(
11086 d + (0 * 2),
11087 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
11088 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
11089 wuffs_base__load_u32le__no_bounds_check(s + (0 * 4)))));
11090
11091 s += 1 * 4;
11092 d += 1 * 2;
11093 n -= 1;
11094 }
11095
11096 return len;
11097}
11098
11099static uint64_t //
11100wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(
11101 uint8_t* dst_ptr,
11102 size_t dst_len,
11103 uint8_t* dst_palette_ptr,
11104 size_t dst_palette_len,
11105 const uint8_t* src_ptr,
11106 size_t src_len) {
11107 size_t dst_len2 = dst_len / 2;
11108 size_t src_len4 = src_len / 4;
11109 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
11110 uint8_t* d = dst_ptr;
11111 const uint8_t* s = src_ptr;
11112 size_t n = len;
11113
11114 // TODO: unroll.
11115
11116 while (n >= 1) {
11117 // Convert from 8-bit color to 16-bit color.
11118 uint32_t sa = 0x101 * ((uint32_t)s[3]);
11119 uint32_t sr = 0x101 * ((uint32_t)s[2]);
11120 uint32_t sg = 0x101 * ((uint32_t)s[1]);
11121 uint32_t sb = 0x101 * ((uint32_t)s[0]);
11122
11123 // Convert from 565 color to 16-bit color.
11124 uint32_t old_rgb_565 = wuffs_base__load_u16le__no_bounds_check(d + (0 * 2));
11125 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
11126 uint32_t dr = (0x8421 * old_r5) >> 4;
11127 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
11128 uint32_t dg = (0x1041 * old_g6) >> 2;
11129 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
11130 uint32_t db = (0x8421 * old_b5) >> 4;
11131
11132 // Calculate the inverse of the src-alpha: how much of the dst to keep.
11133 uint32_t ia = 0xFFFF - sa;
11134
11135 // Composite src (nonpremul) over dst (premul).
11136 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
11137 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
11138 db = ((sb * sa) + (db * ia)) / 0xFFFF;
11139
11140 // Convert from 16-bit color to 565 color and combine the components.
11141 uint32_t new_r5 = 0x1F & (dr >> 11);
11142 uint32_t new_g6 = 0x3F & (dg >> 10);
11143 uint32_t new_b5 = 0x1F & (db >> 11);
11144 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
11145 wuffs_base__store_u16le__no_bounds_check(d + (0 * 2),
11146 (uint16_t)new_rgb_565);
11147
11148 s += 1 * 4;
11149 d += 1 * 2;
11150 n -= 1;
11151 }
11152
11153 return len;
11154}
11155
11156static uint64_t //
11157wuffs_base__pixel_swizzler__bgr_565__y(uint8_t* dst_ptr,
11158 size_t dst_len,
11159 uint8_t* dst_palette_ptr,
11160 size_t dst_palette_len,
11161 const uint8_t* src_ptr,
11162 size_t src_len) {
11163 size_t dst_len2 = dst_len / 2;
11164 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
11165 uint8_t* d = dst_ptr;
11166 const uint8_t* s = src_ptr;
11167 size_t n = len;
11168
11169 // TODO: unroll.
11170
11171 while (n >= 1) {
11172 uint32_t y5 = s[0] >> 3;
11173 uint32_t y6 = s[0] >> 2;
11174 uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
11175 wuffs_base__store_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
11176
11177 s += 1 * 1;
11178 d += 1 * 2;
11179 n -= 1;
11180 }
11181
11182 return len;
11183}
11184
11185static uint64_t //
11186wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t* dst_ptr,
11187 size_t dst_len,
11188 uint8_t* dst_palette_ptr,
11189 size_t dst_palette_len,
11190 const uint8_t* src_ptr,
11191 size_t src_len) {
11192 if (dst_palette_len != 1024) {
11193 return 0;
11194 }
11195 size_t dst_len2 = dst_len / 2;
11196 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
11197 uint8_t* d = dst_ptr;
11198 const uint8_t* s = src_ptr;
11199 size_t n = len;
11200
11201 const size_t loop_unroll_count = 4;
11202
11203 while (n >= loop_unroll_count) {
11204 wuffs_base__store_u16le__no_bounds_check(
11205 d + (0 * 2), wuffs_base__load_u16le__no_bounds_check(
11206 dst_palette_ptr + ((size_t)s[0] * 4)));
11207 wuffs_base__store_u16le__no_bounds_check(
11208 d + (1 * 2), wuffs_base__load_u16le__no_bounds_check(
11209 dst_palette_ptr + ((size_t)s[1] * 4)));
11210 wuffs_base__store_u16le__no_bounds_check(
11211 d + (2 * 2), wuffs_base__load_u16le__no_bounds_check(
11212 dst_palette_ptr + ((size_t)s[2] * 4)));
11213 wuffs_base__store_u16le__no_bounds_check(
11214 d + (3 * 2), wuffs_base__load_u16le__no_bounds_check(
11215 dst_palette_ptr + ((size_t)s[3] * 4)));
11216
11217 s += loop_unroll_count * 1;
11218 d += loop_unroll_count * 2;
11219 n -= loop_unroll_count;
11220 }
11221
11222 while (n >= 1) {
11223 wuffs_base__store_u16le__no_bounds_check(
11224 d + (0 * 2), wuffs_base__load_u16le__no_bounds_check(
11225 dst_palette_ptr + ((size_t)s[0] * 4)));
11226
11227 s += 1 * 1;
11228 d += 1 * 2;
11229 n -= 1;
11230 }
11231
11232 return len;
11233}
11234
11235static uint64_t //
11236wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(
11237 uint8_t* dst_ptr,
11238 size_t dst_len,
11239 uint8_t* dst_palette_ptr,
11240 size_t dst_palette_len,
11241 const uint8_t* src_ptr,
11242 size_t src_len) {
11243 if (dst_palette_len != 1024) {
11244 return 0;
11245 }
11246 size_t dst_len2 = dst_len / 2;
11247 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
11248 uint8_t* d = dst_ptr;
11249 const uint8_t* s = src_ptr;
11250 size_t n = len;
11251
11252 // TODO: unroll.
11253
11254 while (n >= 1) {
11255 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11256 ((size_t)s[0] * 4));
11257 if (s0) {
11258 wuffs_base__store_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0);
11259 }
11260
11261 s += 1 * 1;
11262 d += 1 * 2;
11263 n -= 1;
11264 }
11265
11266 return len;
11267}
11268
11269// --------
11270
11271static uint64_t //
11272wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t* dst_ptr,
11273 size_t dst_len,
11274 uint8_t* dst_palette_ptr,
11275 size_t dst_palette_len,
11276 const uint8_t* src_ptr,
11277 size_t src_len) {
11278 size_t dst_len3 = dst_len / 3;
11279 size_t src_len4 = src_len / 4;
11280 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
11281 uint8_t* d = dst_ptr;
11282 const uint8_t* s = src_ptr;
11283 size_t n = len;
11284
11285 // TODO: unroll.
11286
11287 while (n >= 1) {
11288 uint32_t s0 =
11289 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
11290 wuffs_base__load_u32le__no_bounds_check(s + (0 * 4)));
11291 wuffs_base__store_u24le__no_bounds_check(d + (0 * 3), s0);
11292
11293 s += 1 * 4;
11294 d += 1 * 3;
11295 n -= 1;
11296 }
11297
11298 return len;
11299}
11300
11301static uint64_t //
11302wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(
11303 uint8_t* dst_ptr,
11304 size_t dst_len,
11305 uint8_t* dst_palette_ptr,
11306 size_t dst_palette_len,
11307 const uint8_t* src_ptr,
11308 size_t src_len) {
11309 size_t dst_len3 = dst_len / 3;
11310 size_t src_len4 = src_len / 4;
11311 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
11312 uint8_t* d = dst_ptr;
11313 const uint8_t* s = src_ptr;
11314 size_t n = len;
11315
11316 // TODO: unroll.
11317
11318 while (n >= 1) {
11319 // Convert from 8-bit color to 16-bit color.
11320 uint32_t sa = 0x101 * ((uint32_t)s[3]);
11321 uint32_t sr = 0x101 * ((uint32_t)s[2]);
11322 uint32_t sg = 0x101 * ((uint32_t)s[1]);
11323 uint32_t sb = 0x101 * ((uint32_t)s[0]);
11324 uint32_t dr = 0x101 * ((uint32_t)d[2]);
11325 uint32_t dg = 0x101 * ((uint32_t)d[1]);
11326 uint32_t db = 0x101 * ((uint32_t)d[0]);
11327
11328 // Calculate the inverse of the src-alpha: how much of the dst to keep.
11329 uint32_t ia = 0xFFFF - sa;
11330
11331 // Composite src (nonpremul) over dst (premul).
11332 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
11333 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
11334 db = ((sb * sa) + (db * ia)) / 0xFFFF;
11335
11336 // Convert from 16-bit color to 8-bit color.
11337 d[0] = (uint8_t)(db >> 8);
11338 d[1] = (uint8_t)(dg >> 8);
11339 d[2] = (uint8_t)(dr >> 8);
11340
11341 s += 1 * 4;
11342 d += 1 * 3;
11343 n -= 1;
11344 }
11345
11346 return len;
11347}
11348
11349// --------
11350
11351static uint64_t //
11352wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(
11353 uint8_t* dst_ptr,
11354 size_t dst_len,
11355 uint8_t* dst_palette_ptr,
11356 size_t dst_palette_len,
11357 const uint8_t* src_ptr,
11358 size_t src_len) {
11359 size_t dst_len4 = dst_len / 4;
11360 size_t src_len4 = src_len / 4;
11361 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
11362 uint8_t* d = dst_ptr;
11363 const uint8_t* s = src_ptr;
11364 size_t n = len;
11365
11366 // TODO: unroll.
11367
11368 while (n >= 1) {
11369 uint32_t d0 = wuffs_base__load_u32le__no_bounds_check(d + (0 * 4));
11370 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(s + (0 * 4));
11371 wuffs_base__store_u32le__no_bounds_check(
11372 d + (0 * 4),
11373 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
11374
11375 s += 1 * 4;
11376 d += 1 * 4;
11377 n -= 1;
11378 }
11379
11380 return len;
11381}
11382
11383// --------
11384
11385static uint64_t //
11386wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
11387 uint8_t* dst_ptr,
11388 size_t dst_len,
11389 uint8_t* dst_palette_ptr,
11390 size_t dst_palette_len,
11391 const uint8_t* src_ptr,
11392 size_t src_len) {
11393 size_t dst_len4 = dst_len / 4;
11394 size_t src_len4 = src_len / 4;
11395 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
11396 uint8_t* d = dst_ptr;
11397 const uint8_t* s = src_ptr;
11398 size_t n = len;
11399
11400 // TODO: unroll.
11401
11402 while (n >= 1) {
11403 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(s + (0 * 4));
11404 wuffs_base__store_u32le__no_bounds_check(
11405 d + (0 * 4),
11406 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
11407
11408 s += 1 * 4;
11409 d += 1 * 4;
11410 n -= 1;
11411 }
11412
11413 return len;
11414}
11415
11416static uint64_t //
11417wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(
11418 uint8_t* dst_ptr,
11419 size_t dst_len,
11420 uint8_t* dst_palette_ptr,
11421 size_t dst_palette_len,
11422 const uint8_t* src_ptr,
11423 size_t src_len) {
11424 size_t dst_len4 = dst_len / 4;
11425 size_t src_len4 = src_len / 4;
11426 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
11427 uint8_t* d = dst_ptr;
11428 const uint8_t* s = src_ptr;
11429 size_t n = len;
11430
11431 // TODO: unroll.
11432
11433 while (n >= 1) {
11434 uint32_t d0 = wuffs_base__load_u32le__no_bounds_check(d + (0 * 4));
11435 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(s + (0 * 4));
11436 wuffs_base__store_u32le__no_bounds_check(
11437 d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
11438
11439 s += 1 * 4;
11440 d += 1 * 4;
11441 n -= 1;
11442 }
11443
11444 return len;
11445}
11446
11447// --------
11448
11449static uint64_t //
11450wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr,
11451 size_t dst_len,
11452 uint8_t* dst_palette_ptr,
11453 size_t dst_palette_len,
11454 const uint8_t* src_ptr,
11455 size_t src_len) {
11456 if (dst_palette_len != 1024) {
11457 return 0;
11458 }
11459 size_t dst_len3 = dst_len / 3;
11460 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
11461 uint8_t* d = dst_ptr;
11462 const uint8_t* s = src_ptr;
11463 size_t n = len;
11464
11465 const size_t loop_unroll_count = 4;
11466
11467 // The comparison in the while condition is ">", not ">=", because with
11468 // ">=", the last 4-byte store could write past the end of the dst slice.
11469 //
11470 // Each 4-byte store writes one too many bytes, but a subsequent store
11471 // will overwrite that with the correct byte. There is always another
11472 // store, whether a 4-byte store in this loop or a 1-byte store in the
11473 // next loop.
11474 while (n > loop_unroll_count) {
11475 wuffs_base__store_u32le__no_bounds_check(
11476 d + (0 * 3), wuffs_base__load_u32le__no_bounds_check(
11477 dst_palette_ptr + ((size_t)s[0] * 4)));
11478 wuffs_base__store_u32le__no_bounds_check(
11479 d + (1 * 3), wuffs_base__load_u32le__no_bounds_check(
11480 dst_palette_ptr + ((size_t)s[1] * 4)));
11481 wuffs_base__store_u32le__no_bounds_check(
11482 d + (2 * 3), wuffs_base__load_u32le__no_bounds_check(
11483 dst_palette_ptr + ((size_t)s[2] * 4)));
11484 wuffs_base__store_u32le__no_bounds_check(
11485 d + (3 * 3), wuffs_base__load_u32le__no_bounds_check(
11486 dst_palette_ptr + ((size_t)s[3] * 4)));
11487
11488 s += loop_unroll_count * 1;
11489 d += loop_unroll_count * 3;
11490 n -= loop_unroll_count;
11491 }
11492
11493 while (n >= 1) {
11494 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11495 ((size_t)s[0] * 4));
11496 wuffs_base__store_u24le__no_bounds_check(d + (0 * 3), s0);
11497
11498 s += 1 * 1;
11499 d += 1 * 3;
11500 n -= 1;
11501 }
11502
11503 return len;
11504}
11505
11506static uint64_t //
11507wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(
11508 uint8_t* dst_ptr,
11509 size_t dst_len,
11510 uint8_t* dst_palette_ptr,
11511 size_t dst_palette_len,
11512 const uint8_t* src_ptr,
11513 size_t src_len) {
11514 if (dst_palette_len != 1024) {
11515 return 0;
11516 }
11517 size_t dst_len3 = dst_len / 3;
11518 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
11519 uint8_t* d = dst_ptr;
11520 const uint8_t* s = src_ptr;
11521 size_t n = len;
11522
11523 const size_t loop_unroll_count = 4;
11524
11525 while (n >= loop_unroll_count) {
11526 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11527 ((size_t)s[0] * 4));
11528 if (s0) {
11529 wuffs_base__store_u24le__no_bounds_check(d + (0 * 3), s0);
11530 }
11531 uint32_t s1 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11532 ((size_t)s[1] * 4));
11533 if (s1) {
11534 wuffs_base__store_u24le__no_bounds_check(d + (1 * 3), s1);
11535 }
11536 uint32_t s2 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11537 ((size_t)s[2] * 4));
11538 if (s2) {
11539 wuffs_base__store_u24le__no_bounds_check(d + (2 * 3), s2);
11540 }
11541 uint32_t s3 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11542 ((size_t)s[3] * 4));
11543 if (s3) {
11544 wuffs_base__store_u24le__no_bounds_check(d + (3 * 3), s3);
11545 }
11546
11547 s += loop_unroll_count * 1;
11548 d += loop_unroll_count * 3;
11549 n -= loop_unroll_count;
11550 }
11551
11552 while (n >= 1) {
11553 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11554 ((size_t)s[0] * 4));
11555 if (s0) {
11556 wuffs_base__store_u24le__no_bounds_check(d + (0 * 3), s0);
11557 }
11558
11559 s += 1 * 1;
11560 d += 1 * 3;
11561 n -= 1;
11562 }
11563
11564 return len;
11565}
11566
11567static uint64_t //
11568wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr,
11569 size_t dst_len,
11570 uint8_t* dst_palette_ptr,
11571 size_t dst_palette_len,
11572 const uint8_t* src_ptr,
11573 size_t src_len) {
11574 size_t dst_len3 = dst_len / 3;
11575 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
11576 uint8_t* d = dst_ptr;
11577 const uint8_t* s = src_ptr;
11578 size_t n = len;
11579
11580 // TODO: unroll.
11581
11582 while (n >= 1) {
11583 uint8_t s0 = s[0];
11584 d[0] = s0;
11585 d[1] = s0;
11586 d[2] = s0;
11587
11588 s += 1 * 1;
11589 d += 1 * 3;
11590 n -= 1;
11591 }
11592
11593 return len;
11594}
11595
11596// --------
11597
11598static uint64_t //
11599wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t* dst_ptr,
11600 size_t dst_len,
11601 uint8_t* dst_palette_ptr,
11602 size_t dst_palette_len,
11603 const uint8_t* src_ptr,
11604 size_t src_len) {
11605 if (dst_palette_len != 1024) {
11606 return 0;
11607 }
11608 size_t dst_len4 = dst_len / 4;
11609 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
11610 uint8_t* d = dst_ptr;
11611 const uint8_t* s = src_ptr;
11612 size_t n = len;
11613
11614 const size_t loop_unroll_count = 4;
11615
11616 while (n >= loop_unroll_count) {
11617 wuffs_base__store_u32le__no_bounds_check(
11618 d + (0 * 4), wuffs_base__load_u32le__no_bounds_check(
11619 dst_palette_ptr + ((size_t)s[0] * 4)));
11620 wuffs_base__store_u32le__no_bounds_check(
11621 d + (1 * 4), wuffs_base__load_u32le__no_bounds_check(
11622 dst_palette_ptr + ((size_t)s[1] * 4)));
11623 wuffs_base__store_u32le__no_bounds_check(
11624 d + (2 * 4), wuffs_base__load_u32le__no_bounds_check(
11625 dst_palette_ptr + ((size_t)s[2] * 4)));
11626 wuffs_base__store_u32le__no_bounds_check(
11627 d + (3 * 4), wuffs_base__load_u32le__no_bounds_check(
11628 dst_palette_ptr + ((size_t)s[3] * 4)));
11629
11630 s += loop_unroll_count * 1;
11631 d += loop_unroll_count * 4;
11632 n -= loop_unroll_count;
11633 }
11634
11635 while (n >= 1) {
11636 wuffs_base__store_u32le__no_bounds_check(
11637 d + (0 * 4), wuffs_base__load_u32le__no_bounds_check(
11638 dst_palette_ptr + ((size_t)s[0] * 4)));
11639
11640 s += 1 * 1;
11641 d += 1 * 4;
11642 n -= 1;
11643 }
11644
11645 return len;
11646}
11647
11648static uint64_t //
11649wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(
11650 uint8_t* dst_ptr,
11651 size_t dst_len,
11652 uint8_t* dst_palette_ptr,
11653 size_t dst_palette_len,
11654 const uint8_t* src_ptr,
11655 size_t src_len) {
11656 if (dst_palette_len != 1024) {
11657 return 0;
11658 }
11659 size_t dst_len4 = dst_len / 4;
11660 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
11661 uint8_t* d = dst_ptr;
11662 const uint8_t* s = src_ptr;
11663 size_t n = len;
11664
11665 const size_t loop_unroll_count = 4;
11666
11667 while (n >= loop_unroll_count) {
11668 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11669 ((size_t)s[0] * 4));
11670 if (s0) {
11671 wuffs_base__store_u32le__no_bounds_check(d + (0 * 4), s0);
11672 }
11673 uint32_t s1 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11674 ((size_t)s[1] * 4));
11675 if (s1) {
11676 wuffs_base__store_u32le__no_bounds_check(d + (1 * 4), s1);
11677 }
11678 uint32_t s2 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11679 ((size_t)s[2] * 4));
11680 if (s2) {
11681 wuffs_base__store_u32le__no_bounds_check(d + (2 * 4), s2);
11682 }
11683 uint32_t s3 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11684 ((size_t)s[3] * 4));
11685 if (s3) {
11686 wuffs_base__store_u32le__no_bounds_check(d + (3 * 4), s3);
11687 }
11688
11689 s += loop_unroll_count * 1;
11690 d += loop_unroll_count * 4;
11691 n -= loop_unroll_count;
11692 }
11693
11694 while (n >= 1) {
11695 uint32_t s0 = wuffs_base__load_u32le__no_bounds_check(dst_palette_ptr +
11696 ((size_t)s[0] * 4));
11697 if (s0) {
11698 wuffs_base__store_u32le__no_bounds_check(d + (0 * 4), s0);
11699 }
11700
11701 s += 1 * 1;
11702 d += 1 * 4;
11703 n -= 1;
11704 }
11705
11706 return len;
11707}
11708
11709static uint64_t //
11710wuffs_base__pixel_swizzler__xxxx__xxx(uint8_t* dst_ptr,
11711 size_t dst_len,
11712 uint8_t* dst_palette_ptr,
11713 size_t dst_palette_len,
11714 const uint8_t* src_ptr,
11715 size_t src_len) {
11716 size_t dst_len4 = dst_len / 4;
11717 size_t src_len3 = src_len / 3;
11718 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
11719 uint8_t* d = dst_ptr;
11720 const uint8_t* s = src_ptr;
11721 size_t n = len;
11722
11723 // TODO: unroll.
11724
11725 while (n >= 1) {
11726 wuffs_base__store_u32le__no_bounds_check(
11727 d + (0 * 4),
11728 0xFF000000 | wuffs_base__load_u24le__no_bounds_check(s + (0 * 3)));
11729
11730 s += 1 * 3;
11731 d += 1 * 4;
11732 n -= 1;
11733 }
11734
11735 return len;
11736}
11737
11738static uint64_t //
11739wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr,
11740 size_t dst_len,
11741 uint8_t* dst_palette_ptr,
11742 size_t dst_palette_len,
11743 const uint8_t* src_ptr,
11744 size_t src_len) {
11745 size_t dst_len4 = dst_len / 4;
11746 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
11747 uint8_t* d = dst_ptr;
11748 const uint8_t* s = src_ptr;
11749 size_t n = len;
11750
11751 // TODO: unroll.
11752
11753 while (n >= 1) {
11754 wuffs_base__store_u32le__no_bounds_check(
11755 d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
11756
11757 s += 1 * 1;
11758 d += 1 * 4;
11759 n -= 1;
11760 }
11761
11762 return len;
11763}
11764
11765// --------
11766
11767static wuffs_base__pixel_swizzler__func //
11768wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler* p,
11769 wuffs_base__pixel_format dst_pixfmt,
11770 wuffs_base__slice_u8 dst_palette,
11771 wuffs_base__slice_u8 src_palette,
11772 wuffs_base__pixel_blend blend) {
11773 switch (dst_pixfmt.repr) {
11774 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
11775 return wuffs_base__pixel_swizzler__bgr_565__y;
11776
11777 case WUFFS_BASE__PIXEL_FORMAT__BGR:
11778 case WUFFS_BASE__PIXEL_FORMAT__RGB:
11779 return wuffs_base__pixel_swizzler__xxx__y;
11780
11781 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
11782 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
11783 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
11784 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
11785 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
11786 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
11787 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
11788 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
11789 return wuffs_base__pixel_swizzler__xxxx__y;
11790 }
11791 return NULL;
11792}
11793
11794static wuffs_base__pixel_swizzler__func //
11795wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
11796 wuffs_base__pixel_swizzler* p,
11797 wuffs_base__pixel_format dst_pixfmt,
11798 wuffs_base__slice_u8 dst_palette,
11799 wuffs_base__slice_u8 src_palette,
11800 wuffs_base__pixel_blend blend) {
11801 switch (dst_pixfmt.repr) {
11802 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
11803 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
11804 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
11805 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
11806 1024) {
11807 return NULL;
11808 }
11809 switch (blend) {
11810 case WUFFS_BASE__PIXEL_BLEND__SRC:
11811 return wuffs_base__pixel_swizzler__copy_1_1;
11812 }
11813 return NULL;
11814
11815 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
11816 if (wuffs_base__pixel_swizzler__squash_bgr_565_888(dst_palette,
11817 src_palette) != 1024) {
11818 return NULL;
11819 }
11820 switch (blend) {
11821 case WUFFS_BASE__PIXEL_BLEND__SRC:
11822 return wuffs_base__pixel_swizzler__bgr_565__index__src;
11823 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11824 return wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over;
11825 }
11826 return NULL;
11827
11828 case WUFFS_BASE__PIXEL_FORMAT__BGR:
11829 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
11830 1024) {
11831 return NULL;
11832 }
11833 switch (blend) {
11834 case WUFFS_BASE__PIXEL_BLEND__SRC:
11835 return wuffs_base__pixel_swizzler__xxx__index__src;
11836 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11837 return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
11838 }
11839 return NULL;
11840
11841 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
11842 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
11843 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
11844 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
11845 1024) {
11846 return NULL;
11847 }
11848 switch (blend) {
11849 case WUFFS_BASE__PIXEL_BLEND__SRC:
11850 return wuffs_base__pixel_swizzler__xxxx__index__src;
11851 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11852 return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
11853 }
11854 return NULL;
11855
11856 case WUFFS_BASE__PIXEL_FORMAT__RGB:
11857 if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,
11858 src_palette) != 1024) {
11859 return NULL;
11860 }
11861 switch (blend) {
11862 case WUFFS_BASE__PIXEL_BLEND__SRC:
11863 return wuffs_base__pixel_swizzler__xxx__index__src;
11864 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11865 return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
11866 }
11867 return NULL;
11868
11869 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
11870 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
11871 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
11872 if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(dst_palette,
11873 src_palette) != 1024) {
11874 return NULL;
11875 }
11876 switch (blend) {
11877 case WUFFS_BASE__PIXEL_BLEND__SRC:
11878 return wuffs_base__pixel_swizzler__xxxx__index__src;
11879 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11880 return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
11881 }
11882 return NULL;
11883 }
11884 return NULL;
11885}
11886
11887static wuffs_base__pixel_swizzler__func //
11888wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler* p,
11889 wuffs_base__pixel_format dst_pixfmt,
11890 wuffs_base__slice_u8 dst_palette,
11891 wuffs_base__slice_u8 src_palette,
11892 wuffs_base__pixel_blend blend) {
11893 switch (dst_pixfmt.repr) {
11894 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
11895 return wuffs_base__pixel_swizzler__bgr_565__bgr;
11896
11897 case WUFFS_BASE__PIXEL_FORMAT__BGR:
11898 return wuffs_base__pixel_swizzler__copy_3_3;
11899
11900 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
11901 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
11902 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
11903 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
11904 return wuffs_base__pixel_swizzler__xxxx__xxx;
11905
11906 case WUFFS_BASE__PIXEL_FORMAT__RGB:
11907 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
11908 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
11909 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
11910 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
11911 // TODO.
11912 break;
11913 }
11914 return NULL;
11915}
11916
11917static wuffs_base__pixel_swizzler__func //
11918wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
11919 wuffs_base__pixel_swizzler* p,
11920 wuffs_base__pixel_format dst_pixfmt,
11921 wuffs_base__slice_u8 dst_palette,
11922 wuffs_base__slice_u8 src_palette,
11923 wuffs_base__pixel_blend blend) {
11924 switch (dst_pixfmt.repr) {
11925 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
11926 switch (blend) {
11927 case WUFFS_BASE__PIXEL_BLEND__SRC:
11928 return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src;
11929 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11930 return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over;
11931 }
11932 return NULL;
11933
11934 case WUFFS_BASE__PIXEL_FORMAT__BGR:
11935 switch (blend) {
11936 case WUFFS_BASE__PIXEL_BLEND__SRC:
11937 return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
11938 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11939 return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
11940 }
11941 return NULL;
11942
11943 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
11944 switch (blend) {
11945 case WUFFS_BASE__PIXEL_BLEND__SRC:
11946 return wuffs_base__pixel_swizzler__copy_4_4;
11947 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11948 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
11949 }
11950 return NULL;
11951
11952 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
11953 switch (blend) {
11954 case WUFFS_BASE__PIXEL_BLEND__SRC:
11955 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
11956 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
11957 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
11958 }
11959 return NULL;
11960
11961 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
11962 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
11963 // TODO.
11964 break;
11965
11966 case WUFFS_BASE__PIXEL_FORMAT__RGB:
11967 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
11968 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
11969 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
11970 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
11971 // TODO.
11972 break;
11973 }
11974 return NULL;
11975}
11976
11977// --------
11978
11979WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
11980wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
11981 wuffs_base__pixel_format dst_pixfmt,
11982 wuffs_base__slice_u8 dst_palette,
11983 wuffs_base__pixel_format src_pixfmt,
11984 wuffs_base__slice_u8 src_palette,
11985 wuffs_base__pixel_blend blend) {
11986 if (!p) {
11987 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11988 }
11989 p->private_impl.func = NULL;
11990 p->private_impl.src_pixfmt_bytes_per_pixel = 0;
11991
11992 wuffs_base__pixel_swizzler__func func = NULL;
11993 uint32_t src_pixfmt_bits_per_pixel =
11994 wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);
11995 if ((src_pixfmt_bits_per_pixel == 0) ||
11996 ((src_pixfmt_bits_per_pixel & 7) != 0)) {
11997 return wuffs_base__make_status(
11998 wuffs_base__error__unsupported_pixel_swizzler_option);
11999 }
12000
12001 // TODO: support many more formats.
12002
12003 switch (src_pixfmt.repr) {
12004 case WUFFS_BASE__PIXEL_FORMAT__Y:
12005 func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette,
12006 src_palette, blend);
12007 break;
12008
12009 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
12010 func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
12011 p, dst_pixfmt, dst_palette, src_palette, blend);
12012 break;
12013
12014 case WUFFS_BASE__PIXEL_FORMAT__BGR:
12015 func = wuffs_base__pixel_swizzler__prepare__bgr(
12016 p, dst_pixfmt, dst_palette, src_palette, blend);
12017 break;
12018
12019 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
12020 func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
12021 p, dst_pixfmt, dst_palette, src_palette, blend);
12022 break;
12023 }
12024
12025 p->private_impl.func = func;
12026 p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;
12027 return wuffs_base__make_status(
12028 func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);
12029}
12030
12031WUFFS_BASE__MAYBE_STATIC uint64_t //
12032wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
12033 const wuffs_base__pixel_swizzler* p,
12034 wuffs_base__slice_u8 dst,
12035 wuffs_base__slice_u8 dst_palette,
12036 const uint8_t** ptr_iop_r,
12037 const uint8_t* io2_r) {
12038 if (p && p->private_impl.func) {
12039 const uint8_t* iop_r = *ptr_iop_r;
12040 uint64_t n = (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
12041 dst_palette.len, iop_r,
12042 (size_t)(io2_r - iop_r));
12043 *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
12044 return n;
12045 }
12046 return 0;
12047}
12048
12049WUFFS_BASE__MAYBE_STATIC uint64_t //
12050wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
12051 const wuffs_base__pixel_swizzler* p,
12052 wuffs_base__slice_u8 dst,
12053 wuffs_base__slice_u8 dst_palette,
12054 wuffs_base__slice_u8 src) {
12055 if (p && p->private_impl.func) {
12056 return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
12057 dst_palette.len, src.ptr, src.len);
12058 }
12059 return 0;
12060}
12061
12062#endif // !defined(WUFFS_CONFIG__MODULES) ||
12063 // defined(WUFFS_CONFIG__MODULE__BASE) ||
12064 // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
12065
12066#ifdef __cplusplus
12067} // extern "C"
12068#endif
12069
12070#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
12071
12072// ---------------- Status Codes Implementations
12073
12074// ---------------- Private Consts
12075
12076// ---------------- Private Initializer Prototypes
12077
12078// ---------------- Private Function Prototypes
12079
12080// ---------------- VTables
12081
12082const wuffs_base__hasher_u32__func_ptrs
12083wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
12084 (wuffs_base__empty_struct(*)(void*,
12085 uint32_t,
12086 bool))(&wuffs_adler32__hasher__set_quirk_enabled),
12087 (uint32_t(*)(void*,
12088 wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32),
12089};
12090
12091// ---------------- Initializer Implementations
12092
12093wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12094wuffs_adler32__hasher__initialize(
12095 wuffs_adler32__hasher* self,
12096 size_t sizeof_star_self,
12097 uint64_t wuffs_version,
12098 uint32_t initialize_flags){
12099 if (!self) {
12100 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12101 }
12102 if (sizeof(*self) != sizeof_star_self) {
12103 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
12104 }
12105 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
12106 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
12107 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
12108 }
12109
12110 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
12111 // The whole point of this if-check is to detect an uninitialized *self.
12112 // We disable the warning on GCC. Clang-5.0 does not have this warning.
12113#if !defined(__clang__) && defined(__GNUC__)
12114#pragma GCC diagnostic push
12115#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
12116#endif
12117 if (self->private_impl.magic != 0) {
12118 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
12119 }
12120#if !defined(__clang__) && defined(__GNUC__)
12121#pragma GCC diagnostic pop
12122#endif
12123 } else {
12124 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
12125 memset(self, 0, sizeof(*self));
12126 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
12127 } else {
12128 memset(&(self->private_impl), 0, sizeof(self->private_impl));
12129 }
12130 }
12131
12132 self->private_impl.magic = WUFFS_BASE__MAGIC;
12133 self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
12134 wuffs_base__hasher_u32__vtable_name;
12135 self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
12136 (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
12137 return wuffs_base__make_status(NULL);
12138}
12139
12140wuffs_adler32__hasher*
12141wuffs_adler32__hasher__alloc() {
12142 wuffs_adler32__hasher* x =
12143 (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
12144 if (!x) {
12145 return NULL;
12146 }
12147 if (wuffs_adler32__hasher__initialize(
12148 x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
12149 free(x);
12150 return NULL;
12151 }
12152 return x;
12153}
12154
12155size_t
12156sizeof__wuffs_adler32__hasher() {
12157 return sizeof(wuffs_adler32__hasher);
12158}
12159
12160// ---------------- Function Implementations
12161
12162// -------- func adler32.hasher.set_quirk_enabled
12163
12164WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12165wuffs_adler32__hasher__set_quirk_enabled(
12166 wuffs_adler32__hasher* self,
12167 uint32_t a_quirk,
12168 bool a_enabled) {
12169 return wuffs_base__make_empty_struct();
12170}
12171
12172// -------- func adler32.hasher.update_u32
12173
12174WUFFS_BASE__MAYBE_STATIC uint32_t
12175wuffs_adler32__hasher__update_u32(
12176 wuffs_adler32__hasher* self,
12177 wuffs_base__slice_u8 a_x) {
12178 if (!self) {
12179 return 0;
12180 }
12181 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12182 return 0;
12183 }
12184
12185 uint32_t v_s1 = 0;
12186 uint32_t v_s2 = 0;
12187 wuffs_base__slice_u8 v_remaining = {0};
12188 wuffs_base__slice_u8 v_p = {0};
12189
12190 if ( ! self->private_impl.f_started) {
12191 self->private_impl.f_started = true;
12192 self->private_impl.f_state = 1;
12193 }
12194 v_s1 = ((self->private_impl.f_state) & 0xFFFF);
12195 v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
12196 while (((uint64_t)(a_x.len)) > 0) {
12197 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
12198 if (((uint64_t)(a_x.len)) > 5552) {
12199 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552);
12200 a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552);
12201 }
12202 {
12203 wuffs_base__slice_u8 i_slice_p = a_x;
12204 v_p = i_slice_p;
12205 v_p.len = 1;
12206 uint8_t* i_end0_p = i_slice_p.ptr + (i_slice_p.len / 8) * 8;
12207 while (v_p.ptr < i_end0_p) {
12208 v_s1 += ((uint32_t)(v_p.ptr[0]));
12209 v_s2 += v_s1;
12210 v_p.ptr += 1;
12211 v_s1 += ((uint32_t)(v_p.ptr[0]));
12212 v_s2 += v_s1;
12213 v_p.ptr += 1;
12214 v_s1 += ((uint32_t)(v_p.ptr[0]));
12215 v_s2 += v_s1;
12216 v_p.ptr += 1;
12217 v_s1 += ((uint32_t)(v_p.ptr[0]));
12218 v_s2 += v_s1;
12219 v_p.ptr += 1;
12220 v_s1 += ((uint32_t)(v_p.ptr[0]));
12221 v_s2 += v_s1;
12222 v_p.ptr += 1;
12223 v_s1 += ((uint32_t)(v_p.ptr[0]));
12224 v_s2 += v_s1;
12225 v_p.ptr += 1;
12226 v_s1 += ((uint32_t)(v_p.ptr[0]));
12227 v_s2 += v_s1;
12228 v_p.ptr += 1;
12229 v_s1 += ((uint32_t)(v_p.ptr[0]));
12230 v_s2 += v_s1;
12231 v_p.ptr += 1;
12232 }
12233 v_p.len = 1;
12234 uint8_t* i_end1_p = i_slice_p.ptr + (i_slice_p.len / 1) * 1;
12235 while (v_p.ptr < i_end1_p) {
12236 v_s1 += ((uint32_t)(v_p.ptr[0]));
12237 v_s2 += v_s1;
12238 v_p.ptr += 1;
12239 }
12240 }
12241 v_s1 %= 65521;
12242 v_s2 %= 65521;
12243 a_x = v_remaining;
12244 }
12245 self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
12246 return self->private_impl.f_state;
12247}
12248
12249#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
12250
12251#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
12252
12253// ---------------- Status Codes Implementations
12254
12255const char* wuffs_bmp__error__bad_header = "#bmp: bad header";
12256const char* wuffs_bmp__error__unsupported_bmp_file = "#bmp: unsupported BMP file";
12257const char* wuffs_bmp__note__internal_note_short_read = "@bmp: internal note: short read";
12258
12259// ---------------- Private Consts
12260
12261// ---------------- Private Initializer Prototypes
12262
12263// ---------------- Private Function Prototypes
12264
12265static wuffs_base__status
12266wuffs_bmp__decoder__swizzle(
12267 wuffs_bmp__decoder* self,
12268 wuffs_base__pixel_buffer* a_dst,
12269 wuffs_base__io_buffer* a_src);
12270
12271static wuffs_base__status
12272wuffs_bmp__decoder__skip_frame(
12273 wuffs_bmp__decoder* self,
12274 wuffs_base__io_buffer* a_src);
12275
12276// ---------------- VTables
12277
12278const wuffs_base__image_decoder__func_ptrs
12279wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
12280 (wuffs_base__status(*)(void*,
12281 wuffs_base__pixel_buffer*,
12282 wuffs_base__io_buffer*,
12283 wuffs_base__pixel_blend,
12284 wuffs_base__slice_u8,
12285 wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame),
12286 (wuffs_base__status(*)(void*,
12287 wuffs_base__frame_config*,
12288 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config),
12289 (wuffs_base__status(*)(void*,
12290 wuffs_base__image_config*,
12291 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config),
12292 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect),
12293 (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops),
12294 (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs),
12295 (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames),
12296 (wuffs_base__status(*)(void*,
12297 uint64_t,
12298 uint64_t))(&wuffs_bmp__decoder__restart_frame),
12299 (wuffs_base__empty_struct(*)(void*,
12300 uint32_t,
12301 bool))(&wuffs_bmp__decoder__set_quirk_enabled),
12302 (wuffs_base__empty_struct(*)(void*,
12303 uint32_t,
12304 bool))(&wuffs_bmp__decoder__set_report_metadata),
12305 (wuffs_base__status(*)(void*,
12306 wuffs_base__io_buffer*,
12307 wuffs_base__more_information*,
12308 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more),
12309 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len),
12310};
12311
12312// ---------------- Initializer Implementations
12313
12314wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
12315wuffs_bmp__decoder__initialize(
12316 wuffs_bmp__decoder* self,
12317 size_t sizeof_star_self,
12318 uint64_t wuffs_version,
12319 uint32_t initialize_flags){
12320 if (!self) {
12321 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12322 }
12323 if (sizeof(*self) != sizeof_star_self) {
12324 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
12325 }
12326 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
12327 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
12328 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
12329 }
12330
12331 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
12332 // The whole point of this if-check is to detect an uninitialized *self.
12333 // We disable the warning on GCC. Clang-5.0 does not have this warning.
12334#if !defined(__clang__) && defined(__GNUC__)
12335#pragma GCC diagnostic push
12336#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
12337#endif
12338 if (self->private_impl.magic != 0) {
12339 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
12340 }
12341#if !defined(__clang__) && defined(__GNUC__)
12342#pragma GCC diagnostic pop
12343#endif
12344 } else {
12345 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
12346 memset(self, 0, sizeof(*self));
12347 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
12348 } else {
12349 memset(&(self->private_impl), 0, sizeof(self->private_impl));
12350 }
12351 }
12352
12353 self->private_impl.magic = WUFFS_BASE__MAGIC;
12354 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
12355 wuffs_base__image_decoder__vtable_name;
12356 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
12357 (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
12358 return wuffs_base__make_status(NULL);
12359}
12360
12361wuffs_bmp__decoder*
12362wuffs_bmp__decoder__alloc() {
12363 wuffs_bmp__decoder* x =
12364 (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
12365 if (!x) {
12366 return NULL;
12367 }
12368 if (wuffs_bmp__decoder__initialize(
12369 x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
12370 free(x);
12371 return NULL;
12372 }
12373 return x;
12374}
12375
12376size_t
12377sizeof__wuffs_bmp__decoder() {
12378 return sizeof(wuffs_bmp__decoder);
12379}
12380
12381// ---------------- Function Implementations
12382
12383// -------- func bmp.decoder.set_quirk_enabled
12384
12385WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
12386wuffs_bmp__decoder__set_quirk_enabled(
12387 wuffs_bmp__decoder* self,
12388 uint32_t a_quirk,
12389 bool a_enabled) {
12390 return wuffs_base__make_empty_struct();
12391}
12392
12393// -------- func bmp.decoder.decode_image_config
12394
12395WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12396wuffs_bmp__decoder__decode_image_config(
12397 wuffs_bmp__decoder* self,
12398 wuffs_base__image_config* a_dst,
12399 wuffs_base__io_buffer* a_src) {
12400 if (!self) {
12401 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12402 }
12403 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12404 return wuffs_base__make_status(
12405 (self->private_impl.magic == WUFFS_BASE__DISABLED)
12406 ? wuffs_base__error__disabled_by_previous_error
12407 : wuffs_base__error__initialize_not_called);
12408 }
12409 if (!a_src) {
12410 self->private_impl.magic = WUFFS_BASE__DISABLED;
12411 return wuffs_base__make_status(wuffs_base__error__bad_argument);
12412 }
12413 if ((self->private_impl.active_coroutine != 0) &&
12414 (self->private_impl.active_coroutine != 1)) {
12415 self->private_impl.magic = WUFFS_BASE__DISABLED;
12416 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
12417 }
12418 self->private_impl.active_coroutine = 0;
12419 wuffs_base__status status = wuffs_base__make_status(NULL);
12420
12421 uint32_t v_magic = 0;
12422 uint32_t v_bitmap_info_len = 0;
12423 uint32_t v_width = 0;
12424 uint32_t v_height = 0;
12425 uint32_t v_planes = 0;
12426 uint32_t v_bits_per_pixel = 0;
12427 uint32_t v_compression = 0;
12428
12429 const uint8_t* iop_a_src = NULL;
12430 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
12431 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
12432 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
12433 if (a_src) {
12434 io0_a_src = a_src->data.ptr;
12435 io1_a_src = io0_a_src + a_src->meta.ri;
12436 iop_a_src = io1_a_src;
12437 io2_a_src = io0_a_src + a_src->meta.wi;
12438 }
12439
12440 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
12441 if (coro_susp_point) {
12442 v_bitmap_info_len = self->private_data.s_decode_image_config[0].v_bitmap_info_len;
12443 v_bits_per_pixel = self->private_data.s_decode_image_config[0].v_bits_per_pixel;
12444 v_compression = self->private_data.s_decode_image_config[0].v_compression;
12445 }
12446 switch (coro_susp_point) {
12447 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
12448
12449 if ((self->private_impl.f_call_sequence != 0) || (self->private_impl.f_io_redirect_fourcc == 1)) {
12450 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
12451 goto exit;
12452 } else if (self->private_impl.f_io_redirect_fourcc != 0) {
12453 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
12454 goto ok;
12455 }
12456 {
12457 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
12458 uint32_t t_0;
12459 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
12460 t_0 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
12461 iop_a_src += 2;
12462 } else {
12463 self->private_data.s_decode_image_config[0].scratch = 0;
12464 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
12465 while (true) {
12466 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12467 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12468 goto suspend;
12469 }
12470 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12471 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
12472 *scratch <<= 8;
12473 *scratch >>= 8;
12474 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
12475 if (num_bits_0 == 8) {
12476 t_0 = ((uint32_t)(*scratch));
12477 break;
12478 }
12479 num_bits_0 += 8;
12480 *scratch |= ((uint64_t)(num_bits_0)) << 56;
12481 }
12482 }
12483 v_magic = t_0;
12484 }
12485 if (v_magic != 19778) {
12486 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
12487 goto exit;
12488 }
12489 self->private_data.s_decode_image_config[0].scratch = 8;
12490 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
12491 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
12492 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
12493 iop_a_src = io2_a_src;
12494 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12495 goto suspend;
12496 }
12497 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
12498 {
12499 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
12500 uint32_t t_1;
12501 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12502 t_1 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12503 iop_a_src += 4;
12504 } else {
12505 self->private_data.s_decode_image_config[0].scratch = 0;
12506 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
12507 while (true) {
12508 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12509 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12510 goto suspend;
12511 }
12512 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12513 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
12514 *scratch <<= 8;
12515 *scratch >>= 8;
12516 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
12517 if (num_bits_1 == 24) {
12518 t_1 = ((uint32_t)(*scratch));
12519 break;
12520 }
12521 num_bits_1 += 8;
12522 *scratch |= ((uint64_t)(num_bits_1)) << 56;
12523 }
12524 }
12525 self->private_impl.f_padding = t_1;
12526 }
12527 if (self->private_impl.f_padding < 14) {
12528 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
12529 goto exit;
12530 }
12531 self->private_impl.f_padding -= 14;
12532 self->private_impl.f_io_redirect_pos = wuffs_base__u64__sat_add(((uint64_t)(self->private_impl.f_padding)), wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src))));
12533 {
12534 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
12535 uint32_t t_2;
12536 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12537 t_2 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12538 iop_a_src += 4;
12539 } else {
12540 self->private_data.s_decode_image_config[0].scratch = 0;
12541 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
12542 while (true) {
12543 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12544 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12545 goto suspend;
12546 }
12547 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12548 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
12549 *scratch <<= 8;
12550 *scratch >>= 8;
12551 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
12552 if (num_bits_2 == 24) {
12553 t_2 = ((uint32_t)(*scratch));
12554 break;
12555 }
12556 num_bits_2 += 8;
12557 *scratch |= ((uint64_t)(num_bits_2)) << 56;
12558 }
12559 }
12560 v_bitmap_info_len = t_2;
12561 }
12562 if ((v_bitmap_info_len != 40) && (v_bitmap_info_len != 108) && (v_bitmap_info_len != 124)) {
12563 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
12564 goto exit;
12565 }
12566 if (self->private_impl.f_padding < v_bitmap_info_len) {
12567 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
12568 goto exit;
12569 }
12570 self->private_impl.f_padding -= v_bitmap_info_len;
12571 {
12572 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
12573 uint32_t t_3;
12574 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12575 t_3 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12576 iop_a_src += 4;
12577 } else {
12578 self->private_data.s_decode_image_config[0].scratch = 0;
12579 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
12580 while (true) {
12581 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12582 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12583 goto suspend;
12584 }
12585 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12586 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
12587 *scratch <<= 8;
12588 *scratch >>= 8;
12589 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
12590 if (num_bits_3 == 24) {
12591 t_3 = ((uint32_t)(*scratch));
12592 break;
12593 }
12594 num_bits_3 += 8;
12595 *scratch |= ((uint64_t)(num_bits_3)) << 56;
12596 }
12597 }
12598 v_width = t_3;
12599 }
12600 if (v_width >= 2147483648) {
12601 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
12602 goto exit;
12603 }
12604 self->private_impl.f_width = v_width;
12605 {
12606 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
12607 uint32_t t_4;
12608 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12609 t_4 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12610 iop_a_src += 4;
12611 } else {
12612 self->private_data.s_decode_image_config[0].scratch = 0;
12613 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
12614 while (true) {
12615 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12616 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12617 goto suspend;
12618 }
12619 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12620 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
12621 *scratch <<= 8;
12622 *scratch >>= 8;
12623 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
12624 if (num_bits_4 == 24) {
12625 t_4 = ((uint32_t)(*scratch));
12626 break;
12627 }
12628 num_bits_4 += 8;
12629 *scratch |= ((uint64_t)(num_bits_4)) << 56;
12630 }
12631 }
12632 v_height = t_4;
12633 }
12634 if (v_height == 2147483648) {
12635 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
12636 goto exit;
12637 } else if (v_height >= 2147483648) {
12638 self->private_impl.f_height = ((0 - v_height) & 2147483647);
12639 self->private_impl.f_top_down = true;
12640 } else {
12641 self->private_impl.f_height = v_height;
12642 }
12643 {
12644 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
12645 uint32_t t_5;
12646 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
12647 t_5 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
12648 iop_a_src += 2;
12649 } else {
12650 self->private_data.s_decode_image_config[0].scratch = 0;
12651 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
12652 while (true) {
12653 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12654 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12655 goto suspend;
12656 }
12657 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12658 uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
12659 *scratch <<= 8;
12660 *scratch >>= 8;
12661 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
12662 if (num_bits_5 == 8) {
12663 t_5 = ((uint32_t)(*scratch));
12664 break;
12665 }
12666 num_bits_5 += 8;
12667 *scratch |= ((uint64_t)(num_bits_5)) << 56;
12668 }
12669 }
12670 v_planes = t_5;
12671 }
12672 if (v_planes != 1) {
12673 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
12674 goto exit;
12675 }
12676 {
12677 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
12678 uint32_t t_6;
12679 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
12680 t_6 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
12681 iop_a_src += 2;
12682 } else {
12683 self->private_data.s_decode_image_config[0].scratch = 0;
12684 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
12685 while (true) {
12686 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12687 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12688 goto suspend;
12689 }
12690 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12691 uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
12692 *scratch <<= 8;
12693 *scratch >>= 8;
12694 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
12695 if (num_bits_6 == 8) {
12696 t_6 = ((uint32_t)(*scratch));
12697 break;
12698 }
12699 num_bits_6 += 8;
12700 *scratch |= ((uint64_t)(num_bits_6)) << 56;
12701 }
12702 }
12703 v_bits_per_pixel = t_6;
12704 }
12705 {
12706 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
12707 uint32_t t_7;
12708 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12709 t_7 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12710 iop_a_src += 4;
12711 } else {
12712 self->private_data.s_decode_image_config[0].scratch = 0;
12713 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
12714 while (true) {
12715 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12716 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12717 goto suspend;
12718 }
12719 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12720 uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
12721 *scratch <<= 8;
12722 *scratch >>= 8;
12723 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
12724 if (num_bits_7 == 24) {
12725 t_7 = ((uint32_t)(*scratch));
12726 break;
12727 }
12728 num_bits_7 += 8;
12729 *scratch |= ((uint64_t)(num_bits_7)) << 56;
12730 }
12731 }
12732 v_compression = t_7;
12733 }
12734 if (v_bits_per_pixel == 0) {
12735 if (v_compression == 4) {
12736 self->private_impl.f_io_redirect_fourcc = 1246774599;
12737 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
12738 goto ok;
12739 } else if (v_compression == 5) {
12740 self->private_impl.f_io_redirect_fourcc = 1347307296;
12741 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
12742 goto ok;
12743 }
12744 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
12745 goto exit;
12746 } else if (v_bits_per_pixel == 24) {
12747 self->private_impl.f_bytes_per_row = ((((((uint64_t)(self->private_impl.f_width)) * 3) + 3) >> 2) << 2);
12748 self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3);
12749 self->private_impl.f_pixfmt = wuffs_base__utility__make_pixel_format(2147485832);
12750 } else if (v_bits_per_pixel == 32) {
12751 self->private_impl.f_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * 4);
12752 self->private_impl.f_pad_per_row = 0;
12753 self->private_impl.f_pixfmt = wuffs_base__utility__make_pixel_format(2164295816);
12754 } else {
12755 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
12756 goto exit;
12757 }
12758 self->private_data.s_decode_image_config[0].scratch = 20;
12759 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
12760 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
12761 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
12762 iop_a_src = io2_a_src;
12763 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12764 goto suspend;
12765 }
12766 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
12767 if (v_bitmap_info_len >= 108) {
12768 {
12769 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
12770 uint32_t t_8;
12771 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12772 t_8 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12773 iop_a_src += 4;
12774 } else {
12775 self->private_data.s_decode_image_config[0].scratch = 0;
12776 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
12777 while (true) {
12778 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12779 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12780 goto suspend;
12781 }
12782 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12783 uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
12784 *scratch <<= 8;
12785 *scratch >>= 8;
12786 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
12787 if (num_bits_8 == 24) {
12788 t_8 = ((uint32_t)(*scratch));
12789 break;
12790 }
12791 num_bits_8 += 8;
12792 *scratch |= ((uint64_t)(num_bits_8)) << 56;
12793 }
12794 }
12795 self->private_impl.f_mask_r = t_8;
12796 }
12797 {
12798 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
12799 uint32_t t_9;
12800 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12801 t_9 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12802 iop_a_src += 4;
12803 } else {
12804 self->private_data.s_decode_image_config[0].scratch = 0;
12805 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
12806 while (true) {
12807 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12808 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12809 goto suspend;
12810 }
12811 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12812 uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
12813 *scratch <<= 8;
12814 *scratch >>= 8;
12815 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
12816 if (num_bits_9 == 24) {
12817 t_9 = ((uint32_t)(*scratch));
12818 break;
12819 }
12820 num_bits_9 += 8;
12821 *scratch |= ((uint64_t)(num_bits_9)) << 56;
12822 }
12823 }
12824 self->private_impl.f_mask_g = t_9;
12825 }
12826 {
12827 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
12828 uint32_t t_10;
12829 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12830 t_10 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12831 iop_a_src += 4;
12832 } else {
12833 self->private_data.s_decode_image_config[0].scratch = 0;
12834 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
12835 while (true) {
12836 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12837 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12838 goto suspend;
12839 }
12840 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12841 uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
12842 *scratch <<= 8;
12843 *scratch >>= 8;
12844 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
12845 if (num_bits_10 == 24) {
12846 t_10 = ((uint32_t)(*scratch));
12847 break;
12848 }
12849 num_bits_10 += 8;
12850 *scratch |= ((uint64_t)(num_bits_10)) << 56;
12851 }
12852 }
12853 self->private_impl.f_mask_b = t_10;
12854 }
12855 {
12856 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
12857 uint32_t t_11;
12858 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
12859 t_11 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
12860 iop_a_src += 4;
12861 } else {
12862 self->private_data.s_decode_image_config[0].scratch = 0;
12863 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
12864 while (true) {
12865 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
12866 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12867 goto suspend;
12868 }
12869 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
12870 uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
12871 *scratch <<= 8;
12872 *scratch >>= 8;
12873 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
12874 if (num_bits_11 == 24) {
12875 t_11 = ((uint32_t)(*scratch));
12876 break;
12877 }
12878 num_bits_11 += 8;
12879 *scratch |= ((uint64_t)(num_bits_11)) << 56;
12880 }
12881 }
12882 self->private_impl.f_mask_a = t_11;
12883 }
12884 if ((v_compression == 3) &&
12885 (self->private_impl.f_mask_r == 16711680) &&
12886 (self->private_impl.f_mask_g == 65280) &&
12887 (self->private_impl.f_mask_b == 255) &&
12888 (self->private_impl.f_mask_a == 4278190080)) {
12889 v_compression = 0;
12890 }
12891 self->private_data.s_decode_image_config[0].scratch = (v_bitmap_info_len - 56);
12892 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
12893 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
12894 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
12895 iop_a_src = io2_a_src;
12896 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
12897 goto suspend;
12898 }
12899 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
12900 }
12901 if (v_compression != 0) {
12902 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
12903 goto exit;
12904 }
12905 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
12906 if (a_dst != NULL) {
12907 wuffs_base__image_config__set(
12908 a_dst,
12909 2164295816,
12910 0,
12911 self->private_impl.f_width,
12912 self->private_impl.f_height,
12913 self->private_impl.f_frame_config_io_position,
12914 true);
12915 }
12916 self->private_impl.f_call_sequence = 1;
12917
12918 goto ok;
12919 ok:
12920 self->private_impl.p_decode_image_config[0] = 0;
12921 goto exit;
12922 }
12923
12924 goto suspend;
12925 suspend:
12926 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
12927 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
12928 self->private_data.s_decode_image_config[0].v_bitmap_info_len = v_bitmap_info_len;
12929 self->private_data.s_decode_image_config[0].v_bits_per_pixel = v_bits_per_pixel;
12930 self->private_data.s_decode_image_config[0].v_compression = v_compression;
12931
12932 goto exit;
12933 exit:
12934 if (a_src) {
12935 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
12936 }
12937
12938 if (wuffs_base__status__is_error(&status)) {
12939 self->private_impl.magic = WUFFS_BASE__DISABLED;
12940 }
12941 return status;
12942}
12943
12944// -------- func bmp.decoder.decode_frame_config
12945
12946WUFFS_BASE__MAYBE_STATIC wuffs_base__status
12947wuffs_bmp__decoder__decode_frame_config(
12948 wuffs_bmp__decoder* self,
12949 wuffs_base__frame_config* a_dst,
12950 wuffs_base__io_buffer* a_src) {
12951 if (!self) {
12952 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12953 }
12954 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12955 return wuffs_base__make_status(
12956 (self->private_impl.magic == WUFFS_BASE__DISABLED)
12957 ? wuffs_base__error__disabled_by_previous_error
12958 : wuffs_base__error__initialize_not_called);
12959 }
12960 if (!a_src) {
12961 self->private_impl.magic = WUFFS_BASE__DISABLED;
12962 return wuffs_base__make_status(wuffs_base__error__bad_argument);
12963 }
12964 if ((self->private_impl.active_coroutine != 0) &&
12965 (self->private_impl.active_coroutine != 2)) {
12966 self->private_impl.magic = WUFFS_BASE__DISABLED;
12967 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
12968 }
12969 self->private_impl.active_coroutine = 0;
12970 wuffs_base__status status = wuffs_base__make_status(NULL);
12971
12972 const uint8_t* iop_a_src = NULL;
12973 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
12974 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
12975 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
12976 if (a_src) {
12977 io0_a_src = a_src->data.ptr;
12978 io1_a_src = io0_a_src + a_src->meta.ri;
12979 iop_a_src = io1_a_src;
12980 io2_a_src = io0_a_src + a_src->meta.wi;
12981 }
12982
12983 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
12984 switch (coro_susp_point) {
12985 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
12986
12987 if (self->private_impl.f_call_sequence < 1) {
12988 if (a_src) {
12989 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
12990 }
12991 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
12992 status = wuffs_bmp__decoder__decode_image_config(self, NULL, a_src);
12993 if (a_src) {
12994 iop_a_src = a_src->data.ptr + a_src->meta.ri;
12995 }
12996 if (status.repr) {
12997 goto suspend;
12998 }
12999 } else if (self->private_impl.f_call_sequence == 1) {
13000 if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)))) {
13001 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
13002 goto exit;
13003 }
13004 } else if (self->private_impl.f_call_sequence == 2) {
13005 if (a_src) {
13006 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
13007 }
13008 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
13009 status = wuffs_bmp__decoder__skip_frame(self, a_src);
13010 if (a_src) {
13011 iop_a_src = a_src->data.ptr + a_src->meta.ri;
13012 }
13013 if (status.repr) {
13014 goto suspend;
13015 }
13016 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
13017 goto ok;
13018 } else {
13019 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
13020 goto ok;
13021 }
13022 if (a_dst != NULL) {
13023 wuffs_base__frame_config__set(
13024 a_dst,
13025 wuffs_base__utility__make_rect_ie_u32(
13026 0,
13027 0,
13028 self->private_impl.f_width,
13029 self->private_impl.f_height),
13030 ((wuffs_base__flicks)(0)),
13031 0,
13032 self->private_impl.f_frame_config_io_position,
13033 0,
13034 true,
13035 false,
13036 4278190080);
13037 }
13038 self->private_impl.f_call_sequence = 2;
13039
13040 goto ok;
13041 ok:
13042 self->private_impl.p_decode_frame_config[0] = 0;
13043 goto exit;
13044 }
13045
13046 goto suspend;
13047 suspend:
13048 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
13049 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
13050
13051 goto exit;
13052 exit:
13053 if (a_src) {
13054 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
13055 }
13056
13057 if (wuffs_base__status__is_error(&status)) {
13058 self->private_impl.magic = WUFFS_BASE__DISABLED;
13059 }
13060 return status;
13061}
13062
13063// -------- func bmp.decoder.decode_frame
13064
13065WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13066wuffs_bmp__decoder__decode_frame(
13067 wuffs_bmp__decoder* self,
13068 wuffs_base__pixel_buffer* a_dst,
13069 wuffs_base__io_buffer* a_src,
13070 wuffs_base__pixel_blend a_blend,
13071 wuffs_base__slice_u8 a_workbuf,
13072 wuffs_base__decode_frame_options* a_opts) {
13073 if (!self) {
13074 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
13075 }
13076 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
13077 return wuffs_base__make_status(
13078 (self->private_impl.magic == WUFFS_BASE__DISABLED)
13079 ? wuffs_base__error__disabled_by_previous_error
13080 : wuffs_base__error__initialize_not_called);
13081 }
13082 if (!a_dst || !a_src) {
13083 self->private_impl.magic = WUFFS_BASE__DISABLED;
13084 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13085 }
13086 if ((self->private_impl.active_coroutine != 0) &&
13087 (self->private_impl.active_coroutine != 3)) {
13088 self->private_impl.magic = WUFFS_BASE__DISABLED;
13089 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
13090 }
13091 self->private_impl.active_coroutine = 0;
13092 wuffs_base__status status = wuffs_base__make_status(NULL);
13093
13094 wuffs_base__status v_status = wuffs_base__make_status(NULL);
13095
13096 const uint8_t* iop_a_src = NULL;
13097 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13098 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13099 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13100 if (a_src) {
13101 io0_a_src = a_src->data.ptr;
13102 io1_a_src = io0_a_src + a_src->meta.ri;
13103 iop_a_src = io1_a_src;
13104 io2_a_src = io0_a_src + a_src->meta.wi;
13105 }
13106
13107 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
13108 switch (coro_susp_point) {
13109 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
13110
13111 if (self->private_impl.f_call_sequence < 2) {
13112 if (a_src) {
13113 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
13114 }
13115 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
13116 status = wuffs_bmp__decoder__decode_frame_config(self, NULL, a_src);
13117 if (a_src) {
13118 iop_a_src = a_src->data.ptr + a_src->meta.ri;
13119 }
13120 if (status.repr) {
13121 goto suspend;
13122 }
13123 } else if (self->private_impl.f_call_sequence == 2) {
13124 } else {
13125 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
13126 goto ok;
13127 }
13128 self->private_data.s_decode_frame[0].scratch = self->private_impl.f_padding;
13129 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
13130 if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
13131 self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
13132 iop_a_src = io2_a_src;
13133 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
13134 goto suspend;
13135 }
13136 iop_a_src += self->private_data.s_decode_frame[0].scratch;
13137 if ((self->private_impl.f_width > 0) && (self->private_impl.f_height > 0)) {
13138 self->private_impl.f_dst_x = 0;
13139 if (self->private_impl.f_top_down) {
13140 self->private_impl.f_dst_y = 0;
13141 self->private_impl.f_dst_y_end = self->private_impl.f_height;
13142 self->private_impl.f_dst_y_inc = 1;
13143 } else {
13144 self->private_impl.f_dst_y = (self->private_impl.f_height - 1);
13145 self->private_impl.f_dst_y_end = 4294967295;
13146 self->private_impl.f_dst_y_inc = 4294967295;
13147 }
13148 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
13149 wuffs_base__pixel_buffer__pixel_format(a_dst),
13150 wuffs_base__pixel_buffer__palette(a_dst),
13151 self->private_impl.f_pixfmt,
13152 wuffs_base__utility__empty_slice_u8(),
13153 a_blend);
13154 if ( ! wuffs_base__status__is_ok(&v_status)) {
13155 status = v_status;
13156 if (wuffs_base__status__is_error(&status)) {
13157 goto exit;
13158 } else if (wuffs_base__status__is_suspension(&status)) {
13159 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
13160 goto exit;
13161 }
13162 goto ok;
13163 }
13164 while (true) {
13165 if (a_src) {
13166 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
13167 }
13168 v_status = wuffs_bmp__decoder__swizzle(self, a_dst, a_src);
13169 if (a_src) {
13170 iop_a_src = a_src->data.ptr + a_src->meta.ri;
13171 }
13172 if (wuffs_base__status__is_ok(&v_status)) {
13173 goto label__0__break;
13174 } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) {
13175 status = v_status;
13176 if (wuffs_base__status__is_error(&status)) {
13177 goto exit;
13178 } else if (wuffs_base__status__is_suspension(&status)) {
13179 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
13180 goto exit;
13181 }
13182 goto ok;
13183 }
13184 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
13185 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
13186 }
13187 label__0__break:;
13188 }
13189 self->private_impl.f_call_sequence = 3;
13190
13191 goto ok;
13192 ok:
13193 self->private_impl.p_decode_frame[0] = 0;
13194 goto exit;
13195 }
13196
13197 goto suspend;
13198 suspend:
13199 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
13200 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
13201
13202 goto exit;
13203 exit:
13204 if (a_src) {
13205 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
13206 }
13207
13208 if (wuffs_base__status__is_error(&status)) {
13209 self->private_impl.magic = WUFFS_BASE__DISABLED;
13210 }
13211 return status;
13212}
13213
13214// -------- func bmp.decoder.swizzle
13215
13216static wuffs_base__status
13217wuffs_bmp__decoder__swizzle(
13218 wuffs_bmp__decoder* self,
13219 wuffs_base__pixel_buffer* a_dst,
13220 wuffs_base__io_buffer* a_src) {
13221 wuffs_base__status status = wuffs_base__make_status(NULL);
13222
13223 wuffs_base__pixel_format v_dst_pixfmt = {0};
13224 uint32_t v_dst_bits_per_pixel = 0;
13225 uint64_t v_dst_bytes_per_pixel = 0;
13226 uint64_t v_dst_bytes_per_row = 0;
13227 wuffs_base__table_u8 v_tab = {0};
13228 wuffs_base__slice_u8 v_dst = {0};
13229 uint64_t v_i = 0;
13230 uint64_t v_n = 0;
13231
13232 const uint8_t* iop_a_src = NULL;
13233 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13234 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13235 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13236 if (a_src) {
13237 io0_a_src = a_src->data.ptr;
13238 io1_a_src = io0_a_src + a_src->meta.ri;
13239 iop_a_src = io1_a_src;
13240 io2_a_src = io0_a_src + a_src->meta.wi;
13241 }
13242
13243 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
13244 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
13245 if ((v_dst_bits_per_pixel & 7) != 0) {
13246 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
13247 goto exit;
13248 }
13249 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
13250 v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
13251 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
13252 label__outer__continue:;
13253 while (true) {
13254 while (self->private_impl.f_pending_pad > 0) {
13255 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
13256 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
13257 goto ok;
13258 }
13259 self->private_impl.f_pending_pad -= 1;
13260 (iop_a_src += 1, wuffs_base__make_empty_struct());
13261 }
13262 label__inner__continue:;
13263 while (true) {
13264 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
13265 self->private_impl.f_dst_x = 0;
13266 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
13267 if (self->private_impl.f_dst_y == self->private_impl.f_dst_y_end) {
13268 goto label__outer__break;
13269 } else if (self->private_impl.f_pad_per_row != 0) {
13270 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
13271 goto label__outer__continue;
13272 }
13273 }
13274 v_dst = wuffs_base__table_u8__row(v_tab, self->private_impl.f_dst_y);
13275 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
13276 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
13277 }
13278 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
13279 if (v_i >= ((uint64_t)(v_dst.len))) {
13280 goto label__inner__continue;
13281 }
13282 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
13283 &self->private_impl.f_swizzler,
13284 wuffs_base__slice_u8__subslice_i(v_dst, v_i),
13285 wuffs_base__utility__empty_slice_u8(),
13286 &iop_a_src,
13287 io2_a_src);
13288 if (v_n == 0) {
13289 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
13290 goto ok;
13291 }
13292 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
13293 }
13294 }
13295 label__outer__break:;
13296 status = wuffs_base__make_status(NULL);
13297 goto ok;
13298
13299 goto ok;
13300 ok:
13301 goto exit;
13302 exit:
13303 if (a_src) {
13304 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
13305 }
13306
13307 return status;
13308}
13309
13310// -------- func bmp.decoder.skip_frame
13311
13312static wuffs_base__status
13313wuffs_bmp__decoder__skip_frame(
13314 wuffs_bmp__decoder* self,
13315 wuffs_base__io_buffer* a_src) {
13316 wuffs_base__status status = wuffs_base__make_status(NULL);
13317
13318 const uint8_t* iop_a_src = NULL;
13319 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13320 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13321 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
13322 if (a_src) {
13323 io0_a_src = a_src->data.ptr;
13324 io1_a_src = io0_a_src + a_src->meta.ri;
13325 iop_a_src = io1_a_src;
13326 io2_a_src = io0_a_src + a_src->meta.wi;
13327 }
13328
13329 uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
13330 switch (coro_susp_point) {
13331 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
13332
13333 self->private_data.s_skip_frame[0].scratch = self->private_impl.f_padding;
13334 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
13335 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
13336 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
13337 iop_a_src = io2_a_src;
13338 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
13339 goto suspend;
13340 }
13341 iop_a_src += self->private_data.s_skip_frame[0].scratch;
13342 self->private_data.s_skip_frame[0].scratch = (self->private_impl.f_bytes_per_row * ((uint64_t)(self->private_impl.f_height)));
13343 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
13344 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
13345 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
13346 iop_a_src = io2_a_src;
13347 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
13348 goto suspend;
13349 }
13350 iop_a_src += self->private_data.s_skip_frame[0].scratch;
13351 self->private_impl.f_call_sequence = 3;
13352
13353 goto ok;
13354 ok:
13355 self->private_impl.p_skip_frame[0] = 0;
13356 goto exit;
13357 }
13358
13359 goto suspend;
13360 suspend:
13361 self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
13362
13363 goto exit;
13364 exit:
13365 if (a_src) {
13366 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
13367 }
13368
13369 return status;
13370}
13371
13372// -------- func bmp.decoder.frame_dirty_rect
13373
13374WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
13375wuffs_bmp__decoder__frame_dirty_rect(
13376 const wuffs_bmp__decoder* self) {
13377 if (!self) {
13378 return wuffs_base__utility__empty_rect_ie_u32();
13379 }
13380 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
13381 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
13382 return wuffs_base__utility__empty_rect_ie_u32();
13383 }
13384
13385 return wuffs_base__utility__make_rect_ie_u32(
13386 0,
13387 0,
13388 self->private_impl.f_width,
13389 self->private_impl.f_height);
13390}
13391
13392// -------- func bmp.decoder.num_animation_loops
13393
13394WUFFS_BASE__MAYBE_STATIC uint32_t
13395wuffs_bmp__decoder__num_animation_loops(
13396 const wuffs_bmp__decoder* self) {
13397 if (!self) {
13398 return 0;
13399 }
13400 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
13401 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
13402 return 0;
13403 }
13404
13405 return 0;
13406}
13407
13408// -------- func bmp.decoder.num_decoded_frame_configs
13409
13410WUFFS_BASE__MAYBE_STATIC uint64_t
13411wuffs_bmp__decoder__num_decoded_frame_configs(
13412 const wuffs_bmp__decoder* self) {
13413 if (!self) {
13414 return 0;
13415 }
13416 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
13417 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
13418 return 0;
13419 }
13420
13421 if (self->private_impl.f_call_sequence > 1) {
13422 return 1;
13423 }
13424 return 0;
13425}
13426
13427// -------- func bmp.decoder.num_decoded_frames
13428
13429WUFFS_BASE__MAYBE_STATIC uint64_t
13430wuffs_bmp__decoder__num_decoded_frames(
13431 const wuffs_bmp__decoder* self) {
13432 if (!self) {
13433 return 0;
13434 }
13435 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
13436 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
13437 return 0;
13438 }
13439
13440 if (self->private_impl.f_call_sequence > 2) {
13441 return 1;
13442 }
13443 return 0;
13444}
13445
13446// -------- func bmp.decoder.restart_frame
13447
13448WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13449wuffs_bmp__decoder__restart_frame(
13450 wuffs_bmp__decoder* self,
13451 uint64_t a_index,
13452 uint64_t a_io_position) {
13453 if (!self) {
13454 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
13455 }
13456 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
13457 return wuffs_base__make_status(
13458 (self->private_impl.magic == WUFFS_BASE__DISABLED)
13459 ? wuffs_base__error__disabled_by_previous_error
13460 : wuffs_base__error__initialize_not_called);
13461 }
13462
13463 if (self->private_impl.f_call_sequence == 0) {
13464 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
13465 }
13466 if (a_index != 0) {
13467 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13468 }
13469 self->private_impl.f_call_sequence = 1;
13470 self->private_impl.f_frame_config_io_position = a_io_position;
13471 return wuffs_base__make_status(NULL);
13472}
13473
13474// -------- func bmp.decoder.set_report_metadata
13475
13476WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
13477wuffs_bmp__decoder__set_report_metadata(
13478 wuffs_bmp__decoder* self,
13479 uint32_t a_fourcc,
13480 bool a_report) {
13481 return wuffs_base__make_empty_struct();
13482}
13483
13484// -------- func bmp.decoder.tell_me_more
13485
13486WUFFS_BASE__MAYBE_STATIC wuffs_base__status
13487wuffs_bmp__decoder__tell_me_more(
13488 wuffs_bmp__decoder* self,
13489 wuffs_base__io_buffer* a_dst,
13490 wuffs_base__more_information* a_minfo,
13491 wuffs_base__io_buffer* a_src) {
13492 if (!self) {
13493 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
13494 }
13495 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
13496 return wuffs_base__make_status(
13497 (self->private_impl.magic == WUFFS_BASE__DISABLED)
13498 ? wuffs_base__error__disabled_by_previous_error
13499 : wuffs_base__error__initialize_not_called);
13500 }
13501 if (!a_dst || !a_src) {
13502 self->private_impl.magic = WUFFS_BASE__DISABLED;
13503 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13504 }
13505 if ((self->private_impl.active_coroutine != 0) &&
13506 (self->private_impl.active_coroutine != 4)) {
13507 self->private_impl.magic = WUFFS_BASE__DISABLED;
13508 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
13509 }
13510 self->private_impl.active_coroutine = 0;
13511 wuffs_base__status status = wuffs_base__make_status(NULL);
13512
13513 if (self->private_impl.f_io_redirect_fourcc <= 1) {
13514 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
13515 goto exit;
13516 }
13517 if (a_minfo != NULL) {
13518 wuffs_base__more_information__set(a_minfo,
13519 1,
13520 self->private_impl.f_io_redirect_fourcc,
13521 0,
13522 self->private_impl.f_io_redirect_pos,
13523 18446744073709551615u);
13524 }
13525 self->private_impl.f_io_redirect_fourcc = 1;
13526
13527 goto ok;
13528 ok:
13529 goto exit;
13530 exit:
13531 if (wuffs_base__status__is_error(&status)) {
13532 self->private_impl.magic = WUFFS_BASE__DISABLED;
13533 }
13534 return status;
13535}
13536
13537// -------- func bmp.decoder.workbuf_len
13538
13539WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
13540wuffs_bmp__decoder__workbuf_len(
13541 const wuffs_bmp__decoder* self) {
13542 if (!self) {
13543 return wuffs_base__utility__empty_range_ii_u64();
13544 }
13545 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
13546 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
13547 return wuffs_base__utility__empty_range_ii_u64();
13548 }
13549
13550 return wuffs_base__utility__make_range_ii_u64(0, 0);
13551}
13552
13553#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
13554
13555#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
13556
13557// ---------------- Status Codes Implementations
13558
13559// ---------------- Private Consts
13560
13561static const uint32_t
13562WUFFS_CRC32__IEEE_TABLE[16][256]WUFFS_BASE__POTENTIALLY_UNUSED = {
13563 {
13564 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
13565 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
13566 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
13567 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
13568 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
13569 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
13570 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
13571 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
13572 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
13573 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
13574 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
13575 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
13576 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
13577 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
13578 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
13579 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
13580 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
13581 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
13582 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
13583 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
13584 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
13585 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
13586 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
13587 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
13588 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
13589 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
13590 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
13591 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
13592 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
13593 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
13594 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
13595 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117,
13596 }, {
13597 0, 421212481, 842424962, 724390851, 1684849924, 2105013317, 1448781702, 1329698503,
13598 3369699848, 3519200073, 4210026634, 3824474571, 2897563404, 3048111693, 2659397006, 2274893007,
13599 1254232657, 1406739216, 2029285587, 1643069842, 783210325, 934667796, 479770071, 92505238,
13600 2182846553, 2600511768, 2955803355, 2838940570, 3866582365, 4285295644, 3561045983, 3445231262,
13601 2508465314, 2359236067, 2813478432, 3198777185, 4058571174, 3908292839, 3286139684, 3670389349,
13602 1566420650, 1145479147, 1869335592, 1987116393, 959540142, 539646703, 185010476, 303839341,
13603 3745920755, 3327985586, 3983561841, 4100678960, 3140154359, 2721170102, 2300350837, 2416418868,
13604 396344571, 243568058, 631889529, 1018359608, 1945336319, 1793607870, 1103436669, 1490954812,
13605 4034481925, 3915546180, 3259968903, 3679722694, 2484439553, 2366552896, 2787371139, 3208174018,
13606 950060301, 565965900, 177645455, 328046286, 1556873225, 1171730760, 1861902987, 2011255754,
13607 3132841300, 2745199637, 2290958294, 2442530455, 3738671184, 3352078609, 3974232786, 4126854035,
13608 1919080284, 1803150877, 1079293406, 1498383519, 370020952, 253043481, 607678682, 1025720731,
13609 1711106983, 2095471334, 1472923941, 1322268772, 26324643, 411738082, 866634785, 717028704,
13610 2904875439, 3024081134, 2668790573, 2248782444, 3376948395, 3495106026, 4219356713, 3798300520,
13611 792689142, 908347575, 487136116, 68299317, 1263779058, 1380486579, 2036719216, 1618931505,
13612 3890672638, 4278043327, 3587215740, 3435896893, 2206873338, 2593195963, 2981909624, 2829542713,
13613 998479947, 580430090, 162921161, 279890824, 1609522511, 1190423566, 1842954189, 1958874764,
13614 4082766403, 3930137346, 3245109441, 3631694208, 2536953671, 2385372678, 2768287173, 3155920004,
13615 1900120602, 1750776667, 1131931800, 1517083097, 355290910, 204897887, 656092572, 1040194781,
13616 3113746450, 2692952403, 2343461520, 2461357009, 3723805974, 3304059991, 4022511508, 4141455061,
13617 2919742697, 3072101800, 2620513899, 2234183466, 3396041197, 3547351212, 4166851439, 3779471918,
13618 1725839073, 2143618976, 1424512099, 1307796770, 45282277, 464110244, 813994343, 698327078,
13619 3838160568, 4259225593, 3606301754, 3488152955, 2158586812, 2578602749, 2996767038, 2877569151,
13620 740041904, 889656817, 506086962, 120682355, 1215357364, 1366020341, 2051441462, 1667084919,
13621 3422213966, 3538019855, 4190942668, 3772220557, 2945847882, 3062702859, 2644537544, 2226864521,
13622 52649286, 439905287, 823476164, 672009861, 1733269570, 2119477507, 1434057408, 1281543041,
13623 2167981343, 2552493150, 3004082077, 2853541596, 3847487515, 4233048410, 3613549209, 3464057816,
13624 1239502615, 1358593622, 2077699477, 1657543892, 764250643, 882293586, 532408465, 111204816,
13625 1585378284, 1197851309, 1816695150, 1968414767, 974272232, 587794345, 136598634, 289367339,
13626 2527558116, 2411481253, 2760973158, 3179948583, 4073438432, 3956313505, 3237863010, 3655790371,
13627 347922877, 229101820, 646611775, 1066513022, 1892689081, 1774917112, 1122387515, 1543337850,
13628 3697634229, 3313392372, 3998419255, 4148705398, 3087642289, 2702352368, 2319436851, 2468674930,
13629 }, {
13630 0, 29518391, 59036782, 38190681, 118073564, 114017003, 76381362, 89069189,
13631 236147128, 265370511, 228034006, 206958561, 152762724, 148411219, 178138378, 190596925,
13632 472294256, 501532999, 530741022, 509615401, 456068012, 451764635, 413917122, 426358261,
13633 305525448, 334993663, 296822438, 275991697, 356276756, 352202787, 381193850, 393929805,
13634 944588512, 965684439, 1003065998, 973863097, 1061482044, 1049003019, 1019230802, 1023561829,
13635 912136024, 933002607, 903529270, 874031361, 827834244, 815125939, 852716522, 856752605,
13636 611050896, 631869351, 669987326, 640506825, 593644876, 580921211, 551983394, 556069653,
13637 712553512, 733666847, 704405574, 675154545, 762387700, 749958851, 787859610, 792175277,
13638 1889177024, 1901651959, 1931368878, 1927033753, 2006131996, 1985040171, 1947726194, 1976933189,
13639 2122964088, 2135668303, 2098006038, 2093965857, 2038461604, 2017599123, 2047123658, 2076625661,
13640 1824272048, 1836991623, 1866005214, 1861914857, 1807058540, 1786244187, 1748062722, 1777547317,
13641 1655668488, 1668093247, 1630251878, 1625932113, 1705433044, 1684323811, 1713505210, 1742760333,
13642 1222101792, 1226154263, 1263738702, 1251046777, 1339974652, 1310460363, 1281013650, 1301863845,
13643 1187289752, 1191637167, 1161842422, 1149379777, 1103966788, 1074747507, 1112139306, 1133218845,
13644 1425107024, 1429406311, 1467333694, 1454888457, 1408811148, 1379576507, 1350309090, 1371438805,
13645 1524775400, 1528845279, 1499917702, 1487177649, 1575719220, 1546255107, 1584350554, 1605185389,
13646 3778354048, 3774312887, 3803303918, 3816007129, 3862737756, 3892238699, 3854067506, 3833203973,
13647 4012263992, 4007927823, 3970080342, 3982554209, 3895452388, 3924658387, 3953866378, 3932773565,
13648 4245928176, 4241609415, 4271336606, 4283762345, 4196012076, 4225268251, 4187931714, 4166823541,
13649 4076923208, 4072833919, 4035198246, 4047918865, 4094247316, 4123732899, 4153251322, 4132437965,
13650 3648544096, 3636082519, 3673983246, 3678331705, 3732010428, 3753090955, 3723829714, 3694611429,
13651 3614117080, 3601426159, 3572488374, 3576541825, 3496125444, 3516976691, 3555094634, 3525581405,
13652 3311336976, 3298595879, 3336186494, 3340255305, 3260503756, 3281337595, 3251864226, 3222399125,
13653 3410866088, 3398419871, 3368647622, 3372945905, 3427010420, 3448139075, 3485520666, 3456284973,
13654 2444203584, 2423127159, 2452308526, 2481530905, 2527477404, 2539934891, 2502093554, 2497740997,
13655 2679949304, 2659102159, 2620920726, 2650438049, 2562027300, 2574714131, 2603727690, 2599670141,
13656 2374579504, 2353749767, 2383274334, 2412743529, 2323684844, 2336421851, 2298759554, 2294686645,
13657 2207933576, 2186809023, 2149495014, 2178734801, 2224278612, 2236720739, 2266437690, 2262135309,
13658 2850214048, 2820717207, 2858812622, 2879680249, 2934667388, 2938704459, 2909776914, 2897069605,
13659 2817622296, 2788420399, 2759153014, 2780249921, 2700618180, 2704950259, 2742877610, 2730399645,
13660 3049550800, 3020298727, 3057690558, 3078802825, 2999835404, 3004150075, 2974355298, 2961925461,
13661 3151438440, 3121956959, 3092510214, 3113327665, 3168701108, 3172786307, 3210370778, 3197646061,
13662 }, {
13663 0, 3099354981, 2852767883, 313896942, 2405603159, 937357362, 627793884, 2648127673,
13664 3316918511, 2097696650, 1874714724, 3607201537, 1255587768, 4067088605, 3772741427, 1482887254,
13665 1343838111, 3903140090, 4195393300, 1118632049, 3749429448, 1741137837, 1970407491, 3452858150,
13666 2511175536, 756094997, 1067759611, 2266550430, 449832999, 2725482306, 2965774508, 142231497,
13667 2687676222, 412010587, 171665333, 2995192016, 793786473, 2548850444, 2237264098, 1038456711,
13668 1703315409, 3711623348, 3482275674, 1999841343, 3940814982, 1381529571, 1089329165, 4166106984,
13669 4029413537, 1217896388, 1512189994, 3802027855, 2135519222, 3354724499, 3577784189, 1845280792,
13670 899665998, 2367928107, 2677414085, 657096608, 3137160985, 37822588, 284462994, 2823350519,
13671 2601801789, 598228824, 824021174, 2309093331, 343330666, 2898962447, 3195996129, 113467524,
13672 1587572946, 3860600759, 4104763481, 1276501820, 3519211397, 1769898208, 2076913422, 3279374443,
13673 3406630818, 1941006535, 1627703081, 3652755532, 1148164341, 4241751952, 3999682686, 1457141531,
13674 247015245, 3053797416, 2763059142, 470583459, 2178658330, 963106687, 735213713, 2473467892,
13675 992409347, 2207944806, 2435792776, 697522413, 3024379988, 217581361, 508405983, 2800865210,
13676 4271038444, 1177467017, 1419450215, 3962007554, 1911572667, 3377213406, 3690561584, 1665525589,
13677 1799331996, 3548628985, 3241568279, 2039091058, 3831314379, 1558270126, 1314193216, 4142438437,
13678 2928380019, 372764438, 75645176, 3158189981, 568925988, 2572515393, 2346768303, 861712586,
13679 3982079547, 1441124702, 1196457648, 4293663189, 1648042348, 3666298377, 3358779879, 1888390786,
13680 686661332, 2421291441, 2196002399, 978858298, 2811169155, 523464422, 226935048, 3040519789,
13681 3175145892, 100435649, 390670639, 2952089162, 841119475, 2325614998, 2553003640, 546822429,
13682 2029308235, 3225988654, 3539796416, 1782671013, 4153826844, 1328167289, 1570739863, 3844338162,
13683 1298864389, 4124540512, 3882013070, 1608431339, 3255406162, 2058742071, 1744848601, 3501990332,
13684 2296328682, 811816591, 584513889, 2590678532, 129869501, 3204563416, 2914283062, 352848211,
13685 494030490, 2781751807, 3078325777, 264757620, 2450577869, 715964072, 941166918, 2158327331,
13686 3636881013, 1618608400, 1926213374, 3396585883, 1470427426, 4011365959, 4255988137, 1158766284,
13687 1984818694, 3471935843, 3695453837, 1693991400, 4180638033, 1100160564, 1395044826, 3952793279,
13688 3019491049, 189112716, 435162722, 2706139399, 1016811966, 2217162459, 2526189877, 774831696,
13689 643086745, 2666061564, 2354934034, 887166583, 2838900430, 294275499, 54519365, 3145957664,
13690 3823145334, 1532818963, 1240029693, 4048895640, 1820460577, 3560857924, 3331051178, 2117577167,
13691 3598663992, 1858283101, 2088143283, 3301633750, 1495127663, 3785470218, 4078182116, 1269332353,
13692 332098007, 2876706482, 3116540252, 25085497, 2628386432, 605395429, 916469259, 2384220526,
13693 2254837415, 1054503362, 745528876, 2496903497, 151290352, 2981684885, 2735556987, 464596510,
13694 1137851976, 4218313005, 3923506883, 1365741990, 3434129695, 1946996346, 1723425172, 3724871409,
13695 }, {
13696 0, 1029712304, 2059424608, 1201699536, 4118849216, 3370159984, 2403399072, 2988497936,
13697 812665793, 219177585, 1253054625, 2010132753, 3320900865, 4170237105, 3207642721, 2186319825,
13698 1625331586, 1568718386, 438355170, 658566482, 2506109250, 2818578674, 4020265506, 3535817618,
13699 1351670851, 1844508147, 709922595, 389064339, 2769320579, 2557498163, 3754961379, 3803185235,
13700 3250663172, 4238411444, 3137436772, 2254525908, 876710340, 153198708, 1317132964, 1944187668,
13701 4054934725, 3436268917, 2339452837, 3054575125, 70369797, 961670069, 2129760613, 1133623509,
13702 2703341702, 2621542710, 3689016294, 3867263574, 1419845190, 1774270454, 778128678, 318858390,
13703 2438067015, 2888948471, 3952189479, 3606153623, 1691440519, 1504803895, 504432359, 594620247,
13704 1492342857, 1704161785, 573770537, 525542041, 2910060169, 2417219385, 3618876905, 3939730521,
13705 1753420680, 1440954936, 306397416, 790849880, 2634265928, 2690882808, 3888375336, 3668168600,
13706 940822475, 91481723, 1121164459, 2142483739, 3448989963, 4042473659, 3075684971, 2318603227,
13707 140739594, 889433530, 1923340138, 1338244826, 4259521226, 3229813626, 2267247018, 3124975642,
13708 2570221389, 2756861693, 3824297005, 3734113693, 1823658381, 1372780605, 376603373, 722643805,
13709 2839690380, 2485261628, 3548540908, 4007806556, 1556257356, 1638052860, 637716780, 459464860,
13710 4191346895, 3300051327, 2199040943, 3195181599, 206718479, 825388991, 1989285231, 1274166495,
13711 3382881038, 4106388158, 3009607790, 2382549470, 1008864718, 21111934, 1189240494, 2072147742,
13712 2984685714, 2357631266, 3408323570, 4131834434, 1147541074, 2030452706, 1051084082, 63335554,
13713 2174155603, 3170292451, 4216760371, 3325460867, 1947622803, 1232499747, 248909555, 867575619,
13714 3506841360, 3966111392, 2881909872, 2527485376, 612794832, 434546784, 1581699760, 1663499008,
13715 3782634705, 3692447073, 2612412337, 2799048193, 351717905, 697754529, 1849071985, 1398190273,
13716 1881644950, 1296545318, 182963446, 931652934, 2242328918, 3100053734, 4284967478, 3255255942,
13717 1079497815, 2100821479, 983009079, 133672583, 3050795671, 2293717799, 3474399735, 4067887175,
13718 281479188, 765927844, 1778867060, 1466397380, 3846680276, 3626469220, 2676489652, 2733102084,
13719 548881365, 500656741, 1517752501, 1729575173, 3577210133, 3898068133, 2952246901, 2459410373,
13720 3910527195, 3564487019, 2480257979, 2931134987, 479546907, 569730987, 1716854139, 1530213579,
13721 3647316762, 3825568426, 2745561210, 2663766474, 753206746, 293940330, 1445287610, 1799716618,
13722 2314567513, 3029685993, 4080348217, 3461678473, 2088098201, 1091956777, 112560889, 1003856713,
13723 3112514712, 2229607720, 3276105720, 4263857736, 1275433560, 1902492648, 918929720, 195422344,
13724 685033439, 364179055, 1377080511, 1869921551, 3713294623, 3761522863, 2811507327, 2599689167,
13725 413436958, 633644462, 1650777982, 1594160846, 3978570462, 3494118254, 2548332990, 2860797966,
13726 1211387997, 1968470509, 854852413, 261368461, 3182753437, 2161434413, 3346310653, 4195650637,
13727 2017729436, 1160000044, 42223868, 1071931724, 2378480988, 2963576044, 4144295484, 3395602316,
13728 }, {
13729 0, 3411858341, 1304994059, 2257875630, 2609988118, 1355649459, 3596215069, 486879416,
13730 3964895853, 655315400, 2711298918, 1791488195, 2009251963, 3164476382, 973758832, 4048990933,
13731 64357019, 3364540734, 1310630800, 2235723829, 2554806413, 1394316072, 3582976390, 517157411,
13732 4018503926, 618222419, 2722963965, 1762783832, 1947517664, 3209171269, 970744811, 4068520014,
13733 128714038, 3438335635, 1248109629, 2167961496, 2621261600, 1466012805, 3522553387, 447296910,
13734 3959392091, 547575038, 2788632144, 1835791861, 1886307661, 3140622056, 1034314822, 4143626211,
13735 75106221, 3475428360, 1236444838, 2196665603, 2682996155, 1421317662, 3525567664, 427767573,
13736 3895035328, 594892389, 2782995659, 1857943406, 1941489622, 3101955187, 1047553757, 4113347960,
13737 257428076, 3288652233, 1116777319, 2311878850, 2496219258, 1603640287, 3640781169, 308099796,
13738 3809183745, 676813732, 2932025610, 1704983215, 2023410199, 3016104370, 894593820, 4262377657,
13739 210634999, 3352484690, 1095150076, 2316991065, 2535410401, 1547934020, 3671583722, 294336591,
13740 3772615322, 729897279, 2903845777, 1716123700, 2068629644, 2953845545, 914647431, 4258839074,
13741 150212442, 3282623743, 1161604689, 2388688372, 2472889676, 1480171241, 3735940167, 368132066,
13742 3836185911, 805002898, 2842635324, 1647574937, 2134298401, 3026852996, 855535146, 4188192143,
13743 186781121, 3229539940, 1189784778, 2377547631, 2427670487, 1542429810, 3715886812, 371670393,
13744 3882979244, 741170185, 2864262823, 1642462466, 2095107514, 3082559007, 824732849, 4201955092,
13745 514856152, 3589064573, 1400419795, 2552522358, 2233554638, 1316849003, 3370776517, 62202976,
13746 4075001525, 968836368, 3207280574, 1954014235, 1769133219, 2720925446, 616199592, 4024870413,
13747 493229635, 3594175974, 1353627464, 2616354029, 2264355925, 1303087088, 3409966430, 6498043,
13748 4046820398, 979978123, 3170710821, 2007099008, 1789187640, 2717386141, 661419827, 3962610838,
13749 421269998, 3527459403, 1423225061, 2676515648, 2190300152, 1238466653, 3477467891, 68755798,
13750 4115633027, 1041448998, 3095868040, 1943789869, 1860096405, 2776760880, 588673182, 3897205563,
13751 449450869, 3516317904, 1459794558, 2623431131, 2170245475, 1242006214, 3432247400, 131015629,
13752 4137259288, 1036337853, 3142660115, 1879958454, 1829294862, 2790523051, 549483013, 3952910752,
13753 300424884, 3669282065, 1545650111, 2541513754, 2323209378, 1092980487, 3350330793, 216870412,
13754 4256931033, 921128828, 2960342482, 2066738807, 1714085583, 2910195050, 736264132, 3770592353,
13755 306060335, 3647131530, 1610005796, 2494197377, 2309971513, 1123257756, 3295149874, 255536279,
13756 4268596802, 892423655, 3013951305, 2029645036, 1711070292, 2929725425, 674528607, 3815288570,
13757 373562242, 3709388839, 1535949449, 2429577516, 2379569556, 1183418929, 3223189663, 188820282,
13758 4195850735, 827017802, 3084859620, 2089020225, 1636228089, 2866415708, 743340786, 3876759895,
13759 361896217, 3738094268, 1482340370, 2466671543, 2382584591, 1163888810, 3284924932, 144124321,
13760 4190215028, 849168593, 3020503679, 2136336858, 1649465698, 2836138695, 798521449, 3838094284,
13761 }, {
13762 0, 2792819636, 2543784233, 837294749, 4098827283, 1379413927, 1674589498, 3316072078,
13763 871321191, 2509784531, 2758827854, 34034938, 3349178996, 1641505216, 1346337629, 4131942633,
13764 1742642382, 3249117050, 4030828007, 1446413907, 2475800797, 904311657, 68069876, 2725880384,
13765 1412551337, 4064729373, 3283010432, 1708771380, 2692675258, 101317902, 937551763, 2442587175,
13766 3485284764, 1774858792, 1478633653, 4266992385, 1005723023, 2642744891, 2892827814, 169477906,
13767 4233263099, 1512406095, 1808623314, 3451546982, 136139752, 2926205020, 2676114113, 972376437,
13768 2825102674, 236236518, 1073525883, 2576072655, 1546420545, 4200303349, 3417542760, 1841601500,
13769 2609703733, 1039917185, 202635804, 2858742184, 1875103526, 3384067218, 4166835727, 1579931067,
13770 1141601657, 3799809741, 3549717584, 1977839588, 2957267306, 372464350, 668680259, 2175552503,
13771 2011446046, 3516084394, 3766168119, 1175200131, 2209029901, 635180217, 338955812, 2990736784,
13772 601221559, 2242044419, 3024812190, 306049834, 3617246628, 1911408144, 1074125965, 3866285881,
13773 272279504, 3058543716, 2275784441, 567459149, 3832906691, 1107462263, 1944752874, 3583875422,
13774 2343980261, 767641425, 472473036, 3126744696, 2147051766, 3649987394, 3899029983, 1309766251,
13775 3092841090, 506333494, 801510315, 2310084639, 1276520081, 3932237093, 3683203000, 2113813516,
13776 3966292011, 1243601823, 2079834370, 3716205238, 405271608, 3192979340, 2411259153, 701492901,
13777 3750207052, 2045810168, 1209569125, 4000285905, 734575199, 2378150379, 3159862134, 438345922,
13778 2283203314, 778166598, 529136603, 3120492655, 2086260449, 3660498261, 3955679176, 1303499900,
13779 3153699989, 495890209, 744928700, 2316418568, 1337360518, 3921775410, 3626602927, 2120129051,
13780 4022892092, 1237286280, 2018993941, 3726666913, 461853231, 3186645403, 2350400262, 711936178,
13781 3693557851, 2052076527, 1270360434, 3989775046, 677911624, 2384402428, 3220639073, 427820757,
13782 1202443118, 3789347034, 3493118535, 1984154099, 3018127229, 362020041, 612099668, 2181885408,
13783 1950653705, 3526596285, 3822816288, 1168934804, 2148251930, 645706414, 395618355, 2984485767,
13784 544559008, 2248295444, 3085590153, 295523645, 3560598451, 1917673479, 1134918298, 3855773998,
13785 328860103, 3052210803, 2214924526, 577903450, 3889505748, 1101147744, 1883911421, 3594338121,
13786 3424493451, 1785369663, 1535282850, 4260726038, 944946072, 2653270060, 2949491377, 163225861,
13787 4294103532, 1501944408, 1752023237, 3457862513, 196998655, 2915761739, 2619532502, 978710370,
13788 2881684293, 229902577, 1012666988, 2586515928, 1603020630, 4193987810, 3356702335, 1852063179,
13789 2553040162, 1046169238, 263412747, 2848217023, 1818454321, 3390333573, 4227627032, 1569420204,
13790 60859927, 2782375331, 2487203646, 843627658, 4159668740, 1368951216, 1617990445, 3322386585,
13791 810543216, 2520310724, 2815490393, 27783917, 3288386659, 1652017111, 1402985802, 4125677310,
13792 1685994201, 3255382381, 4091620336, 1435902020, 2419138250, 910562686, 128847843, 2715354199,
13793 1469150398, 4058414858, 3222168983, 1719234083, 2749255853, 94984985, 876691844, 2453031472,
13794 }, {
13795 0, 3433693342, 1109723005, 2391738339, 2219446010, 1222643300, 3329165703, 180685081,
13796 3555007413, 525277995, 2445286600, 1567235158, 1471092047, 2600801745, 361370162, 3642757804,
13797 2092642603, 2953916853, 1050555990, 4063508168, 4176560081, 878395215, 3134470316, 1987983410,
13798 2942184094, 1676945920, 3984272867, 567356797, 722740324, 3887998202, 1764827929, 2778407815,
13799 4185285206, 903635656, 3142804779, 2012833205, 2101111980, 2979425330, 1058630609, 4088621903,
13800 714308067, 3862526333, 1756790430, 2753330688, 2933487385, 1651734407, 3975966820, 542535930,
13801 2244825981, 1231508451, 3353891840, 188896414, 25648519, 3442302233, 1134713594, 2399689316,
13802 1445480648, 2592229462, 336416693, 3634843435, 3529655858, 516441772, 2420588879, 1559052753,
13803 698204909, 3845636723, 1807271312, 2803025166, 2916600855, 1635634313, 4025666410, 593021940,
13804 4202223960, 919787974, 3093159461, 1962401467, 2117261218, 2996361020, 1008193759, 4038971457,
13805 1428616134, 2576151384, 386135227, 3685348389, 3513580860, 499580322, 2471098945, 1608776415,
13806 2260985971, 1248454893, 3303468814, 139259792, 42591881, 3458459159, 1085071860, 2349261162,
13807 3505103035, 474062885, 2463016902, 1583654744, 1419882049, 2550902495, 377792828, 3660491170,
13808 51297038, 3483679632, 1093385331, 2374089965, 2269427188, 1273935210, 3311514249, 164344343,
13809 2890961296, 1627033870, 4000683757, 585078387, 672833386, 3836780532, 1782552599, 2794821769,
13810 2142603813, 3005188795, 1032883544, 4047146438, 4227826911, 928351297, 3118105506, 1970307900,
13811 1396409818, 2677114180, 287212199, 3719594553, 3614542624, 467372990, 2505346141, 1509854403,
13812 2162073199, 1282711281, 3271268626, 240228748, 76845205, 3359543307, 1186043880, 2317064054,
13813 796964081, 3811226735, 1839575948, 2702160658, 2882189835, 1734392469, 3924802934, 625327592,
13814 4234522436, 818917338, 3191908409, 1927981223, 2016387518, 3028656416, 973776579, 4137723485,
13815 2857232268, 1726474002, 3899187441, 616751215, 772270454, 3803048424, 1814228491, 2693328533,
13816 2041117753, 3036871847, 999160644, 4146592730, 4259508931, 826864221, 3217552830, 1936586016,
13817 3606501031, 442291769, 2496909786, 1484378436, 1388107869, 2652297411, 278519584, 3694387134,
13818 85183762, 3384397196, 1194773103, 2342308593, 2170143720, 1307820918, 3279733909, 265733131,
13819 2057717559, 3054258089, 948125770, 4096344276, 4276898253, 843467091, 3167309488, 1885556270,
13820 2839764098, 1709792284, 3949353983, 667704161, 755585656, 3785577190, 1865176325, 2743489947,
13821 102594076, 3401021058, 1144549729, 2291298815, 2186770662, 1325234296, 3228729243, 215514885,
13822 3589828009, 424832311, 2547870420, 1534552650, 1370645331, 2635621325, 328688686, 3745342640,
13823 2211456353, 1333405183, 3254067740, 224338562, 127544219, 3408931589, 1170156774, 2299866232,
13824 1345666772, 2627681866, 303053225, 3736746295, 3565105198, 416624816, 2522494803, 1525692365,
13825 4285207626, 868291796, 3176010551, 1910772649, 2065767088, 3079346734, 956571085, 4121828691,
13826 747507711, 3760459617, 1856702594, 2717976604, 2831417605, 1684930971, 3940615800, 642451174,
13827 },
13828 {
13829 0, 393942083, 787884166, 965557445, 1575768332, 1251427663, 1931114890, 1684106697,
13830 3151536664, 2896410203, 2502855326, 2186649309, 3862229780, 4048545623, 3368213394, 3753496529,
13831 2898281073, 3149616690, 2184604407, 2504883892, 4046197629, 3864463166, 3755621371, 3366006712,
13832 387506281, 6550570, 971950319, 781573292, 1257550181, 1569695014, 1677892067, 1937345952,
13833 2196865699, 2508887776, 2886183461, 3145514598, 3743273903, 3362179052, 4058774313, 3868258154,
13834 958996667, 777139448, 400492605, 10755198, 1690661303, 1941857780, 1244879153, 1565019506,
13835 775012562, 961205393, 13101140, 398261271, 1943900638, 1688634781, 1563146584, 1246801179,
13836 2515100362, 2190636681, 3139390028, 2892258831, 3355784134, 3749586821, 3874691904, 4052225795,
13837 3734110983, 3387496260, 4033096577, 3877584834, 2206093835, 2483373640, 2911402637, 3136515790,
13838 1699389727, 1915860316, 1270647193, 1556585946, 950464531, 803071056, 374397077, 19647702,
13839 1917993334, 1697207605, 1554278896, 1272937907, 800985210, 952435769, 21510396, 372452543,
13840 3381322606, 3740399405, 3883715560, 4027047851, 2489758306, 2199758369, 3130039012, 2917895847,
13841 1550025124, 1259902439, 1922410786, 1710144865, 26202280, 385139947, 796522542, 939715693,
13842 3887801276, 4039129087, 3377269562, 3728088953, 3126293168, 2905368307, 2493602358, 2212122229,
13843 4037264341, 3889747862, 3730172755, 3375300368, 2907673305, 3124004506, 2209987167, 2495786524,
13844 1266377165, 1543533966, 1703758155, 1928748296, 379007169, 32253058, 945887303, 790236164,
13845 1716846671, 1898845196, 1218652361, 1608006794, 1002000707, 750929152, 357530053, 36990342,
13846 3717046871, 3405166100, 4084959953, 3825245842, 2153902939, 2535122712, 2929187805, 3119304606,
13847 3398779454, 3723384445, 3831720632, 4078468859, 2541294386, 2147616625, 3113171892, 2935238647,
13848 1900929062, 1714877541, 1606142112, 1220599011, 748794154, 1004184937, 39295404, 355241455,
13849 3835986668, 4091516591, 3394415210, 3710500393, 3108557792, 2922629027, 2545875814, 2160455461,
13850 1601970420, 1208431799, 1904871538, 1727077425, 43020792, 367748539, 744905086, 991776061,
13851 1214562461, 1595921630, 1720903707, 1911159896, 361271697, 49513938, 998160663, 738569556,
13852 4089209477, 3838277318, 3712633347, 3392233024, 2924491657, 3106613194, 2158369551, 2547846988,
13853 3100050248, 2948339467, 2519804878, 2169126797, 3844821572, 4065347079, 3420289730, 3701894785,
13854 52404560, 342144275, 770279894, 982687125, 1593045084, 1233708063, 1879431386, 1736363161,
13855 336019769, 58479994, 988899775, 764050940, 1240141877, 1586496630, 1729968307, 1885744368,
13856 2950685473, 3097818978, 2166999975, 2522013668, 4063474221, 3846743662, 3703937707, 3418263272,
13857 976650731, 760059304, 348170605, 62635310, 1742393575, 1889649828, 1227683937, 1582820386,
13858 2179867635, 2526361520, 2937588597, 3093503798, 3691148031, 3413731004, 4076100217, 3851374138,
13859 2532754330, 2173556697, 3087067932, 2944139103, 3407516310, 3697379029, 3857496592, 4070026835,
13860 758014338, 978679233, 64506116, 346250567, 1891774606, 1740186829, 1580472328, 1229917259,
13861 }, {
13862 0, 4022496062, 83218493, 3946298115, 166436986, 3861498692, 220098631, 3806075769,
13863 332873972, 4229245898, 388141257, 4175494135, 440197262, 4127099824, 516501683, 4044053389,
13864 665747944, 3362581206, 593187285, 3432594155, 776282514, 3246869164, 716239279, 3312622225,
13865 880394524, 3686509090, 814485793, 3746462239, 1033003366, 3528460888, 963096923, 3601193573,
13866 1331495888, 2694801646, 1269355501, 2758457555, 1186374570, 2843003028, 1111716759, 2910918825,
13867 1552565028, 3007850522, 1484755737, 3082680359, 1432478558, 3131279456, 1368666979, 3193329757,
13868 1760789048, 2268195078, 1812353541, 2210675003, 1628971586, 2396670332, 1710092927, 2318375233,
13869 2066006732, 2498144754, 2144408305, 2417195471, 1926193846, 2634877320, 1983558283, 2583222709,
13870 2662991776, 1903717534, 2588923805, 1972223139, 2538711002, 2022952164, 2477029351, 2087066841,
13871 2372749140, 1655647338, 2308478825, 1717238871, 2223433518, 1799654416, 2155034387, 1873894445,
13872 3105130056, 1456926070, 3185661557, 1378041163, 2969511474, 1597852940, 3020617231, 1539874097,
13873 2864957116, 1157737858, 2922780289, 1106542015, 2737333958, 1290407416, 2816325371, 1210047941,
13874 3521578096, 1042640718, 3574781005, 986759027, 3624707082, 936300340, 3707335735, 859512585,
13875 3257943172, 770846650, 3334837433, 688390023, 3420185854, 605654976, 3475911875, 552361981,
13876 4132013464, 428600998, 4072428965, 494812827, 4288816610, 274747100, 4216845791, 345349857,
13877 3852387692, 173846098, 3781891409, 245988975, 3967116566, 62328360, 3900749099, 121822741,
13878 3859089665, 164061759, 3807435068, 221426178, 4025395579, 2933317, 3944446278, 81334904,
13879 4124199413, 437265099, 4045904328, 518386422, 4231653775, 335250097, 4174133682, 386814604,
13880 3249244393, 778691543, 3311294676, 714879978, 3359647891, 662848429, 3434477742, 595039120,
13881 3531393053, 1035903779, 3599308832, 961245982, 3684132967, 877986649, 3747788890, 815846244,
13882 2841119441, 1184522735, 2913852140, 1114616274, 2696129195, 1332855189, 2756082326, 1266946472,
13883 3129952805, 1431118107, 3195705880, 1371074854, 3009735263, 1554415969, 3079748194, 1481855324,
13884 2398522169, 1630855175, 2315475716, 1707159610, 2266835779, 1759461501, 2213084030, 1814728768,
13885 2636237773, 1927520499, 2580814832, 1981182158, 2496293815, 2064121993, 2420095882, 2147340468,
13886 2025787041, 2541577631, 2085281436, 2475210146, 1901375195, 2660681189, 1973518054, 2590184920,
13887 1801997909, 2225743211, 1872600680, 2153772374, 1652813359, 2369881361, 1719025170, 2310296876,
13888 1594986313, 2966676599, 1541693300, 3022402634, 1459236659, 3107472397, 1376780046, 3184366640,
13889 1288097725, 2734990467, 1211309952, 2817619134, 1160605639, 2867791097, 1104723962, 2920993988,
13890 937561457, 3626001999, 857201996, 3704993394, 1040821515, 3519792693, 989625654, 3577615880,
13891 607473029, 3421972155, 549494200, 3473077894, 769584639, 3256649409, 690699714, 3337180924,
13892 273452185, 4287555495, 347692196, 4219156378, 430386403, 4133832669, 491977950, 4069562336,
13893 60542061, 3965298515, 124656720, 3903616878, 175139863, 3853649705, 243645482, 3779581716,
13894 }, {
13895 0, 3247366080, 1483520449, 2581751297, 2967040898, 1901571138, 3904227907, 691737987,
13896 3133399365, 2068659845, 3803142276, 589399876, 169513671, 3415493895, 1383475974, 2482566342,
13897 2935407819, 1870142219, 4137319690, 924099274, 506443593, 3751897225, 1178799752, 2278412616,
13898 339027342, 3585866318, 1280941135, 2379694991, 2766951948, 1700956620, 4236308429, 1024339981,
13899 2258407383, 1192382487, 3740284438, 528411094, 910556245, 4157285269, 1848198548, 2946996820,
13900 1012887186, 4258378066, 1681119059, 2780629139, 2357599504, 1292419792, 3572147409, 358906641,
13901 678054684, 3924071644, 1879503581, 2978491677, 2561882270, 1497229150, 3235873119, 22109855,
13902 2460592729, 1395094937, 3401913240, 189516888, 577821147, 3825075739, 2048679962, 3146956762,
13903 3595049455, 398902831, 2384764974, 1336573934, 1720805997, 2803873197, 1056822188, 4285729900,
13904 1821112490, 2902796138, 887570795, 4117339819, 3696397096, 500978920, 2218668777, 1169222953,
13905 2025774372, 3106931428, 550659301, 3780950821, 3362238118, 166293862, 2416645991, 1367722151,
13906 3262987361, 66315169, 2584839584, 1537170016, 1923370979, 3005911075, 717813282, 3947244002,
13907 1356109368, 2438613496, 146288633, 3375820857, 3759007162, 562248314, 3093388411, 2045739963,
13908 3927406461, 731490493, 2994458300, 1945440636, 1523451135, 2604718911, 44219710, 3274466046,
13909 4263662323, 1068272947, 2790189874, 1740649714, 1325080945, 2406874801, 379033776, 3608758128,
13910 1155642294, 2238671990, 479005303, 3708016055, 4097359924, 901128180, 2891217397, 1843045941,
13911 2011248031, 3060787807, 797805662, 3993195422, 3342353949, 112630237, 2673147868, 1591353372,
13912 3441611994, 212601626, 2504944923, 1421914843, 2113644376, 3161815192, 630660761, 3826893145,
13913 3642224980, 412692116, 2172340373, 1089836885, 1775141590, 2822790422, 832715543, 4029474007,
13914 1674842129, 2723860433, 1001957840, 4197873168, 3540870035, 310623315, 2338445906, 1257178514,
13915 4051548744, 821257608, 2836464521, 1755307081, 1101318602, 2150241802, 432566283, 3628511179,
13916 1270766349, 2318435533, 332587724, 3529260300, 4217841807, 988411727, 2735444302, 1652903566,
13917 1602977411, 2651169091, 132630338, 3328776322, 4015131905, 786223809, 3074340032, 1991273216,
13918 3846741958, 616972294, 3173262855, 2091579847, 1435626564, 2485072772, 234706309, 3430124101,
13919 2712218736, 1613231024, 4190475697, 944458353, 292577266, 3506339890, 1226630707, 2291284467,
13920 459984181, 3672380149, 1124496628, 2189994804, 2880683703, 1782407543, 4091479926, 844224694,
13921 257943739, 3469817723, 1462980986, 2529005242, 3213269817, 2114471161, 3890881272, 644152632,
13922 3046902270, 1947391550, 3991973951, 746483711, 88439420, 3301680572, 1563018173, 2628197501,
13923 657826727, 3871046759, 2136545894, 3201811878, 2548879397, 1449267173, 3481299428, 235845156,
13924 2650161890, 1551408418, 3315268387, 68429027, 758067552, 3970035360, 1967360161, 3033356129,
13925 2311284588, 1213053100, 3517963949, 270598509, 958010606, 4170500910, 1635167535, 2700636911,
13926 855672361, 4069415401, 1802256360, 2866995240, 2212099499, 1113008747, 3686091882, 440112042,
13927 }, {
13928 0, 2611301487, 3963330207, 2006897392, 50740095, 2560849680, 4013794784, 1956178319,
13929 101480190, 2645113489, 3929532513, 1905435662, 84561281, 2662269422, 3912356638, 1922342769,
13930 202960380, 2545787283, 3760419683, 2072395532, 253679235, 2495322860, 3810871324, 2021655667,
13931 169122562, 2444351341, 3861841309, 2106214898, 152215677, 2461527058, 3844685538, 2123133581,
13932 405920760, 2207553431, 4094313831, 1873742088, 456646791, 2157096168, 4144791064, 1823027831,
13933 507358470, 2241388905, 4060492697, 1772322806, 490444409, 2258557462, 4043311334, 1789215881,
13934 338245124, 2408348267, 4161972379, 1672996084, 388959611, 2357870868, 4212429796, 1622269835,
13935 304431354, 2306870421, 4263435877, 1706791434, 287538053, 2324051946, 4246267162, 1723705717,
13936 811841520, 2881944479, 3696765295, 1207788800, 862293135, 2831204576, 3747484176, 1157324415,
13937 913293582, 2915732833, 3662962577, 1106318334, 896137841, 2932651550, 3646055662, 1123494017,
13938 1014716940, 2816349795, 3493905555, 1273334012, 1065181555, 2765630748, 3544645612, 1222882179,
13939 980888818, 2714919069, 3595350637, 1307180546, 963712909, 2731826146, 3578431762, 1324336509,
13940 676490248, 3019317351, 3295277719, 1607253752, 726947703, 2968591128, 3345992168, 1556776327,
13941 777919222, 3053147801, 3261432937, 1505806342, 760750473, 3070062054, 3244539670, 1522987897,
13942 608862708, 3220163995, 3362856811, 1406423812, 659339915, 3169449700, 3413582868, 1355966587,
13943 575076106, 3118709605, 3464325525, 1440228858, 557894773, 3135602714, 3447411434, 1457397381,
13944 1623683040, 4217512847, 2365387135, 391757072, 1673614495, 4167309552, 2415577600, 341804655,
13945 1724586270, 4251866481, 2331019137, 290835438, 1707942497, 4268256782, 2314648830, 307490961,
13946 1826587164, 4152020595, 2162433155, 457265388, 1876539747, 4101829900, 2212636668, 407333779,
13947 1792275682, 4051089549, 2263378557, 491595282, 1775619997, 4067460082, 2246988034, 508239213,
13948 2029433880, 3813931127, 2496473735, 258500328, 2079362919, 3763716872, 2546668024, 208559511,
13949 2130363110, 3848244873, 2462145657, 157552662, 2113730969, 3864638966, 2445764358, 174205801,
13950 1961777636, 4014675339, 2564147067, 57707284, 2011718299, 3964481268, 2614361092, 7778411,
13951 1927425818, 3913769845, 2665066885, 92077546, 1910772837, 3930150922, 2648673018, 108709525,
13952 1352980496, 3405878399, 3164554895, 658115296, 1403183983, 3355946752, 3214507504, 607924639,
13953 1453895406, 3440239233, 3130208369, 557218846, 1437504913, 3456883198, 3113552654, 573589345,
13954 1555838444, 3340335491, 2961681267, 723707676, 1606028947, 3290383100, 3011612684, 673504355,
13955 1521500946, 3239382909, 3062619533, 758026722, 1505130605, 3256038402, 3045975794, 774417053,
13956 1217725416, 3543158663, 2762906999, 1057739032, 1267939479, 3493229816, 2812847624, 1007544935,
13957 1318679830, 3577493881, 2728586121, 956803046, 1302285929, 3594125830, 2711933174, 973184153,
13958 1150152212, 3743982203, 2830528651, 856898788, 1200346475, 3694041348, 2880457716, 806684571,
13959 1115789546, 3643069573, 2931426933, 891243034, 1099408277, 3659722746, 2914794762, 907637093,
13960 }, {
13961 0, 3717650821, 1616688459, 3184159950, 3233376918, 489665299, 2699419613, 2104690264,
13962 1510200173, 2274691816, 979330598, 3888758691, 2595928571, 1194090622, 4209380528, 661706037,
13963 3020400346, 1771143007, 3562738577, 164481556, 1958661196, 2837976521, 350386439, 3379863682,
13964 3993269687, 865250354, 2388181244, 1406015865, 784146209, 4079732388, 1323412074, 2474079215,
13965 3011398645, 1860735600, 3542286014, 246687547, 1942430051, 2924607718, 328963112, 3456978349,
13966 3917322392, 887832861, 2300653011, 1421341782, 700772878, 4099025803, 1234716485, 2483986112,
13967 125431087, 3673109674, 1730500708, 3132326369, 3351283641, 441867836, 2812031730, 2047535991,
13968 1568292418, 2163009479, 1025936137, 3769651852, 2646824148, 1079348561, 4255113631, 537475098,
13969 3180171691, 1612400686, 3721471200, 4717925, 2100624189, 2694980280, 493375094, 3237910515,
13970 3884860102, 974691139, 2278750093, 1514417672, 657926224, 4204917205, 1198234907, 2600289438,
13971 160053105, 3558665972, 1775665722, 3024116671, 3375586791, 346391650, 2842683564, 1962488105,
13972 1401545756, 2384412057, 869618007, 3997403346, 2469432970, 1319524111, 4083956673, 788193860,
13973 250862174, 3546612699, 1856990997, 3006903952, 3461001416, 333211981, 2920678787, 1937824774,
13974 1425017139, 2305216694, 883735672, 3912918525, 2487837605, 1239398944, 4095071982, 696455019,
13975 3136584836, 1734518017, 3668494799, 121507914, 2051872274, 2816200599, 437363545, 3347544796,
13976 3774328809, 1029797484, 2158697122, 1564328743, 542033279, 4258798842, 1074950196, 2642717105,
13977 2691310871, 2113731730, 3224801372, 497043929, 1624461185, 3175454212, 9435850, 3709412175,
13978 4201248378, 671035391, 2587181873, 1201904308, 986750188, 3880142185, 1519135143, 2266689570,
13979 342721485, 3388693064, 1949382278, 2846355203, 3570723163, 155332830, 3028835344, 1763607957,
13980 1315852448, 2482538789, 775087595, 4087626862, 2396469814, 1396827059, 4002123645, 857560824,
13981 320106210, 3464673127, 1934154665, 2933785132, 3551331444, 238804465, 3018961215, 1852270778,
13982 1226292623, 2491507722, 692783300, 4108177729, 2309936921, 1412959900, 3924976210, 879016919,
13983 2803091512, 2055541181, 3343875443, 450471158, 1739236014, 3124525867, 133568485, 3663777376,
13984 4245691221, 545702608, 2639048222, 1088059291, 1034514883, 3762268230, 1576387720, 2153979149,
13985 501724348, 3228659001, 2109407735, 2687359090, 3713981994, 13109167, 3171052385, 1620357860,
13986 1206151121, 2591211092, 666423962, 4197321503, 2271022407, 1523307714, 3875649548, 982999433,
13987 2850034278, 1953942499, 3384583981, 338329256, 1767471344, 3033506165, 151375291, 3566408766,
13988 4091789579, 779425934, 2478797888, 1311354309, 861580189, 4006375960, 1392910038, 2391852883,
13989 2929327945, 1930372812, 3469036034, 324244359, 1847629279, 3015068762, 243015828, 3555391761,
13990 4103744548, 688715169, 2496043375, 1229996266, 874727090, 3920994103, 1417671673, 2313759356,
13991 446585235, 3339223062, 2059594968, 2807313757, 3660002053, 129100416, 3128657486, 1743609803,
13992 1084066558, 2634765179, 549535669, 4250396208, 2149900392, 1571961325, 3765982499, 1039043750,
13993 }, {
13994 0, 2635063670, 3782132909, 2086741467, 430739227, 2225303149, 4173482934, 1707977408,
13995 861478454, 2924937024, 3526875803, 1329085421, 720736557, 3086643291, 3415954816, 1452586230,
13996 1722956908, 4223524122, 2279405761, 450042295, 2132718455, 3792785921, 2658170842, 58693292,
13997 1441473114, 3370435372, 3028674295, 696911745, 1279765825, 3511176247, 2905172460, 807831706,
13998 3445913816, 1349228974, 738901109, 2969918723, 3569940419, 1237784245, 900084590, 2829701656,
13999 4265436910, 1664255896, 525574723, 2187084597, 3885099509, 2057177219, 117386584, 2616249390,
14000 2882946228, 920233410, 1253605401, 3619119471, 2994391983, 796207833, 1393823490, 3457937012,
14001 2559531650, 92322804, 2044829231, 3840835417, 2166609305, 472659183, 1615663412, 4249022530,
14002 1102706673, 3702920839, 2698457948, 1037619754, 1477802218, 3306854812, 3111894087, 611605809,
14003 1927342535, 4025419953, 2475568490, 243387420, 1800169180, 4131620778, 2317525617, 388842247,
14004 655084445, 3120835307, 3328511792, 1533734470, 1051149446, 2745738736, 3754524715, 1120297309,
14005 340972971, 2304586973, 4114354438, 1748234352, 234773168, 2431761350, 3968900637, 1906278251,
14006 2363330345, 299003487, 1840466820, 4038896370, 2507210802, 142532932, 1948239007, 3910149609,
14007 3213136159, 579563625, 1592415666, 3286611140, 2787646980, 992477042, 1195825833, 3662232543,
14008 3933188933, 2002801203, 184645608, 2517538462, 4089658462, 1858919720, 313391347, 2409765253,
14009 3644239219, 1144605701, 945318366, 2773977256, 3231326824, 1570095902, 569697989, 3170568115,
14010 2205413346, 511446676, 1646078799, 4279421497, 2598330617, 131105167, 2075239508, 3871229218,
14011 2955604436, 757403810, 1363424633, 3427521551, 2844163791, 881434553, 1223211618, 3588709140,
14012 3854685070, 2026779384, 78583587, 2577462869, 4235025557, 1633861091, 486774840, 2148301134,
14013 3600338360, 1268198606, 938871061, 2868504675, 3476308643, 1379640277, 777684494, 3008718712,
14014 1310168890, 3541595724, 2943964055, 846639841, 1471879201, 3400857943, 3067468940, 735723002,
14015 2102298892, 3762382970, 2619362721, 19901655, 1692534295, 4193118049, 2240594618, 411247564,
14016 681945942, 3047836192, 3385552891, 1422167693, 822682701, 2886124859, 3496468704, 1298661782,
14017 469546336, 2264093718, 4203901389, 1738379451, 38812283, 2673859341, 3812556502, 2117148576,
14018 3268024339, 1606809957, 598006974, 3198893512, 3680933640, 1181316734, 973624229, 2802299603,
14019 4052944421, 1822222163, 285065864, 2381456382, 3896478014, 1966106696, 156323219, 2489232613,
14020 2759337087, 964150537, 1159127250, 3625517476, 3184831332, 551242258, 1555722185, 3249901247,
14021 2535537225, 170842943, 1984954084, 3946848146, 2391651666, 327308324, 1877176831, 4075589769,
14022 263086283, 2460058045, 4005602406, 1942963472, 369291216, 2332888742, 4151061373, 1784924683,
14023 1022852861, 2717425547, 3717839440, 1083595558, 626782694, 3092517008, 3291821387, 1497027645,
14024 1763466407, 4094934481, 2289211402, 360544636, 1890636732, 3988730570, 2447251217, 215086695,
14025 1514488465, 3343557607, 3140191804, 639919946, 1139395978, 3739626748, 2726758695, 1065936977,
14026 }, {
14027 0, 3120290792, 2827399569, 293431929, 2323408227, 864534155, 586863858, 2600537882,
14028 3481914503, 1987188591, 1729068310, 3740575486, 1173727716, 4228805132, 3983743093, 1418249117,
14029 1147313999, 4254680231, 3974377182, 1428157750, 3458136620, 2011505092, 1721256893, 3747844181,
14030 2347455432, 839944224, 594403929, 2593536433, 26687147, 3094146371, 2836498234, 283794642,
14031 2294627998, 826205558, 541298447, 2578994407, 45702141, 3141697557, 2856315500, 331624836,
14032 1196225049, 4273416689, 4023010184, 1446090848, 3442513786, 1959480466, 1706436331, 3696098563,
14033 3433538001, 1968994873, 1679888448, 3722103720, 1188807858, 4280295258, 3999102243, 1470541515,
14034 53374294, 3134568126, 2879970503, 307431215, 2303854645, 816436189, 567589284, 2553242188,
14035 3405478781, 1929420949, 1652411116, 3682996484, 1082596894, 4185703926, 3892424591, 1375368295,
14036 91404282, 3163122706, 2918450795, 336584067, 2400113305, 922028401, 663249672, 2658384096,
14037 2392450098, 929185754, 639587747, 2682555979, 82149713, 3172883129, 2892181696, 362343208,
14038 1091578037, 4176212829, 3918960932, 1349337804, 3412872662, 1922537022, 1676344391, 3658557359,
14039 1111377379, 4224032267, 3937989746, 1396912026, 3359776896, 1908013928, 1623494929, 3644803833,
14040 2377615716, 877417100, 623982837, 2630542109, 130804743, 3190831087, 2941083030, 381060734,
14041 106748588, 3215393092, 2933549885, 388083925, 2350956495, 903570471, 614862430, 2640172470,
14042 3386185259, 1882115523, 1632872378, 3634920530, 1135178568, 4199721120, 3945775833, 1389631793,
14043 1317531835, 4152109907, 3858841898, 1610259138, 3304822232, 2097172016, 1820140617, 3582394273,
14044 2165193788, 955639764, 696815021, 2423477829, 192043359, 2995356343, 2750736590, 437203750,
14045 182808564, 3005133852, 2724453989, 462947725, 2157513367, 962777471, 673168134, 2447663342,
14046 3312231283, 2090301595, 1844056802, 3557935370, 1326499344, 4142603768, 3885397889, 1584245865,
14047 3326266917, 2142836173, 1858371508, 3611272284, 1279175494, 4123357358, 3837270743, 1564721471,
14048 164299426, 2955991370, 2706223923, 414607579, 2209834945, 978107433, 724686416, 2462715320,
14049 2183156074, 1004243586, 715579643, 2472360723, 140260361, 2980573153, 2698675608, 421617264,
14050 1302961645, 4099032581, 3845074044, 1557460884, 3352688782, 2116952934, 1867729183, 3601371895,
14051 2222754758, 1032278062, 754596439, 2499928511, 234942117, 3086693709, 2793824052, 528319708,
14052 1274365761, 4061043881, 3816027856, 1518873912, 3246989858, 2020800970, 1762628531, 3505670235,
14053 3223196809, 2045103969, 1754834200, 3512958704, 1247965674, 4086934018, 3806642299, 1528765331,
14054 261609486, 3060532198, 2802936223, 518697591, 2246819181, 1007707781, 762121468, 2492913428,
14055 213497176, 3041029808, 2755593417, 499441441, 2261110843, 1061030867, 776167850, 2545465922,
14056 3274734047, 2060165687, 1807140942, 3528266662, 1229724860, 4038575956, 3788156205, 1479636677,
14057 1222322711, 4045468159, 3764231046, 1504067694, 3265744756, 2069664924, 1780612837, 3554288909,
14058 2270357136, 1051278712, 802445057, 2519698665, 221152243, 3033880603, 2779263586, 475261322,
14059 }, {
14060 0, 2926088593, 2275419491, 701019378, 3560000647, 2052709654, 1402038756, 4261017717,
14061 1930665807, 3715829470, 4105419308, 1524313021, 2804077512, 155861593, 545453739, 2397726522,
14062 3861331614, 1213181711, 1636244477, 3488582252, 840331801, 2625561480, 3048626042, 467584747,
14063 2503254481, 995897408, 311723186, 3170637091, 1090907478, 4016929991, 3332753461, 1758288292,
14064 390036349, 3109546732, 2426363422, 1056427919, 3272488954, 1835443819, 1152258713, 3938878216,
14065 1680663602, 3393484195, 3817652561, 1306808512, 2954733749, 510998820, 935169494, 2580880455,
14066 4044899811, 1601229938, 1991794816, 3637571857, 623446372, 2336332021, 2726898695, 216120726,
14067 2181814956, 744704829, 95158223, 2881711710, 1446680107, 4166125498, 3516576584, 2146575065,
14068 780072698, 2148951915, 2849952665, 129384968, 4199529085, 1411853292, 2112855838, 3548843663,
14069 1567451573, 4077254692, 3670887638, 1957027143, 2304517426, 657765539, 251396177, 2694091200,
14070 3361327204, 1714510325, 1341779207, 3784408214, 476611811, 2986349938, 2613617024, 899690513,
14071 3142211371, 354600634, 1021997640, 2458051545, 1870338988, 3239283261, 3906682575, 1186180958,
14072 960597383, 2536053782, 3202459876, 277428597, 3983589632, 1125666961, 1792074851, 3300423154,
14073 1246892744, 3829039961, 3455203243, 1671079482, 2657312335, 806080478, 432241452, 3081497277,
14074 3748049689, 1896751752, 1489409658, 4138600427, 190316446, 2772397583, 2365053693, 580864876,
14075 2893360214, 35503559, 735381813, 2243795108, 2017747153, 3593269568, 4293150130, 1368183843,
14076 1560145396, 4069882981, 3680356503, 1966430470, 2295112051, 648294626, 258769936, 2701399425,
14077 804156091, 2173100842, 2823706584, 103204425, 4225711676, 1438101421, 2088704863, 3524758222,
14078 3134903146, 347226875, 1031468553, 2467456920, 1860935661, 3229814396, 3914054286, 1193487135,
14079 3385412645, 1738661300, 1315531078, 3758225623, 502792354, 3012596019, 2589468097, 875607120,
14080 1271043721, 3853125400, 3429020650, 1644831355, 2683558414, 832261023, 408158061, 3057348348,
14081 953223622, 2528745559, 3211865253, 286899508, 3974120769, 1116263632, 1799381026, 3307794867,
14082 2917509143, 59586950, 709201268, 2217549029, 2043995280, 3619452161, 4269064691, 1344032866,
14083 3740677976, 1889445577, 1498812987, 4148069290, 180845535, 2762992206, 2372361916, 588238637,
14084 1921194766, 3706423967, 4112727661, 1531686908, 2796705673, 148555288, 554857194, 2407195515,
14085 26248257, 2952271312, 2251333922, 676868275, 3584149702, 2076793175, 1375858085, 4234771508,
14086 2493785488, 986493953, 319029491, 3178008930, 1083533591, 4009621638, 3342158964, 1767759333,
14087 3887577823, 1239362382, 1612160956, 3464433197, 864482904, 2649647049, 3022443323, 441336490,
14088 1706844275, 3419730402, 3793503504, 1282724993, 2978819316, 535149925, 908921239, 2554697734,
14089 380632892, 3100077741, 2433735263, 1063734222, 3265180603, 1828069930, 1161729752, 3948283721,
14090 2207997677, 770953084, 71007118, 2857626143, 1470763626, 4190274555, 3490330377, 2120394392,
14091 4035494306, 1591758899, 1999168705, 3644880208, 616140069, 2328960180, 2736367686, 225524183,
14092 },
14093};
14094
14095// ---------------- Private Initializer Prototypes
14096
14097// ---------------- Private Function Prototypes
14098
14099// ---------------- VTables
14100
14101const wuffs_base__hasher_u32__func_ptrs
14102wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
14103 (wuffs_base__empty_struct(*)(void*,
14104 uint32_t,
14105 bool))(&wuffs_crc32__ieee_hasher__set_quirk_enabled),
14106 (uint32_t(*)(void*,
14107 wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32),
14108};
14109
14110// ---------------- Initializer Implementations
14111
14112wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14113wuffs_crc32__ieee_hasher__initialize(
14114 wuffs_crc32__ieee_hasher* self,
14115 size_t sizeof_star_self,
14116 uint64_t wuffs_version,
14117 uint32_t initialize_flags){
14118 if (!self) {
14119 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14120 }
14121 if (sizeof(*self) != sizeof_star_self) {
14122 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
14123 }
14124 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
14125 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
14126 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
14127 }
14128
14129 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
14130 // The whole point of this if-check is to detect an uninitialized *self.
14131 // We disable the warning on GCC. Clang-5.0 does not have this warning.
14132#if !defined(__clang__) && defined(__GNUC__)
14133#pragma GCC diagnostic push
14134#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
14135#endif
14136 if (self->private_impl.magic != 0) {
14137 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
14138 }
14139#if !defined(__clang__) && defined(__GNUC__)
14140#pragma GCC diagnostic pop
14141#endif
14142 } else {
14143 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
14144 memset(self, 0, sizeof(*self));
14145 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
14146 } else {
14147 memset(&(self->private_impl), 0, sizeof(self->private_impl));
14148 }
14149 }
14150
14151 self->private_impl.magic = WUFFS_BASE__MAGIC;
14152 self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
14153 wuffs_base__hasher_u32__vtable_name;
14154 self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
14155 (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32);
14156 return wuffs_base__make_status(NULL);
14157}
14158
14159wuffs_crc32__ieee_hasher*
14160wuffs_crc32__ieee_hasher__alloc() {
14161 wuffs_crc32__ieee_hasher* x =
14162 (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
14163 if (!x) {
14164 return NULL;
14165 }
14166 if (wuffs_crc32__ieee_hasher__initialize(
14167 x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
14168 free(x);
14169 return NULL;
14170 }
14171 return x;
14172}
14173
14174size_t
14175sizeof__wuffs_crc32__ieee_hasher() {
14176 return sizeof(wuffs_crc32__ieee_hasher);
14177}
14178
14179// ---------------- Function Implementations
14180
14181// -------- func crc32.ieee_hasher.set_quirk_enabled
14182
14183WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
14184wuffs_crc32__ieee_hasher__set_quirk_enabled(
14185 wuffs_crc32__ieee_hasher* self,
14186 uint32_t a_quirk,
14187 bool a_enabled) {
14188 return wuffs_base__make_empty_struct();
14189}
14190
14191// -------- func crc32.ieee_hasher.update_u32
14192
14193WUFFS_BASE__MAYBE_STATIC uint32_t
14194wuffs_crc32__ieee_hasher__update_u32(
14195 wuffs_crc32__ieee_hasher* self,
14196 wuffs_base__slice_u8 a_x) {
14197 if (!self) {
14198 return 0;
14199 }
14200 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14201 return 0;
14202 }
14203
14204 uint32_t v_s = 0;
14205 wuffs_base__slice_u8 v_p = {0};
14206
14207 v_s = (4294967295 ^ self->private_impl.f_state);
14208 {
14209 wuffs_base__slice_u8 i_slice_p = a_x;
14210 v_p = i_slice_p;
14211 v_p.len = 16;
14212 uint8_t* i_end0_p = i_slice_p.ptr + (i_slice_p.len / 32) * 32;
14213 while (v_p.ptr < i_end0_p) {
14214 v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
14215 (((uint32_t)(v_p.ptr[1])) << 8) |
14216 (((uint32_t)(v_p.ptr[2])) << 16) |
14217 (((uint32_t)(v_p.ptr[3])) << 24));
14218 v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
14219 WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
14220 WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
14221 WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
14222 WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
14223 WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
14224 WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
14225 WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
14226 WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
14227 WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
14228 WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
14229 WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
14230 WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
14231 WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
14232 WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
14233 WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
14234 v_p.ptr += 16;
14235 v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
14236 (((uint32_t)(v_p.ptr[1])) << 8) |
14237 (((uint32_t)(v_p.ptr[2])) << 16) |
14238 (((uint32_t)(v_p.ptr[3])) << 24));
14239 v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
14240 WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
14241 WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
14242 WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
14243 WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
14244 WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
14245 WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
14246 WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
14247 WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
14248 WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
14249 WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
14250 WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
14251 WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
14252 WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
14253 WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
14254 WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
14255 v_p.ptr += 16;
14256 }
14257 v_p.len = 16;
14258 uint8_t* i_end1_p = i_slice_p.ptr + (i_slice_p.len / 16) * 16;
14259 while (v_p.ptr < i_end1_p) {
14260 v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
14261 (((uint32_t)(v_p.ptr[1])) << 8) |
14262 (((uint32_t)(v_p.ptr[2])) << 16) |
14263 (((uint32_t)(v_p.ptr[3])) << 24));
14264 v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
14265 WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
14266 WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
14267 WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
14268 WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
14269 WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
14270 WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
14271 WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
14272 WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
14273 WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
14274 WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
14275 WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
14276 WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
14277 WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
14278 WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
14279 WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
14280 v_p.ptr += 16;
14281 }
14282 v_p.len = 1;
14283 uint8_t* i_end2_p = i_slice_p.ptr + (i_slice_p.len / 1) * 1;
14284 while (v_p.ptr < i_end2_p) {
14285 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
14286 v_p.ptr += 1;
14287 }
14288 }
14289 self->private_impl.f_state = (4294967295 ^ v_s);
14290 return self->private_impl.f_state;
14291}
14292
14293#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
14294
14295#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
14296
14297// ---------------- Status Codes Implementations
14298
14299const char* wuffs_deflate__error__bad_huffman_code_over_subscribed = "#deflate: bad Huffman code (over-subscribed)";
14300const char* wuffs_deflate__error__bad_huffman_code_under_subscribed = "#deflate: bad Huffman code (under-subscribed)";
14301const char* wuffs_deflate__error__bad_huffman_code_length_count = "#deflate: bad Huffman code length count";
14302const char* wuffs_deflate__error__bad_huffman_code_length_repetition = "#deflate: bad Huffman code length repetition";
14303const char* wuffs_deflate__error__bad_huffman_code = "#deflate: bad Huffman code";
14304const char* wuffs_deflate__error__bad_huffman_minimum_code_length = "#deflate: bad Huffman minimum code length";
14305const char* wuffs_deflate__error__bad_block = "#deflate: bad block";
14306const char* wuffs_deflate__error__bad_distance = "#deflate: bad distance";
14307const char* wuffs_deflate__error__bad_distance_code_count = "#deflate: bad distance code count";
14308const char* wuffs_deflate__error__bad_literal_length_code_count = "#deflate: bad literal/length code count";
14309const char* wuffs_deflate__error__inconsistent_stored_block_length = "#deflate: inconsistent stored block length";
14310const char* wuffs_deflate__error__missing_end_of_block_code = "#deflate: missing end-of-block code";
14311const char* wuffs_deflate__error__no_huffman_codes = "#deflate: no Huffman codes";
14312const char* wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state = "#deflate: internal error: inconsistent Huffman decoder state";
14313const char* wuffs_deflate__error__internal_error_inconsistent_i_o = "#deflate: internal error: inconsistent I/O";
14314const char* wuffs_deflate__error__internal_error_inconsistent_distance = "#deflate: internal error: inconsistent distance";
14315const char* wuffs_deflate__error__internal_error_inconsistent_n_bits = "#deflate: internal error: inconsistent n_bits";
14316
14317// ---------------- Private Consts
14318
14319static const uint8_t
14320WUFFS_DEFLATE__CODE_ORDER[19]WUFFS_BASE__POTENTIALLY_UNUSED = {
14321 16, 17, 18, 0, 8, 7, 9, 6,
14322 10, 5, 11, 4, 12, 3, 13, 2,
14323 14, 1, 15,
14324};
14325
14326static const uint8_t
14327WUFFS_DEFLATE__REVERSE8[256]WUFFS_BASE__POTENTIALLY_UNUSED = {
14328 0, 128, 64, 192, 32, 160, 96, 224,
14329 16, 144, 80, 208, 48, 176, 112, 240,
14330 8, 136, 72, 200, 40, 168, 104, 232,
14331 24, 152, 88, 216, 56, 184, 120, 248,
14332 4, 132, 68, 196, 36, 164, 100, 228,
14333 20, 148, 84, 212, 52, 180, 116, 244,
14334 12, 140, 76, 204, 44, 172, 108, 236,
14335 28, 156, 92, 220, 60, 188, 124, 252,
14336 2, 130, 66, 194, 34, 162, 98, 226,
14337 18, 146, 82, 210, 50, 178, 114, 242,
14338 10, 138, 74, 202, 42, 170, 106, 234,
14339 26, 154, 90, 218, 58, 186, 122, 250,
14340 6, 134, 70, 198, 38, 166, 102, 230,
14341 22, 150, 86, 214, 54, 182, 118, 246,
14342 14, 142, 78, 206, 46, 174, 110, 238,
14343 30, 158, 94, 222, 62, 190, 126, 254,
14344 1, 129, 65, 193, 33, 161, 97, 225,
14345 17, 145, 81, 209, 49, 177, 113, 241,
14346 9, 137, 73, 201, 41, 169, 105, 233,
14347 25, 153, 89, 217, 57, 185, 121, 249,
14348 5, 133, 69, 197, 37, 165, 101, 229,
14349 21, 149, 85, 213, 53, 181, 117, 245,
14350 13, 141, 77, 205, 45, 173, 109, 237,
14351 29, 157, 93, 221, 61, 189, 125, 253,
14352 3, 131, 67, 195, 35, 163, 99, 227,
14353 19, 147, 83, 211, 51, 179, 115, 243,
14354 11, 139, 75, 203, 43, 171, 107, 235,
14355 27, 155, 91, 219, 59, 187, 123, 251,
14356 7, 135, 71, 199, 39, 167, 103, 231,
14357 23, 151, 87, 215, 55, 183, 119, 247,
14358 15, 143, 79, 207, 47, 175, 111, 239,
14359 31, 159, 95, 223, 63, 191, 127, 255,
14360};
14361
14362static const uint32_t
14363WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32]WUFFS_BASE__POTENTIALLY_UNUSED = {
14364 1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104, 1073743360, 1073743616,
14365 1073743888, 1073744400, 1073744912, 1073745424, 1073745952, 1073746976, 1073748000, 1073749024,
14366 1073750064, 1073752112, 1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560,
14367 1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728, 134217728, 134217728,
14368};
14369
14370static const uint32_t
14371WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32]WUFFS_BASE__POTENTIALLY_UNUSED = {
14372 1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376, 1073743904, 1073744928,
14373 1073745968, 1073748016, 1073750080, 1073754176, 1073758288, 1073766480, 1073774688, 1073791072,
14374 1073807472, 1073840240, 1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416,
14375 1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488, 134217728, 134217728,
14376};
14377
14378#define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024
14379
14380#define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023
14381
14382// ---------------- Private Initializer Prototypes
14383
14384// ---------------- Private Function Prototypes
14385
14386static wuffs_base__status
14387wuffs_deflate__decoder__decode_blocks(
14388 wuffs_deflate__decoder* self,
14389 wuffs_base__io_buffer* a_dst,
14390 wuffs_base__io_buffer* a_src);
14391
14392static wuffs_base__status
14393wuffs_deflate__decoder__decode_uncompressed(
14394 wuffs_deflate__decoder* self,
14395 wuffs_base__io_buffer* a_dst,
14396 wuffs_base__io_buffer* a_src);
14397
14398static wuffs_base__status
14399wuffs_deflate__decoder__init_fixed_huffman(
14400 wuffs_deflate__decoder* self);
14401
14402static wuffs_base__status
14403wuffs_deflate__decoder__init_dynamic_huffman(
14404 wuffs_deflate__decoder* self,
14405 wuffs_base__io_buffer* a_src);
14406
14407static wuffs_base__status
14408wuffs_deflate__decoder__init_huff(
14409 wuffs_deflate__decoder* self,
14410 uint32_t a_which,
14411 uint32_t a_n_codes0,
14412 uint32_t a_n_codes1,
14413 uint32_t a_base_symbol);
14414
14415static wuffs_base__status
14416wuffs_deflate__decoder__decode_huffman_fast(
14417 wuffs_deflate__decoder* self,
14418 wuffs_base__io_buffer* a_dst,
14419 wuffs_base__io_buffer* a_src);
14420
14421static wuffs_base__status
14422wuffs_deflate__decoder__decode_huffman_slow(
14423 wuffs_deflate__decoder* self,
14424 wuffs_base__io_buffer* a_dst,
14425 wuffs_base__io_buffer* a_src);
14426
14427// ---------------- VTables
14428
14429const wuffs_base__io_transformer__func_ptrs
14430wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = {
14431 (wuffs_base__empty_struct(*)(void*,
14432 uint32_t,
14433 bool))(&wuffs_deflate__decoder__set_quirk_enabled),
14434 (wuffs_base__status(*)(void*,
14435 wuffs_base__io_buffer*,
14436 wuffs_base__io_buffer*,
14437 wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io),
14438 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len),
14439};
14440
14441// ---------------- Initializer Implementations
14442
14443wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
14444wuffs_deflate__decoder__initialize(
14445 wuffs_deflate__decoder* self,
14446 size_t sizeof_star_self,
14447 uint64_t wuffs_version,
14448 uint32_t initialize_flags){
14449 if (!self) {
14450 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14451 }
14452 if (sizeof(*self) != sizeof_star_self) {
14453 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
14454 }
14455 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
14456 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
14457 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
14458 }
14459
14460 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
14461 // The whole point of this if-check is to detect an uninitialized *self.
14462 // We disable the warning on GCC. Clang-5.0 does not have this warning.
14463#if !defined(__clang__) && defined(__GNUC__)
14464#pragma GCC diagnostic push
14465#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
14466#endif
14467 if (self->private_impl.magic != 0) {
14468 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
14469 }
14470#if !defined(__clang__) && defined(__GNUC__)
14471#pragma GCC diagnostic pop
14472#endif
14473 } else {
14474 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
14475 memset(self, 0, sizeof(*self));
14476 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
14477 } else {
14478 memset(&(self->private_impl), 0, sizeof(self->private_impl));
14479 }
14480 }
14481
14482 self->private_impl.magic = WUFFS_BASE__MAGIC;
14483 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
14484 wuffs_base__io_transformer__vtable_name;
14485 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
14486 (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer);
14487 return wuffs_base__make_status(NULL);
14488}
14489
14490wuffs_deflate__decoder*
14491wuffs_deflate__decoder__alloc() {
14492 wuffs_deflate__decoder* x =
14493 (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
14494 if (!x) {
14495 return NULL;
14496 }
14497 if (wuffs_deflate__decoder__initialize(
14498 x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
14499 free(x);
14500 return NULL;
14501 }
14502 return x;
14503}
14504
14505size_t
14506sizeof__wuffs_deflate__decoder() {
14507 return sizeof(wuffs_deflate__decoder);
14508}
14509
14510// ---------------- Function Implementations
14511
14512// -------- func deflate.decoder.add_history
14513
14514WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
14515wuffs_deflate__decoder__add_history(
14516 wuffs_deflate__decoder* self,
14517 wuffs_base__slice_u8 a_hist) {
14518 if (!self) {
14519 return wuffs_base__make_empty_struct();
14520 }
14521 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14522 return wuffs_base__make_empty_struct();
14523 }
14524
14525 wuffs_base__slice_u8 v_s = {0};
14526 uint64_t v_n_copied = 0;
14527 uint32_t v_already_full = 0;
14528
14529 v_s = a_hist;
14530 if (((uint64_t)(v_s.len)) >= 32768) {
14531 v_s = wuffs_base__slice_u8__suffix(v_s, 32768);
14532 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), 32768), v_s);
14533 self->private_impl.f_history_index = 32768;
14534 } else {
14535 v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), (self->private_impl.f_history_index & 32767), 32768), v_s);
14536 if (v_n_copied < ((uint64_t)(v_s.len))) {
14537 v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied);
14538 v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), 32768), v_s);
14539 self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767))) + 32768);
14540 } else {
14541 v_already_full = 0;
14542 if (self->private_impl.f_history_index >= 32768) {
14543 v_already_full = 32768;
14544 }
14545 self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767) + ((uint32_t)((v_n_copied & 32767))) + v_already_full);
14546 }
14547 }
14548 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), 32768), wuffs_base__make_slice_u8(self->private_data.f_history, 33025));
14549 return wuffs_base__make_empty_struct();
14550}
14551
14552// -------- func deflate.decoder.set_quirk_enabled
14553
14554WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
14555wuffs_deflate__decoder__set_quirk_enabled(
14556 wuffs_deflate__decoder* self,
14557 uint32_t a_quirk,
14558 bool a_enabled) {
14559 return wuffs_base__make_empty_struct();
14560}
14561
14562// -------- func deflate.decoder.workbuf_len
14563
14564WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
14565wuffs_deflate__decoder__workbuf_len(
14566 const wuffs_deflate__decoder* self) {
14567 if (!self) {
14568 return wuffs_base__utility__empty_range_ii_u64();
14569 }
14570 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
14571 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
14572 return wuffs_base__utility__empty_range_ii_u64();
14573 }
14574
14575 return wuffs_base__utility__make_range_ii_u64(1, 1);
14576}
14577
14578// -------- func deflate.decoder.transform_io
14579
14580WUFFS_BASE__MAYBE_STATIC wuffs_base__status
14581wuffs_deflate__decoder__transform_io(
14582 wuffs_deflate__decoder* self,
14583 wuffs_base__io_buffer* a_dst,
14584 wuffs_base__io_buffer* a_src,
14585 wuffs_base__slice_u8 a_workbuf) {
14586 if (!self) {
14587 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
14588 }
14589 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
14590 return wuffs_base__make_status(
14591 (self->private_impl.magic == WUFFS_BASE__DISABLED)
14592 ? wuffs_base__error__disabled_by_previous_error
14593 : wuffs_base__error__initialize_not_called);
14594 }
14595 if (!a_dst || !a_src) {
14596 self->private_impl.magic = WUFFS_BASE__DISABLED;
14597 return wuffs_base__make_status(wuffs_base__error__bad_argument);
14598 }
14599 if ((self->private_impl.active_coroutine != 0) &&
14600 (self->private_impl.active_coroutine != 1)) {
14601 self->private_impl.magic = WUFFS_BASE__DISABLED;
14602 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
14603 }
14604 self->private_impl.active_coroutine = 0;
14605 wuffs_base__status status = wuffs_base__make_status(NULL);
14606
14607 uint64_t v_mark = 0;
14608 wuffs_base__status v_status = wuffs_base__make_status(NULL);
14609
14610 uint8_t* iop_a_dst = NULL;
14611 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14612 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14613 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14614 if (a_dst) {
14615 io0_a_dst = a_dst->data.ptr;
14616 io1_a_dst = io0_a_dst + a_dst->meta.wi;
14617 iop_a_dst = io1_a_dst;
14618 io2_a_dst = io0_a_dst + a_dst->data.len;
14619 if (a_dst->meta.closed) {
14620 io2_a_dst = iop_a_dst;
14621 }
14622 }
14623
14624 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
14625 switch (coro_susp_point) {
14626 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
14627
14628 while (true) {
14629 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
14630 {
14631 if (a_dst) {
14632 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
14633 }
14634 wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
14635 if (a_dst) {
14636 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
14637 }
14638 v_status = t_0;
14639 }
14640 if ( ! wuffs_base__status__is_suspension(&v_status)) {
14641 status = v_status;
14642 if (wuffs_base__status__is_error(&status)) {
14643 goto exit;
14644 } else if (wuffs_base__status__is_suspension(&status)) {
14645 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
14646 goto exit;
14647 }
14648 goto ok;
14649 }
14650 wuffs_deflate__decoder__add_history(self, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
14651 status = v_status;
14652 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
14653 }
14654
14655 goto ok;
14656 ok:
14657 self->private_impl.p_transform_io[0] = 0;
14658 goto exit;
14659 }
14660
14661 goto suspend;
14662 suspend:
14663 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
14664 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
14665
14666 goto exit;
14667 exit:
14668 if (a_dst) {
14669 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
14670 }
14671
14672 if (wuffs_base__status__is_error(&status)) {
14673 self->private_impl.magic = WUFFS_BASE__DISABLED;
14674 }
14675 return status;
14676}
14677
14678// -------- func deflate.decoder.decode_blocks
14679
14680static wuffs_base__status
14681wuffs_deflate__decoder__decode_blocks(
14682 wuffs_deflate__decoder* self,
14683 wuffs_base__io_buffer* a_dst,
14684 wuffs_base__io_buffer* a_src) {
14685 wuffs_base__status status = wuffs_base__make_status(NULL);
14686
14687 uint32_t v_final = 0;
14688 uint32_t v_b0 = 0;
14689 uint32_t v_type = 0;
14690 wuffs_base__status v_status = wuffs_base__make_status(NULL);
14691
14692 const uint8_t* iop_a_src = NULL;
14693 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14694 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14695 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14696 if (a_src) {
14697 io0_a_src = a_src->data.ptr;
14698 io1_a_src = io0_a_src + a_src->meta.ri;
14699 iop_a_src = io1_a_src;
14700 io2_a_src = io0_a_src + a_src->meta.wi;
14701 }
14702
14703 uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0];
14704 if (coro_susp_point) {
14705 v_final = self->private_data.s_decode_blocks[0].v_final;
14706 }
14707 switch (coro_susp_point) {
14708 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
14709
14710 label__outer__continue:;
14711 while (v_final == 0) {
14712 while (self->private_impl.f_n_bits < 3) {
14713 {
14714 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
14715 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
14716 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
14717 goto suspend;
14718 }
14719 uint32_t t_0 = *iop_a_src++;
14720 v_b0 = t_0;
14721 }
14722 self->private_impl.f_bits |= (v_b0 << self->private_impl.f_n_bits);
14723 self->private_impl.f_n_bits += 8;
14724 }
14725 v_final = (self->private_impl.f_bits & 1);
14726 v_type = ((self->private_impl.f_bits >> 1) & 3);
14727 self->private_impl.f_bits >>= 3;
14728 self->private_impl.f_n_bits -= 3;
14729 if (v_type == 0) {
14730 if (a_src) {
14731 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
14732 }
14733 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
14734 status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
14735 if (a_src) {
14736 iop_a_src = a_src->data.ptr + a_src->meta.ri;
14737 }
14738 if (status.repr) {
14739 goto suspend;
14740 }
14741 goto label__outer__continue;
14742 } else if (v_type == 1) {
14743 v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
14744 if ( ! wuffs_base__status__is_ok(&v_status)) {
14745 status = v_status;
14746 if (wuffs_base__status__is_error(&status)) {
14747 goto exit;
14748 } else if (wuffs_base__status__is_suspension(&status)) {
14749 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
14750 goto exit;
14751 }
14752 goto ok;
14753 }
14754 } else if (v_type == 2) {
14755 if (a_src) {
14756 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
14757 }
14758 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
14759 status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
14760 if (a_src) {
14761 iop_a_src = a_src->data.ptr + a_src->meta.ri;
14762 }
14763 if (status.repr) {
14764 goto suspend;
14765 }
14766 } else {
14767 status = wuffs_base__make_status(wuffs_deflate__error__bad_block);
14768 goto exit;
14769 }
14770 self->private_impl.f_end_of_block = false;
14771 while (true) {
14772 if (a_src) {
14773 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
14774 }
14775 v_status = wuffs_deflate__decoder__decode_huffman_fast(self, a_dst, a_src);
14776 if (a_src) {
14777 iop_a_src = a_src->data.ptr + a_src->meta.ri;
14778 }
14779 if (wuffs_base__status__is_error(&v_status)) {
14780 status = v_status;
14781 goto exit;
14782 }
14783 if (self->private_impl.f_end_of_block) {
14784 goto label__outer__continue;
14785 }
14786 if (a_src) {
14787 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
14788 }
14789 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
14790 status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
14791 if (a_src) {
14792 iop_a_src = a_src->data.ptr + a_src->meta.ri;
14793 }
14794 if (status.repr) {
14795 goto suspend;
14796 }
14797 if (self->private_impl.f_end_of_block) {
14798 goto label__outer__continue;
14799 }
14800 }
14801 }
14802
14803 goto ok;
14804 ok:
14805 self->private_impl.p_decode_blocks[0] = 0;
14806 goto exit;
14807 }
14808
14809 goto suspend;
14810 suspend:
14811 self->private_impl.p_decode_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
14812 self->private_data.s_decode_blocks[0].v_final = v_final;
14813
14814 goto exit;
14815 exit:
14816 if (a_src) {
14817 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
14818 }
14819
14820 return status;
14821}
14822
14823// -------- func deflate.decoder.decode_uncompressed
14824
14825static wuffs_base__status
14826wuffs_deflate__decoder__decode_uncompressed(
14827 wuffs_deflate__decoder* self,
14828 wuffs_base__io_buffer* a_dst,
14829 wuffs_base__io_buffer* a_src) {
14830 wuffs_base__status status = wuffs_base__make_status(NULL);
14831
14832 uint32_t v_length = 0;
14833 uint32_t v_n_copied = 0;
14834
14835 uint8_t* iop_a_dst = NULL;
14836 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14837 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14838 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14839 if (a_dst) {
14840 io0_a_dst = a_dst->data.ptr;
14841 io1_a_dst = io0_a_dst + a_dst->meta.wi;
14842 iop_a_dst = io1_a_dst;
14843 io2_a_dst = io0_a_dst + a_dst->data.len;
14844 if (a_dst->meta.closed) {
14845 io2_a_dst = iop_a_dst;
14846 }
14847 }
14848 const uint8_t* iop_a_src = NULL;
14849 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14850 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14851 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
14852 if (a_src) {
14853 io0_a_src = a_src->data.ptr;
14854 io1_a_src = io0_a_src + a_src->meta.ri;
14855 iop_a_src = io1_a_src;
14856 io2_a_src = io0_a_src + a_src->meta.wi;
14857 }
14858
14859 uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0];
14860 if (coro_susp_point) {
14861 v_length = self->private_data.s_decode_uncompressed[0].v_length;
14862 }
14863 switch (coro_susp_point) {
14864 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
14865
14866 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
14867 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
14868 goto exit;
14869 }
14870 self->private_impl.f_n_bits = 0;
14871 self->private_impl.f_bits = 0;
14872 {
14873 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
14874 uint32_t t_0;
14875 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
14876 t_0 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
14877 iop_a_src += 4;
14878 } else {
14879 self->private_data.s_decode_uncompressed[0].scratch = 0;
14880 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
14881 while (true) {
14882 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
14883 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
14884 goto suspend;
14885 }
14886 uint64_t* scratch = &self->private_data.s_decode_uncompressed[0].scratch;
14887 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
14888 *scratch <<= 8;
14889 *scratch >>= 8;
14890 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
14891 if (num_bits_0 == 24) {
14892 t_0 = ((uint32_t)(*scratch));
14893 break;
14894 }
14895 num_bits_0 += 8;
14896 *scratch |= ((uint64_t)(num_bits_0)) << 56;
14897 }
14898 }
14899 v_length = t_0;
14900 }
14901 if ((((v_length) & 0xFFFF) + ((v_length) >> (32 - (16)))) != 65535) {
14902 status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length);
14903 goto exit;
14904 }
14905 v_length = ((v_length) & 0xFFFF);
14906 while (true) {
14907 v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_reader(
14908 &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
14909 if (v_length <= v_n_copied) {
14910 status = wuffs_base__make_status(NULL);
14911 goto ok;
14912 }
14913 v_length -= v_n_copied;
14914 if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0) {
14915 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
14916 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
14917 } else {
14918 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
14919 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
14920 }
14921 }
14922
14923 goto ok;
14924 ok:
14925 self->private_impl.p_decode_uncompressed[0] = 0;
14926 goto exit;
14927 }
14928
14929 goto suspend;
14930 suspend:
14931 self->private_impl.p_decode_uncompressed[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
14932 self->private_data.s_decode_uncompressed[0].v_length = v_length;
14933
14934 goto exit;
14935 exit:
14936 if (a_dst) {
14937 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
14938 }
14939 if (a_src) {
14940 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
14941 }
14942
14943 return status;
14944}
14945
14946// -------- func deflate.decoder.init_fixed_huffman
14947
14948static wuffs_base__status
14949wuffs_deflate__decoder__init_fixed_huffman(
14950 wuffs_deflate__decoder* self) {
14951 uint32_t v_i = 0;
14952 wuffs_base__status v_status = wuffs_base__make_status(NULL);
14953
14954 while (v_i < 144) {
14955 self->private_data.f_code_lengths[v_i] = 8;
14956 v_i += 1;
14957 }
14958 while (v_i < 256) {
14959 self->private_data.f_code_lengths[v_i] = 9;
14960 v_i += 1;
14961 }
14962 while (v_i < 280) {
14963 self->private_data.f_code_lengths[v_i] = 7;
14964 v_i += 1;
14965 }
14966 while (v_i < 288) {
14967 self->private_data.f_code_lengths[v_i] = 8;
14968 v_i += 1;
14969 }
14970 while (v_i < 320) {
14971 self->private_data.f_code_lengths[v_i] = 5;
14972 v_i += 1;
14973 }
14974 v_status = wuffs_deflate__decoder__init_huff(self,
14975 0,
14976 0,
14977 288,
14978 257);
14979 if (wuffs_base__status__is_error(&v_status)) {
14980 return v_status;
14981 }
14982 v_status = wuffs_deflate__decoder__init_huff(self,
14983 1,
14984 288,
14985 320,
14986 0);
14987 if (wuffs_base__status__is_error(&v_status)) {
14988 return v_status;
14989 }
14990 return wuffs_base__make_status(NULL);
14991}
14992
14993// -------- func deflate.decoder.init_dynamic_huffman
14994
14995static wuffs_base__status
14996wuffs_deflate__decoder__init_dynamic_huffman(
14997 wuffs_deflate__decoder* self,
14998 wuffs_base__io_buffer* a_src) {
14999 wuffs_base__status status = wuffs_base__make_status(NULL);
15000
15001 uint32_t v_bits = 0;
15002 uint32_t v_n_bits = 0;
15003 uint32_t v_b0 = 0;
15004 uint32_t v_n_lit = 0;
15005 uint32_t v_n_dist = 0;
15006 uint32_t v_n_clen = 0;
15007 uint32_t v_i = 0;
15008 uint32_t v_b1 = 0;
15009 wuffs_base__status v_status = wuffs_base__make_status(NULL);
15010 uint32_t v_mask = 0;
15011 uint32_t v_table_entry = 0;
15012 uint32_t v_table_entry_n_bits = 0;
15013 uint32_t v_b2 = 0;
15014 uint32_t v_n_extra_bits = 0;
15015 uint8_t v_rep_symbol = 0;
15016 uint32_t v_rep_count = 0;
15017 uint32_t v_b3 = 0;
15018
15019 const uint8_t* iop_a_src = NULL;
15020 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15021 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15022 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15023 if (a_src) {
15024 io0_a_src = a_src->data.ptr;
15025 io1_a_src = io0_a_src + a_src->meta.ri;
15026 iop_a_src = io1_a_src;
15027 io2_a_src = io0_a_src + a_src->meta.wi;
15028 }
15029
15030 uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0];
15031 if (coro_susp_point) {
15032 v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits;
15033 v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits;
15034 v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit;
15035 v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist;
15036 v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen;
15037 v_i = self->private_data.s_init_dynamic_huffman[0].v_i;
15038 v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask;
15039 v_table_entry = self->private_data.s_init_dynamic_huffman[0].v_table_entry;
15040 v_n_extra_bits = self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits;
15041 v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol;
15042 v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count;
15043 }
15044 switch (coro_susp_point) {
15045 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
15046
15047 v_bits = self->private_impl.f_bits;
15048 v_n_bits = self->private_impl.f_n_bits;
15049 while (v_n_bits < 14) {
15050 {
15051 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
15052 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15053 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15054 goto suspend;
15055 }
15056 uint32_t t_0 = *iop_a_src++;
15057 v_b0 = t_0;
15058 }
15059 v_bits |= (v_b0 << v_n_bits);
15060 v_n_bits += 8;
15061 }
15062 v_n_lit = (((v_bits) & 0x1F) + 257);
15063 if (v_n_lit > 286) {
15064 status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count);
15065 goto exit;
15066 }
15067 v_bits >>= 5;
15068 v_n_dist = (((v_bits) & 0x1F) + 1);
15069 if (v_n_dist > 30) {
15070 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count);
15071 goto exit;
15072 }
15073 v_bits >>= 5;
15074 v_n_clen = (((v_bits) & 0xF) + 4);
15075 v_bits >>= 4;
15076 v_n_bits -= 14;
15077 v_i = 0;
15078 while (v_i < v_n_clen) {
15079 while (v_n_bits < 3) {
15080 {
15081 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
15082 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15083 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15084 goto suspend;
15085 }
15086 uint32_t t_1 = *iop_a_src++;
15087 v_b1 = t_1;
15088 }
15089 v_bits |= (v_b1 << v_n_bits);
15090 v_n_bits += 8;
15091 }
15092 self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7)));
15093 v_bits >>= 3;
15094 v_n_bits -= 3;
15095 v_i += 1;
15096 }
15097 while (v_i < 19) {
15098 self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0;
15099 v_i += 1;
15100 }
15101 v_status = wuffs_deflate__decoder__init_huff(self,
15102 0,
15103 0,
15104 19,
15105 4095);
15106 if (wuffs_base__status__is_error(&v_status)) {
15107 status = v_status;
15108 goto exit;
15109 }
15110 v_mask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
15111 v_i = 0;
15112 label__0__continue:;
15113 while (v_i < (v_n_lit + v_n_dist)) {
15114 while (true) {
15115 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_mask)];
15116 v_table_entry_n_bits = (v_table_entry & 15);
15117 if (v_n_bits >= v_table_entry_n_bits) {
15118 v_bits >>= v_table_entry_n_bits;
15119 v_n_bits -= v_table_entry_n_bits;
15120 goto label__1__break;
15121 }
15122 {
15123 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
15124 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15125 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15126 goto suspend;
15127 }
15128 uint32_t t_2 = *iop_a_src++;
15129 v_b2 = t_2;
15130 }
15131 v_bits |= (v_b2 << v_n_bits);
15132 v_n_bits += 8;
15133 }
15134 label__1__break:;
15135 if ((v_table_entry >> 24) != 128) {
15136 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15137 goto exit;
15138 }
15139 v_table_entry = ((v_table_entry >> 8) & 255);
15140 if (v_table_entry < 16) {
15141 self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
15142 v_i += 1;
15143 goto label__0__continue;
15144 }
15145 v_n_extra_bits = 0;
15146 v_rep_symbol = 0;
15147 v_rep_count = 0;
15148 if (v_table_entry == 16) {
15149 v_n_extra_bits = 2;
15150 if (v_i <= 0) {
15151 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition);
15152 goto exit;
15153 }
15154 v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1)] & 15);
15155 v_rep_count = 3;
15156 } else if (v_table_entry == 17) {
15157 v_n_extra_bits = 3;
15158 v_rep_symbol = 0;
15159 v_rep_count = 3;
15160 } else if (v_table_entry == 18) {
15161 v_n_extra_bits = 7;
15162 v_rep_symbol = 0;
15163 v_rep_count = 11;
15164 } else {
15165 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15166 goto exit;
15167 }
15168 while (v_n_bits < v_n_extra_bits) {
15169 {
15170 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
15171 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15172 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15173 goto suspend;
15174 }
15175 uint32_t t_3 = *iop_a_src++;
15176 v_b3 = t_3;
15177 }
15178 v_bits |= (v_b3 << v_n_bits);
15179 v_n_bits += 8;
15180 }
15181 v_rep_count += ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits));
15182 v_bits >>= v_n_extra_bits;
15183 v_n_bits -= v_n_extra_bits;
15184 while (v_rep_count > 0) {
15185 if (v_i >= (v_n_lit + v_n_dist)) {
15186 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
15187 goto exit;
15188 }
15189 self->private_data.f_code_lengths[v_i] = v_rep_symbol;
15190 v_i += 1;
15191 v_rep_count -= 1;
15192 }
15193 }
15194 if (v_i != (v_n_lit + v_n_dist)) {
15195 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
15196 goto exit;
15197 }
15198 if (self->private_data.f_code_lengths[256] == 0) {
15199 status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code);
15200 goto exit;
15201 }
15202 v_status = wuffs_deflate__decoder__init_huff(self,
15203 0,
15204 0,
15205 v_n_lit,
15206 257);
15207 if (wuffs_base__status__is_error(&v_status)) {
15208 status = v_status;
15209 goto exit;
15210 }
15211 v_status = wuffs_deflate__decoder__init_huff(self,
15212 1,
15213 v_n_lit,
15214 (v_n_lit + v_n_dist),
15215 0);
15216 if (wuffs_base__status__is_error(&v_status)) {
15217 status = v_status;
15218 goto exit;
15219 }
15220 self->private_impl.f_bits = v_bits;
15221 self->private_impl.f_n_bits = v_n_bits;
15222
15223 goto ok;
15224 ok:
15225 self->private_impl.p_init_dynamic_huffman[0] = 0;
15226 goto exit;
15227 }
15228
15229 goto suspend;
15230 suspend:
15231 self->private_impl.p_init_dynamic_huffman[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
15232 self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits;
15233 self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits;
15234 self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit;
15235 self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist;
15236 self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen;
15237 self->private_data.s_init_dynamic_huffman[0].v_i = v_i;
15238 self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask;
15239 self->private_data.s_init_dynamic_huffman[0].v_table_entry = v_table_entry;
15240 self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits;
15241 self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol;
15242 self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count;
15243
15244 goto exit;
15245 exit:
15246 if (a_src) {
15247 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
15248 }
15249
15250 return status;
15251}
15252
15253// -------- func deflate.decoder.init_huff
15254
15255static wuffs_base__status
15256wuffs_deflate__decoder__init_huff(
15257 wuffs_deflate__decoder* self,
15258 uint32_t a_which,
15259 uint32_t a_n_codes0,
15260 uint32_t a_n_codes1,
15261 uint32_t a_base_symbol) {
15262 uint16_t v_counts[16] = {0};
15263 uint32_t v_i = 0;
15264 uint32_t v_remaining = 0;
15265 uint16_t v_offsets[16] = {0};
15266 uint32_t v_n_symbols = 0;
15267 uint32_t v_count = 0;
15268 uint16_t v_symbols[320] = {0};
15269 uint32_t v_min_cl = 0;
15270 uint32_t v_max_cl = 0;
15271 uint32_t v_initial_high_bits = 0;
15272 uint32_t v_prev_cl = 0;
15273 uint32_t v_prev_redirect_key = 0;
15274 uint32_t v_top = 0;
15275 uint32_t v_next_top = 0;
15276 uint32_t v_code = 0;
15277 uint32_t v_key = 0;
15278 uint32_t v_value = 0;
15279 uint32_t v_cl = 0;
15280 uint32_t v_redirect_key = 0;
15281 uint32_t v_j = 0;
15282 uint32_t v_reversed_key = 0;
15283 uint32_t v_symbol = 0;
15284 uint32_t v_high_bits = 0;
15285 uint32_t v_delta = 0;
15286
15287 v_i = a_n_codes0;
15288 while (v_i < a_n_codes1) {
15289 if (v_counts[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
15290 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15291 }
15292#if defined(__GNUC__)
15293#pragma GCC diagnostic push
15294#pragma GCC diagnostic ignored "-Wconversion"
15295#endif
15296 v_counts[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
15297#if defined(__GNUC__)
15298#pragma GCC diagnostic pop
15299#endif
15300 v_i += 1;
15301 }
15302 if ((((uint32_t)(v_counts[0])) + a_n_codes0) == a_n_codes1) {
15303 return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
15304 }
15305 v_remaining = 1;
15306 v_i = 1;
15307 while (v_i <= 15) {
15308 if (v_remaining > 1073741824) {
15309 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15310 }
15311 v_remaining <<= 1;
15312 if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
15313 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed);
15314 }
15315 v_remaining -= ((uint32_t)(v_counts[v_i]));
15316 v_i += 1;
15317 }
15318 if (v_remaining != 0) {
15319 if ((a_which == 1) &&
15320 (v_counts[1] == 1) &&
15321 (self->private_data.f_code_lengths[a_n_codes0] == 1) &&
15322 ((((uint32_t)(v_counts[0])) + a_n_codes0 + 1) == a_n_codes1)) {
15323 self->private_impl.f_n_huffs_bits[1] = 1;
15324 self->private_data.f_huffs[1][0] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[0] | 1);
15325 self->private_data.f_huffs[1][1] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31] | 1);
15326 return wuffs_base__make_status(NULL);
15327 }
15328 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
15329 }
15330 v_i = 1;
15331 while (v_i <= 15) {
15332 v_offsets[v_i] = ((uint16_t)(v_n_symbols));
15333 v_count = ((uint32_t)(v_counts[v_i]));
15334 if (v_n_symbols > (320 - v_count)) {
15335 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15336 }
15337 v_n_symbols = (v_n_symbols + v_count);
15338 v_i += 1;
15339 }
15340 if (v_n_symbols > 288) {
15341 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15342 }
15343 v_i = a_n_codes0;
15344 while (v_i < a_n_codes1) {
15345 if (v_i < a_n_codes0) {
15346 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15347 }
15348 if (self->private_data.f_code_lengths[v_i] != 0) {
15349 if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
15350 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15351 }
15352 v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15)]] = ((uint16_t)((v_i - a_n_codes0)));
15353#if defined(__GNUC__)
15354#pragma GCC diagnostic push
15355#pragma GCC diagnostic ignored "-Wconversion"
15356#endif
15357 v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
15358#if defined(__GNUC__)
15359#pragma GCC diagnostic pop
15360#endif
15361 }
15362 v_i += 1;
15363 }
15364 v_min_cl = 1;
15365 while (true) {
15366 if (v_counts[v_min_cl] != 0) {
15367 goto label__0__break;
15368 }
15369 if (v_min_cl >= 9) {
15370 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length);
15371 }
15372 v_min_cl += 1;
15373 }
15374 label__0__break:;
15375 v_max_cl = 15;
15376 while (true) {
15377 if (v_counts[v_max_cl] != 0) {
15378 goto label__1__break;
15379 }
15380 if (v_max_cl <= 1) {
15381 return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
15382 }
15383 v_max_cl -= 1;
15384 }
15385 label__1__break:;
15386 if (v_max_cl <= 9) {
15387 self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
15388 } else {
15389 self->private_impl.f_n_huffs_bits[a_which] = 9;
15390 }
15391 v_i = 0;
15392 if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15])))) {
15393 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15394 }
15395 if ((a_n_codes0 + ((uint32_t)(v_symbols[0]))) >= 320) {
15396 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15397 }
15398 v_initial_high_bits = 512;
15399 if (v_max_cl < 9) {
15400 v_initial_high_bits = (((uint32_t)(1)) << v_max_cl);
15401 }
15402 v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0])))] & 15)));
15403 v_prev_redirect_key = 4294967295;
15404 v_top = 0;
15405 v_next_top = 512;
15406 v_code = 0;
15407 v_key = 0;
15408 v_value = 0;
15409 while (true) {
15410 if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320) {
15411 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15412 }
15413 v_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15)));
15414 if (v_cl > v_prev_cl) {
15415 v_code <<= (v_cl - v_prev_cl);
15416 if (v_code >= 32768) {
15417 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15418 }
15419 }
15420 v_prev_cl = v_cl;
15421 v_key = v_code;
15422 if (v_cl > 9) {
15423 v_cl -= 9;
15424 v_redirect_key = ((v_key >> v_cl) & 511);
15425 v_key = ((v_key) & WUFFS_BASE__LOW_BITS_MASK__U32(v_cl));
15426 if (v_prev_redirect_key != v_redirect_key) {
15427 v_prev_redirect_key = v_redirect_key;
15428 v_remaining = (((uint32_t)(1)) << v_cl);
15429 v_j = v_prev_cl;
15430 while (v_j <= 15) {
15431 if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
15432 goto label__2__break;
15433 }
15434 v_remaining -= ((uint32_t)(v_counts[v_j]));
15435 if (v_remaining > 1073741824) {
15436 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15437 }
15438 v_remaining <<= 1;
15439 v_j += 1;
15440 }
15441 label__2__break:;
15442 if ((v_j <= 9) || (15 < v_j)) {
15443 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15444 }
15445 v_j -= 9;
15446 v_initial_high_bits = (((uint32_t)(1)) << v_j);
15447 v_top = v_next_top;
15448 if ((v_top + (((uint32_t)(1)) << v_j)) > 1024) {
15449 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15450 }
15451 v_next_top = (v_top + (((uint32_t)(1)) << v_j));
15452 v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1)])) | ((v_redirect_key & 1) << 8));
15453 self->private_data.f_huffs[a_which][v_redirect_key] = (268435465 | (v_top << 8) | (v_j << 4));
15454 }
15455 }
15456 if ((v_key >= 512) || (v_counts[v_prev_cl] <= 0)) {
15457 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15458 }
15459#if defined(__GNUC__)
15460#pragma GCC diagnostic push
15461#pragma GCC diagnostic ignored "-Wconversion"
15462#endif
15463 v_counts[v_prev_cl] -= 1;
15464#if defined(__GNUC__)
15465#pragma GCC diagnostic pop
15466#endif
15467 v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1)])) | ((v_key & 1) << 8));
15468 v_reversed_key >>= (9 - v_cl);
15469 v_symbol = ((uint32_t)(v_symbols[v_i]));
15470 if (v_symbol == 256) {
15471 v_value = (536870912 | v_cl);
15472 } else if ((v_symbol < 256) && (a_which == 0)) {
15473 v_value = (2147483648 | (v_symbol << 8) | v_cl);
15474 } else if (v_symbol >= a_base_symbol) {
15475 v_symbol -= a_base_symbol;
15476 if (a_which == 0) {
15477 v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
15478 } else {
15479 v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
15480 }
15481 } else {
15482 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15483 }
15484 v_high_bits = v_initial_high_bits;
15485 v_delta = (((uint32_t)(1)) << v_cl);
15486 while (v_high_bits >= v_delta) {
15487 v_high_bits -= v_delta;
15488 if ((v_top + ((v_high_bits | v_reversed_key) & 511)) >= 1024) {
15489 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15490 }
15491 self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511))] = v_value;
15492 }
15493 v_i += 1;
15494 if (v_i >= v_n_symbols) {
15495 goto label__3__break;
15496 }
15497 v_code += 1;
15498 if (v_code >= 32768) {
15499 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15500 }
15501 }
15502 label__3__break:;
15503 return wuffs_base__make_status(NULL);
15504}
15505
15506// -------- func deflate.decoder.decode_huffman_fast
15507
15508static wuffs_base__status
15509wuffs_deflate__decoder__decode_huffman_fast(
15510 wuffs_deflate__decoder* self,
15511 wuffs_base__io_buffer* a_dst,
15512 wuffs_base__io_buffer* a_src) {
15513 wuffs_base__status status = wuffs_base__make_status(NULL);
15514
15515 uint32_t v_bits = 0;
15516 uint32_t v_n_bits = 0;
15517 uint32_t v_table_entry = 0;
15518 uint32_t v_table_entry_n_bits = 0;
15519 uint32_t v_lmask = 0;
15520 uint32_t v_dmask = 0;
15521 uint32_t v_redir_top = 0;
15522 uint32_t v_redir_mask = 0;
15523 uint32_t v_length = 0;
15524 uint32_t v_dist_minus_1 = 0;
15525 uint32_t v_hlen = 0;
15526 uint32_t v_hdist = 0;
15527
15528 uint8_t* iop_a_dst = NULL;
15529 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15530 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15531 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15532 if (a_dst) {
15533 io0_a_dst = a_dst->data.ptr;
15534 io1_a_dst = io0_a_dst + a_dst->meta.wi;
15535 iop_a_dst = io1_a_dst;
15536 io2_a_dst = io0_a_dst + a_dst->data.len;
15537 if (a_dst->meta.closed) {
15538 io2_a_dst = iop_a_dst;
15539 }
15540 }
15541 const uint8_t* iop_a_src = NULL;
15542 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15543 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15544 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15545 if (a_src) {
15546 io0_a_src = a_src->data.ptr;
15547 io1_a_src = io0_a_src + a_src->meta.ri;
15548 iop_a_src = io1_a_src;
15549 io2_a_src = io0_a_src + a_src->meta.wi;
15550 }
15551
15552 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
15553 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
15554 goto exit;
15555 }
15556 v_bits = self->private_impl.f_bits;
15557 v_n_bits = self->private_impl.f_n_bits;
15558 v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
15559 v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
15560 label__loop__continue:;
15561 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 258) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12)) {
15562 if (v_n_bits < 15) {
15563 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15564 (iop_a_src += 1, wuffs_base__make_empty_struct());
15565 v_n_bits += 8;
15566 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15567 (iop_a_src += 1, wuffs_base__make_empty_struct());
15568 v_n_bits += 8;
15569 } else {
15570 }
15571 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
15572 v_table_entry_n_bits = (v_table_entry & 15);
15573 v_bits >>= v_table_entry_n_bits;
15574 v_n_bits -= v_table_entry_n_bits;
15575 if ((v_table_entry >> 31) != 0) {
15576 (wuffs_base__store_u8be__no_bounds_check(iop_a_dst,((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1, wuffs_base__make_empty_struct());
15577 goto label__loop__continue;
15578 } else if ((v_table_entry >> 30) != 0) {
15579 } else if ((v_table_entry >> 29) != 0) {
15580 self->private_impl.f_end_of_block = true;
15581 goto label__loop__break;
15582 } else if ((v_table_entry >> 28) != 0) {
15583 if (v_n_bits < 15) {
15584 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15585 (iop_a_src += 1, wuffs_base__make_empty_struct());
15586 v_n_bits += 8;
15587 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15588 (iop_a_src += 1, wuffs_base__make_empty_struct());
15589 v_n_bits += 8;
15590 } else {
15591 }
15592 v_redir_top = ((v_table_entry >> 8) & 65535);
15593 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
15594 v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
15595 v_table_entry_n_bits = (v_table_entry & 15);
15596 v_bits >>= v_table_entry_n_bits;
15597 v_n_bits -= v_table_entry_n_bits;
15598 if ((v_table_entry >> 31) != 0) {
15599 (wuffs_base__store_u8be__no_bounds_check(iop_a_dst,((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1, wuffs_base__make_empty_struct());
15600 goto label__loop__continue;
15601 } else if ((v_table_entry >> 30) != 0) {
15602 } else if ((v_table_entry >> 29) != 0) {
15603 self->private_impl.f_end_of_block = true;
15604 goto label__loop__break;
15605 } else if ((v_table_entry >> 28) != 0) {
15606 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15607 goto exit;
15608 } else if ((v_table_entry >> 27) != 0) {
15609 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
15610 goto exit;
15611 } else {
15612 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15613 goto exit;
15614 }
15615 } else if ((v_table_entry >> 27) != 0) {
15616 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
15617 goto exit;
15618 } else {
15619 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15620 goto exit;
15621 }
15622 v_length = (((v_table_entry >> 8) & 255) + 3);
15623 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
15624 if (v_table_entry_n_bits > 0) {
15625 if (v_n_bits < 15) {
15626 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15627 (iop_a_src += 1, wuffs_base__make_empty_struct());
15628 v_n_bits += 8;
15629 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15630 (iop_a_src += 1, wuffs_base__make_empty_struct());
15631 v_n_bits += 8;
15632 } else {
15633 }
15634 v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
15635 v_bits >>= v_table_entry_n_bits;
15636 v_n_bits -= v_table_entry_n_bits;
15637 } else {
15638 }
15639 if (v_n_bits < 15) {
15640 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15641 (iop_a_src += 1, wuffs_base__make_empty_struct());
15642 v_n_bits += 8;
15643 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15644 (iop_a_src += 1, wuffs_base__make_empty_struct());
15645 v_n_bits += 8;
15646 } else {
15647 }
15648 v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
15649 v_table_entry_n_bits = (v_table_entry & 15);
15650 v_bits >>= v_table_entry_n_bits;
15651 v_n_bits -= v_table_entry_n_bits;
15652 if ((v_table_entry >> 28) == 1) {
15653 if (v_n_bits < 15) {
15654 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15655 (iop_a_src += 1, wuffs_base__make_empty_struct());
15656 v_n_bits += 8;
15657 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15658 (iop_a_src += 1, wuffs_base__make_empty_struct());
15659 v_n_bits += 8;
15660 } else {
15661 }
15662 v_redir_top = ((v_table_entry >> 8) & 65535);
15663 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
15664 v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
15665 v_table_entry_n_bits = (v_table_entry & 15);
15666 v_bits >>= v_table_entry_n_bits;
15667 v_n_bits -= v_table_entry_n_bits;
15668 } else {
15669 }
15670 if ((v_table_entry >> 24) != 64) {
15671 if ((v_table_entry >> 24) == 8) {
15672 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
15673 goto exit;
15674 }
15675 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15676 goto exit;
15677 }
15678 v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
15679 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
15680 if (v_n_bits < v_table_entry_n_bits) {
15681 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15682 (iop_a_src += 1, wuffs_base__make_empty_struct());
15683 v_n_bits += 8;
15684 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
15685 (iop_a_src += 1, wuffs_base__make_empty_struct());
15686 v_n_bits += 8;
15687 }
15688 v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
15689 v_bits >>= v_table_entry_n_bits;
15690 v_n_bits -= v_table_entry_n_bits;
15691 while (true) {
15692 if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
15693 v_hlen = 0;
15694 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
15695 if (v_length > v_hdist) {
15696 v_length -= v_hdist;
15697 v_hlen = v_hdist;
15698 } else {
15699 v_hlen = v_length;
15700 v_length = 0;
15701 }
15702 if (self->private_impl.f_history_index < v_hdist) {
15703 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
15704 goto exit;
15705 }
15706 v_hdist = (self->private_impl.f_history_index - v_hdist);
15707 wuffs_base__io_writer__limited_copy_u32_from_slice(
15708 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), (v_hdist & 32767)));
15709 if (v_length == 0) {
15710 goto label__loop__continue;
15711 }
15712 if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
15713 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
15714 goto exit;
15715 }
15716 }
15717 wuffs_base__io_writer__limited_copy_u32_from_history_fast(
15718 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
15719 goto label__0__break;
15720 }
15721 label__0__break:;
15722 }
15723 label__loop__break:;
15724 while (v_n_bits >= 8) {
15725 v_n_bits -= 8;
15726 if (iop_a_src > io1_a_src) {
15727 (iop_a_src--, wuffs_base__make_empty_struct());
15728 } else {
15729 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
15730 goto exit;
15731 }
15732 }
15733 self->private_impl.f_bits = (v_bits & ((((uint32_t)(1)) << v_n_bits) - 1));
15734 self->private_impl.f_n_bits = v_n_bits;
15735 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
15736 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
15737 goto exit;
15738 }
15739 goto exit;
15740 exit:
15741 if (a_dst) {
15742 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
15743 }
15744 if (a_src) {
15745 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
15746 }
15747
15748 return status;
15749}
15750
15751// -------- func deflate.decoder.decode_huffman_slow
15752
15753static wuffs_base__status
15754wuffs_deflate__decoder__decode_huffman_slow(
15755 wuffs_deflate__decoder* self,
15756 wuffs_base__io_buffer* a_dst,
15757 wuffs_base__io_buffer* a_src) {
15758 wuffs_base__status status = wuffs_base__make_status(NULL);
15759
15760 uint32_t v_bits = 0;
15761 uint32_t v_n_bits = 0;
15762 uint32_t v_table_entry = 0;
15763 uint32_t v_table_entry_n_bits = 0;
15764 uint32_t v_lmask = 0;
15765 uint32_t v_dmask = 0;
15766 uint32_t v_b0 = 0;
15767 uint32_t v_redir_top = 0;
15768 uint32_t v_redir_mask = 0;
15769 uint32_t v_b1 = 0;
15770 uint32_t v_length = 0;
15771 uint32_t v_b2 = 0;
15772 uint32_t v_b3 = 0;
15773 uint32_t v_b4 = 0;
15774 uint32_t v_dist_minus_1 = 0;
15775 uint32_t v_b5 = 0;
15776 uint32_t v_n_copied = 0;
15777 uint32_t v_hlen = 0;
15778 uint32_t v_hdist = 0;
15779
15780 uint8_t* iop_a_dst = NULL;
15781 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15782 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15783 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15784 if (a_dst) {
15785 io0_a_dst = a_dst->data.ptr;
15786 io1_a_dst = io0_a_dst + a_dst->meta.wi;
15787 iop_a_dst = io1_a_dst;
15788 io2_a_dst = io0_a_dst + a_dst->data.len;
15789 if (a_dst->meta.closed) {
15790 io2_a_dst = iop_a_dst;
15791 }
15792 }
15793 const uint8_t* iop_a_src = NULL;
15794 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15795 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15796 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
15797 if (a_src) {
15798 io0_a_src = a_src->data.ptr;
15799 io1_a_src = io0_a_src + a_src->meta.ri;
15800 iop_a_src = io1_a_src;
15801 io2_a_src = io0_a_src + a_src->meta.wi;
15802 }
15803
15804 uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
15805 if (coro_susp_point) {
15806 v_bits = self->private_data.s_decode_huffman_slow[0].v_bits;
15807 v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits;
15808 v_table_entry = self->private_data.s_decode_huffman_slow[0].v_table_entry;
15809 v_table_entry_n_bits = self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits;
15810 v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask;
15811 v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask;
15812 v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top;
15813 v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask;
15814 v_length = self->private_data.s_decode_huffman_slow[0].v_length;
15815 v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1;
15816 v_hlen = self->private_data.s_decode_huffman_slow[0].v_hlen;
15817 v_hdist = self->private_data.s_decode_huffman_slow[0].v_hdist;
15818 }
15819 switch (coro_susp_point) {
15820 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
15821
15822 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
15823 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
15824 goto exit;
15825 }
15826 v_bits = self->private_impl.f_bits;
15827 v_n_bits = self->private_impl.f_n_bits;
15828 v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
15829 v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
15830 label__loop__continue:;
15831 while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
15832 while (true) {
15833 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
15834 v_table_entry_n_bits = (v_table_entry & 15);
15835 if (v_n_bits >= v_table_entry_n_bits) {
15836 v_bits >>= v_table_entry_n_bits;
15837 v_n_bits -= v_table_entry_n_bits;
15838 goto label__0__break;
15839 }
15840 {
15841 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
15842 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15843 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15844 goto suspend;
15845 }
15846 uint32_t t_0 = *iop_a_src++;
15847 v_b0 = t_0;
15848 }
15849 v_bits |= (v_b0 << v_n_bits);
15850 v_n_bits += 8;
15851 }
15852 label__0__break:;
15853 if ((v_table_entry >> 31) != 0) {
15854 self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
15855 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
15856 if (iop_a_dst == io2_a_dst) {
15857 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
15858 goto suspend;
15859 }
15860 *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
15861 goto label__loop__continue;
15862 } else if ((v_table_entry >> 30) != 0) {
15863 } else if ((v_table_entry >> 29) != 0) {
15864 self->private_impl.f_end_of_block = true;
15865 goto label__loop__break;
15866 } else if ((v_table_entry >> 28) != 0) {
15867 v_redir_top = ((v_table_entry >> 8) & 65535);
15868 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
15869 while (true) {
15870 v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
15871 v_table_entry_n_bits = (v_table_entry & 15);
15872 if (v_n_bits >= v_table_entry_n_bits) {
15873 v_bits >>= v_table_entry_n_bits;
15874 v_n_bits -= v_table_entry_n_bits;
15875 goto label__1__break;
15876 }
15877 {
15878 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
15879 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15880 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15881 goto suspend;
15882 }
15883 uint32_t t_1 = *iop_a_src++;
15884 v_b1 = t_1;
15885 }
15886 v_bits |= (v_b1 << v_n_bits);
15887 v_n_bits += 8;
15888 }
15889 label__1__break:;
15890 if ((v_table_entry >> 31) != 0) {
15891 self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
15892 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
15893 if (iop_a_dst == io2_a_dst) {
15894 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
15895 goto suspend;
15896 }
15897 *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
15898 goto label__loop__continue;
15899 } else if ((v_table_entry >> 30) != 0) {
15900 } else if ((v_table_entry >> 29) != 0) {
15901 self->private_impl.f_end_of_block = true;
15902 goto label__loop__break;
15903 } else if ((v_table_entry >> 28) != 0) {
15904 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15905 goto exit;
15906 } else if ((v_table_entry >> 27) != 0) {
15907 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
15908 goto exit;
15909 } else {
15910 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15911 goto exit;
15912 }
15913 } else if ((v_table_entry >> 27) != 0) {
15914 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
15915 goto exit;
15916 } else {
15917 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15918 goto exit;
15919 }
15920 v_length = (((v_table_entry >> 8) & 255) + 3);
15921 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
15922 if (v_table_entry_n_bits > 0) {
15923 while (v_n_bits < v_table_entry_n_bits) {
15924 {
15925 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
15926 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15927 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15928 goto suspend;
15929 }
15930 uint32_t t_2 = *iop_a_src++;
15931 v_b2 = t_2;
15932 }
15933 v_bits |= (v_b2 << v_n_bits);
15934 v_n_bits += 8;
15935 }
15936 v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
15937 v_bits >>= v_table_entry_n_bits;
15938 v_n_bits -= v_table_entry_n_bits;
15939 }
15940 while (true) {
15941 v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
15942 v_table_entry_n_bits = (v_table_entry & 15);
15943 if (v_n_bits >= v_table_entry_n_bits) {
15944 v_bits >>= v_table_entry_n_bits;
15945 v_n_bits -= v_table_entry_n_bits;
15946 goto label__2__break;
15947 }
15948 {
15949 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
15950 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15951 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15952 goto suspend;
15953 }
15954 uint32_t t_3 = *iop_a_src++;
15955 v_b3 = t_3;
15956 }
15957 v_bits |= (v_b3 << v_n_bits);
15958 v_n_bits += 8;
15959 }
15960 label__2__break:;
15961 if ((v_table_entry >> 28) == 1) {
15962 v_redir_top = ((v_table_entry >> 8) & 65535);
15963 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
15964 while (true) {
15965 v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
15966 v_table_entry_n_bits = (v_table_entry & 15);
15967 if (v_n_bits >= v_table_entry_n_bits) {
15968 v_bits >>= v_table_entry_n_bits;
15969 v_n_bits -= v_table_entry_n_bits;
15970 goto label__3__break;
15971 }
15972 {
15973 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
15974 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
15975 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
15976 goto suspend;
15977 }
15978 uint32_t t_4 = *iop_a_src++;
15979 v_b4 = t_4;
15980 }
15981 v_bits |= (v_b4 << v_n_bits);
15982 v_n_bits += 8;
15983 }
15984 label__3__break:;
15985 }
15986 if ((v_table_entry >> 24) != 64) {
15987 if ((v_table_entry >> 24) == 8) {
15988 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
15989 goto exit;
15990 }
15991 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
15992 goto exit;
15993 }
15994 v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
15995 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
15996 if (v_table_entry_n_bits > 0) {
15997 while (v_n_bits < v_table_entry_n_bits) {
15998 {
15999 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
16000 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
16001 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
16002 goto suspend;
16003 }
16004 uint32_t t_5 = *iop_a_src++;
16005 v_b5 = t_5;
16006 }
16007 v_bits |= (v_b5 << v_n_bits);
16008 v_n_bits += 8;
16009 }
16010 v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
16011 v_bits >>= v_table_entry_n_bits;
16012 v_n_bits -= v_table_entry_n_bits;
16013 }
16014 while (true) {
16015 if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
16016 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
16017 if (v_length > v_hdist) {
16018 v_length -= v_hdist;
16019 v_hlen = v_hdist;
16020 } else {
16021 v_hlen = v_length;
16022 v_length = 0;
16023 }
16024 if (self->private_impl.f_history_index < v_hdist) {
16025 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
16026 goto exit;
16027 }
16028 v_hdist = (self->private_impl.f_history_index - v_hdist);
16029 while (true) {
16030 v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
16031 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), (v_hdist & 32767), 32768));
16032 if (v_hlen <= v_n_copied) {
16033 v_hlen = 0;
16034 goto label__4__break;
16035 }
16036 if (v_n_copied > 0) {
16037 v_hlen -= v_n_copied;
16038 v_hdist = ((v_hdist + v_n_copied) & 32767);
16039 if (v_hdist == 0) {
16040 goto label__4__break;
16041 }
16042 }
16043 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
16044 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
16045 }
16046 label__4__break:;
16047 if (v_hlen > 0) {
16048 while (true) {
16049 v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
16050 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), (v_hdist & 32767), 32768));
16051 if (v_hlen <= v_n_copied) {
16052 v_hlen = 0;
16053 goto label__5__break;
16054 }
16055 v_hlen -= v_n_copied;
16056 v_hdist += v_n_copied;
16057 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
16058 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
16059 }
16060 label__5__break:;
16061 }
16062 if (v_length == 0) {
16063 goto label__loop__continue;
16064 }
16065 }
16066 v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_history(
16067 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
16068 if (v_length <= v_n_copied) {
16069 v_length = 0;
16070 goto label__6__break;
16071 }
16072 v_length -= v_n_copied;
16073 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
16074 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
16075 }
16076 label__6__break:;
16077 }
16078 label__loop__break:;
16079 self->private_impl.f_bits = v_bits;
16080 self->private_impl.f_n_bits = v_n_bits;
16081 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
16082 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
16083 goto exit;
16084 }
16085
16086 goto ok;
16087 ok:
16088 self->private_impl.p_decode_huffman_slow[0] = 0;
16089 goto exit;
16090 }
16091
16092 goto suspend;
16093 suspend:
16094 self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
16095 self->private_data.s_decode_huffman_slow[0].v_bits = v_bits;
16096 self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits;
16097 self->private_data.s_decode_huffman_slow[0].v_table_entry = v_table_entry;
16098 self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits = v_table_entry_n_bits;
16099 self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask;
16100 self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask;
16101 self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top;
16102 self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask;
16103 self->private_data.s_decode_huffman_slow[0].v_length = v_length;
16104 self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1;
16105 self->private_data.s_decode_huffman_slow[0].v_hlen = v_hlen;
16106 self->private_data.s_decode_huffman_slow[0].v_hdist = v_hdist;
16107
16108 goto exit;
16109 exit:
16110 if (a_dst) {
16111 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
16112 }
16113 if (a_src) {
16114 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
16115 }
16116
16117 return status;
16118}
16119
16120#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
16121
16122#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
16123
16124// ---------------- Status Codes Implementations
16125
16126const char* wuffs_lzw__error__bad_code = "#lzw: bad code";
16127const char* wuffs_lzw__error__internal_error_inconsistent_i_o = "#lzw: internal error: inconsistent I/O";
16128
16129// ---------------- Private Consts
16130
16131// ---------------- Private Initializer Prototypes
16132
16133// ---------------- Private Function Prototypes
16134
16135static wuffs_base__empty_struct
16136wuffs_lzw__decoder__read_from(
16137 wuffs_lzw__decoder* self,
16138 wuffs_base__io_buffer* a_src);
16139
16140static wuffs_base__status
16141wuffs_lzw__decoder__write_to(
16142 wuffs_lzw__decoder* self,
16143 wuffs_base__io_buffer* a_dst);
16144
16145// ---------------- VTables
16146
16147const wuffs_base__io_transformer__func_ptrs
16148wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = {
16149 (wuffs_base__empty_struct(*)(void*,
16150 uint32_t,
16151 bool))(&wuffs_lzw__decoder__set_quirk_enabled),
16152 (wuffs_base__status(*)(void*,
16153 wuffs_base__io_buffer*,
16154 wuffs_base__io_buffer*,
16155 wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io),
16156 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len),
16157};
16158
16159// ---------------- Initializer Implementations
16160
16161wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
16162wuffs_lzw__decoder__initialize(
16163 wuffs_lzw__decoder* self,
16164 size_t sizeof_star_self,
16165 uint64_t wuffs_version,
16166 uint32_t initialize_flags){
16167 if (!self) {
16168 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16169 }
16170 if (sizeof(*self) != sizeof_star_self) {
16171 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
16172 }
16173 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
16174 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
16175 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
16176 }
16177
16178 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
16179 // The whole point of this if-check is to detect an uninitialized *self.
16180 // We disable the warning on GCC. Clang-5.0 does not have this warning.
16181#if !defined(__clang__) && defined(__GNUC__)
16182#pragma GCC diagnostic push
16183#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
16184#endif
16185 if (self->private_impl.magic != 0) {
16186 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
16187 }
16188#if !defined(__clang__) && defined(__GNUC__)
16189#pragma GCC diagnostic pop
16190#endif
16191 } else {
16192 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
16193 memset(self, 0, sizeof(*self));
16194 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
16195 } else {
16196 memset(&(self->private_impl), 0, sizeof(self->private_impl));
16197 }
16198 }
16199
16200 self->private_impl.magic = WUFFS_BASE__MAGIC;
16201 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
16202 wuffs_base__io_transformer__vtable_name;
16203 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
16204 (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer);
16205 return wuffs_base__make_status(NULL);
16206}
16207
16208wuffs_lzw__decoder*
16209wuffs_lzw__decoder__alloc() {
16210 wuffs_lzw__decoder* x =
16211 (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
16212 if (!x) {
16213 return NULL;
16214 }
16215 if (wuffs_lzw__decoder__initialize(
16216 x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
16217 free(x);
16218 return NULL;
16219 }
16220 return x;
16221}
16222
16223size_t
16224sizeof__wuffs_lzw__decoder() {
16225 return sizeof(wuffs_lzw__decoder);
16226}
16227
16228// ---------------- Function Implementations
16229
16230// -------- func lzw.decoder.set_quirk_enabled
16231
16232WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
16233wuffs_lzw__decoder__set_quirk_enabled(
16234 wuffs_lzw__decoder* self,
16235 uint32_t a_quirk,
16236 bool a_enabled) {
16237 return wuffs_base__make_empty_struct();
16238}
16239
16240// -------- func lzw.decoder.set_literal_width
16241
16242WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
16243wuffs_lzw__decoder__set_literal_width(
16244 wuffs_lzw__decoder* self,
16245 uint32_t a_lw) {
16246 if (!self) {
16247 return wuffs_base__make_empty_struct();
16248 }
16249 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
16250 return wuffs_base__make_empty_struct();
16251 }
16252 if (a_lw > 8) {
16253 self->private_impl.magic = WUFFS_BASE__DISABLED;
16254 return wuffs_base__make_empty_struct();
16255 }
16256
16257 self->private_impl.f_set_literal_width_arg = (a_lw + 1);
16258 return wuffs_base__make_empty_struct();
16259}
16260
16261// -------- func lzw.decoder.workbuf_len
16262
16263WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
16264wuffs_lzw__decoder__workbuf_len(
16265 const wuffs_lzw__decoder* self) {
16266 if (!self) {
16267 return wuffs_base__utility__empty_range_ii_u64();
16268 }
16269 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
16270 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
16271 return wuffs_base__utility__empty_range_ii_u64();
16272 }
16273
16274 return wuffs_base__utility__make_range_ii_u64(0, 0);
16275}
16276
16277// -------- func lzw.decoder.transform_io
16278
16279WUFFS_BASE__MAYBE_STATIC wuffs_base__status
16280wuffs_lzw__decoder__transform_io(
16281 wuffs_lzw__decoder* self,
16282 wuffs_base__io_buffer* a_dst,
16283 wuffs_base__io_buffer* a_src,
16284 wuffs_base__slice_u8 a_workbuf) {
16285 if (!self) {
16286 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16287 }
16288 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
16289 return wuffs_base__make_status(
16290 (self->private_impl.magic == WUFFS_BASE__DISABLED)
16291 ? wuffs_base__error__disabled_by_previous_error
16292 : wuffs_base__error__initialize_not_called);
16293 }
16294 if (!a_dst || !a_src) {
16295 self->private_impl.magic = WUFFS_BASE__DISABLED;
16296 return wuffs_base__make_status(wuffs_base__error__bad_argument);
16297 }
16298 if ((self->private_impl.active_coroutine != 0) &&
16299 (self->private_impl.active_coroutine != 1)) {
16300 self->private_impl.magic = WUFFS_BASE__DISABLED;
16301 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
16302 }
16303 self->private_impl.active_coroutine = 0;
16304 wuffs_base__status status = wuffs_base__make_status(NULL);
16305
16306 uint32_t v_i = 0;
16307
16308 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
16309 switch (coro_susp_point) {
16310 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
16311
16312 self->private_impl.f_literal_width = 8;
16313 if (self->private_impl.f_set_literal_width_arg > 0) {
16314 self->private_impl.f_literal_width = (self->private_impl.f_set_literal_width_arg - 1);
16315 }
16316 self->private_impl.f_clear_code = (((uint32_t)(1)) << self->private_impl.f_literal_width);
16317 self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1);
16318 self->private_impl.f_save_code = self->private_impl.f_end_code;
16319 self->private_impl.f_prev_code = self->private_impl.f_end_code;
16320 self->private_impl.f_width = (self->private_impl.f_literal_width + 1);
16321 self->private_impl.f_bits = 0;
16322 self->private_impl.f_n_bits = 0;
16323 self->private_impl.f_output_ri = 0;
16324 self->private_impl.f_output_wi = 0;
16325 v_i = 0;
16326 while (v_i < self->private_impl.f_clear_code) {
16327 self->private_data.f_lm1s[v_i] = 0;
16328 self->private_data.f_suffixes[v_i][0] = ((uint8_t)(v_i));
16329 v_i += 1;
16330 }
16331 label__0__continue:;
16332 while (true) {
16333 wuffs_lzw__decoder__read_from(self, a_src);
16334 if (self->private_impl.f_output_wi > 0) {
16335 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
16336 status = wuffs_lzw__decoder__write_to(self, a_dst);
16337 if (status.repr) {
16338 goto suspend;
16339 }
16340 }
16341 if (self->private_impl.f_read_from_return_value == 0) {
16342 goto label__0__break;
16343 } else if (self->private_impl.f_read_from_return_value == 1) {
16344 goto label__0__continue;
16345 } else if (self->private_impl.f_read_from_return_value == 2) {
16346 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
16347 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
16348 } else if (self->private_impl.f_read_from_return_value == 3) {
16349 status = wuffs_base__make_status(wuffs_lzw__error__bad_code);
16350 goto exit;
16351 } else {
16352 status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
16353 goto exit;
16354 }
16355 }
16356 label__0__break:;
16357
16358 goto ok;
16359 ok:
16360 self->private_impl.p_transform_io[0] = 0;
16361 goto exit;
16362 }
16363
16364 goto suspend;
16365 suspend:
16366 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
16367 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
16368
16369 goto exit;
16370 exit:
16371 if (wuffs_base__status__is_error(&status)) {
16372 self->private_impl.magic = WUFFS_BASE__DISABLED;
16373 }
16374 return status;
16375}
16376
16377// -------- func lzw.decoder.read_from
16378
16379static wuffs_base__empty_struct
16380wuffs_lzw__decoder__read_from(
16381 wuffs_lzw__decoder* self,
16382 wuffs_base__io_buffer* a_src) {
16383 uint32_t v_clear_code = 0;
16384 uint32_t v_end_code = 0;
16385 uint32_t v_save_code = 0;
16386 uint32_t v_prev_code = 0;
16387 uint32_t v_width = 0;
16388 uint32_t v_bits = 0;
16389 uint32_t v_n_bits = 0;
16390 uint32_t v_output_wi = 0;
16391 uint32_t v_code = 0;
16392 uint32_t v_c = 0;
16393 uint32_t v_o = 0;
16394 uint32_t v_steps = 0;
16395 uint8_t v_first_byte = 0;
16396 uint16_t v_lm1_b = 0;
16397 uint16_t v_lm1_a = 0;
16398
16399 const uint8_t* iop_a_src = NULL;
16400 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
16401 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
16402 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
16403 if (a_src) {
16404 io0_a_src = a_src->data.ptr;
16405 io1_a_src = io0_a_src + a_src->meta.ri;
16406 iop_a_src = io1_a_src;
16407 io2_a_src = io0_a_src + a_src->meta.wi;
16408 }
16409
16410 v_clear_code = self->private_impl.f_clear_code;
16411 v_end_code = self->private_impl.f_end_code;
16412 v_save_code = self->private_impl.f_save_code;
16413 v_prev_code = self->private_impl.f_prev_code;
16414 v_width = self->private_impl.f_width;
16415 v_bits = self->private_impl.f_bits;
16416 v_n_bits = self->private_impl.f_n_bits;
16417 v_output_wi = self->private_impl.f_output_wi;
16418 while (true) {
16419 if (v_n_bits < v_width) {
16420 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
16421 v_bits |= (wuffs_base__load_u32le__no_bounds_check(iop_a_src) << v_n_bits);
16422 (iop_a_src += ((31 - v_n_bits) >> 3), wuffs_base__make_empty_struct());
16423 v_n_bits |= 24;
16424 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
16425 self->private_impl.f_read_from_return_value = 2;
16426 goto label__0__break;
16427 } else {
16428 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
16429 (iop_a_src += 1, wuffs_base__make_empty_struct());
16430 v_n_bits += 8;
16431 if (v_n_bits >= v_width) {
16432 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
16433 self->private_impl.f_read_from_return_value = 2;
16434 goto label__0__break;
16435 } else {
16436 v_bits |= (((uint32_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
16437 (iop_a_src += 1, wuffs_base__make_empty_struct());
16438 v_n_bits += 8;
16439 if (v_n_bits < v_width) {
16440 self->private_impl.f_read_from_return_value = 4;
16441 goto label__0__break;
16442 }
16443 }
16444 }
16445 }
16446 v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
16447 v_bits >>= v_width;
16448 v_n_bits -= v_width;
16449 if (v_code < v_clear_code) {
16450 self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
16451 v_output_wi = ((v_output_wi + 1) & 8191);
16452 if (v_save_code <= 4095) {
16453 v_lm1_a = ((self->private_data.f_lm1s[v_prev_code] + 1) & 4095);
16454 self->private_data.f_lm1s[v_save_code] = v_lm1_a;
16455 if ((v_lm1_a % 8) != 0) {
16456 self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
16457 memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code]));
16458 self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8)] = ((uint8_t)(v_code));
16459 } else {
16460 self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
16461 self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_code));
16462 }
16463 v_save_code += 1;
16464 if (v_width < 12) {
16465 v_width += (1 & (v_save_code >> v_width));
16466 }
16467 v_prev_code = v_code;
16468 }
16469 } else if (v_code <= v_end_code) {
16470 if (v_code == v_end_code) {
16471 self->private_impl.f_read_from_return_value = 0;
16472 goto label__0__break;
16473 }
16474 v_save_code = v_end_code;
16475 v_prev_code = v_end_code;
16476 v_width = (self->private_impl.f_literal_width + 1);
16477 } else if (v_code <= v_save_code) {
16478 v_c = v_code;
16479 if (v_code == v_save_code) {
16480 v_c = v_prev_code;
16481 }
16482 v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288)) & 8191);
16483 v_output_wi = ((v_output_wi + 1 + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191);
16484 v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3);
16485 while (true) {
16486 memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8);
16487 if (v_steps <= 0) {
16488 goto label__1__break;
16489 }
16490 v_steps -= 1;
16491 v_o = ((v_o - 8) & 8191);
16492 v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
16493 }
16494 label__1__break:;
16495 v_first_byte = self->private_data.f_suffixes[v_c][0];
16496 if (v_code == v_save_code) {
16497 self->private_data.f_output[v_output_wi] = v_first_byte;
16498 v_output_wi = ((v_output_wi + 1) & 8191);
16499 }
16500 if (v_save_code <= 4095) {
16501 v_lm1_b = ((self->private_data.f_lm1s[v_prev_code] + 1) & 4095);
16502 self->private_data.f_lm1s[v_save_code] = v_lm1_b;
16503 if ((v_lm1_b % 8) != 0) {
16504 self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
16505 memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code]));
16506 self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8)] = v_first_byte;
16507 } else {
16508 self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
16509 self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_first_byte));
16510 }
16511 v_save_code += 1;
16512 if (v_width < 12) {
16513 v_width += (1 & (v_save_code >> v_width));
16514 }
16515 v_prev_code = v_code;
16516 }
16517 } else {
16518 self->private_impl.f_read_from_return_value = 3;
16519 goto label__0__break;
16520 }
16521 if (v_output_wi > 4095) {
16522 self->private_impl.f_read_from_return_value = 1;
16523 goto label__0__break;
16524 }
16525 }
16526 label__0__break:;
16527 if (self->private_impl.f_read_from_return_value != 2) {
16528 while (v_n_bits >= 8) {
16529 v_n_bits -= 8;
16530 if (iop_a_src > io1_a_src) {
16531 (iop_a_src--, wuffs_base__make_empty_struct());
16532 } else {
16533 self->private_impl.f_read_from_return_value = 4;
16534 goto label__2__break;
16535 }
16536 }
16537 label__2__break:;
16538 }
16539 self->private_impl.f_save_code = v_save_code;
16540 self->private_impl.f_prev_code = v_prev_code;
16541 self->private_impl.f_width = v_width;
16542 self->private_impl.f_bits = v_bits;
16543 self->private_impl.f_n_bits = v_n_bits;
16544 self->private_impl.f_output_wi = v_output_wi;
16545 if (a_src) {
16546 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
16547 }
16548
16549 return wuffs_base__make_empty_struct();
16550}
16551
16552// -------- func lzw.decoder.write_to
16553
16554static wuffs_base__status
16555wuffs_lzw__decoder__write_to(
16556 wuffs_lzw__decoder* self,
16557 wuffs_base__io_buffer* a_dst) {
16558 wuffs_base__status status = wuffs_base__make_status(NULL);
16559
16560 wuffs_base__slice_u8 v_s = {0};
16561 uint64_t v_n = 0;
16562
16563 uint8_t* iop_a_dst = NULL;
16564 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
16565 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
16566 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
16567 if (a_dst) {
16568 io0_a_dst = a_dst->data.ptr;
16569 io1_a_dst = io0_a_dst + a_dst->meta.wi;
16570 iop_a_dst = io1_a_dst;
16571 io2_a_dst = io0_a_dst + a_dst->data.len;
16572 if (a_dst->meta.closed) {
16573 io2_a_dst = iop_a_dst;
16574 }
16575 }
16576
16577 uint32_t coro_susp_point = self->private_impl.p_write_to[0];
16578 switch (coro_susp_point) {
16579 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
16580
16581 while (self->private_impl.f_output_wi > 0) {
16582 if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
16583 status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
16584 goto exit;
16585 }
16586 v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
16587 8199),
16588 self->private_impl.f_output_ri,
16589 self->private_impl.f_output_wi);
16590 v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s);
16591 if (v_n == ((uint64_t)(v_s.len))) {
16592 self->private_impl.f_output_ri = 0;
16593 self->private_impl.f_output_wi = 0;
16594 status = wuffs_base__make_status(NULL);
16595 goto ok;
16596 }
16597 self->private_impl.f_output_ri = ((self->private_impl.f_output_ri + ((uint32_t)((v_n & 4294967295)))) & 8191);
16598 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
16599 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
16600 }
16601
16602 goto ok;
16603 ok:
16604 self->private_impl.p_write_to[0] = 0;
16605 goto exit;
16606 }
16607
16608 goto suspend;
16609 suspend:
16610 self->private_impl.p_write_to[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
16611
16612 goto exit;
16613 exit:
16614 if (a_dst) {
16615 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
16616 }
16617
16618 return status;
16619}
16620
16621// -------- func lzw.decoder.flush
16622
16623WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
16624wuffs_lzw__decoder__flush(
16625 wuffs_lzw__decoder* self) {
16626 if (!self) {
16627 return wuffs_base__make_slice_u8(NULL, 0);
16628 }
16629 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
16630 return wuffs_base__make_slice_u8(NULL, 0);
16631 }
16632
16633 wuffs_base__slice_u8 v_s = {0};
16634
16635 if (self->private_impl.f_output_ri <= self->private_impl.f_output_wi) {
16636 v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
16637 8199),
16638 self->private_impl.f_output_ri,
16639 self->private_impl.f_output_wi);
16640 }
16641 self->private_impl.f_output_ri = 0;
16642 self->private_impl.f_output_wi = 0;
16643 return v_s;
16644}
16645
16646#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
16647
16648#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
16649
16650// ---------------- Status Codes Implementations
16651
16652const char* wuffs_gif__error__bad_extension_label = "#gif: bad extension label";
16653const char* wuffs_gif__error__bad_frame_size = "#gif: bad frame size";
16654const char* wuffs_gif__error__bad_graphic_control = "#gif: bad graphic control";
16655const char* wuffs_gif__error__bad_header = "#gif: bad header";
16656const char* wuffs_gif__error__bad_literal_width = "#gif: bad literal width";
16657const char* wuffs_gif__error__bad_palette = "#gif: bad palette";
16658const char* wuffs_gif__error__internal_error_inconsistent_ri_wi = "#gif: internal error: inconsistent ri/wi";
16659
16660// ---------------- Private Consts
16661
16662static const uint32_t
16663WUFFS_GIF__INTERLACE_START[5]WUFFS_BASE__POTENTIALLY_UNUSED = {
16664 4294967295, 1, 2, 4, 0,
16665};
16666
16667static const uint8_t
16668WUFFS_GIF__INTERLACE_DELTA[5]WUFFS_BASE__POTENTIALLY_UNUSED = {
16669 1, 2, 4, 8, 8,
16670};
16671
16672static const uint8_t
16673WUFFS_GIF__INTERLACE_COUNT[5]WUFFS_BASE__POTENTIALLY_UNUSED = {
16674 0, 1, 2, 4, 8,
16675};
16676
16677static const uint8_t
16678WUFFS_GIF__ANIMEXTS1DOT0[11]WUFFS_BASE__POTENTIALLY_UNUSED = {
16679 65, 78, 73, 77, 69, 88, 84, 83,
16680 49, 46, 48,
16681};
16682
16683static const uint8_t
16684WUFFS_GIF__NETSCAPE2DOT0[11]WUFFS_BASE__POTENTIALLY_UNUSED = {
16685 78, 69, 84, 83, 67, 65, 80, 69,
16686 50, 46, 48,
16687};
16688
16689static const uint8_t
16690WUFFS_GIF__ICCRGBG1012[11]WUFFS_BASE__POTENTIALLY_UNUSED = {
16691 73, 67, 67, 82, 71, 66, 71, 49,
16692 48, 49, 50,
16693};
16694
16695static const uint8_t
16696WUFFS_GIF__XMPDATAXMP[11]WUFFS_BASE__POTENTIALLY_UNUSED = {
16697 88, 77, 80, 32, 68, 97, 116, 97,
16698 88, 77, 80,
16699};
16700
16701#define WUFFS_GIF__QUIRKS_BASE 1041635328
16702
16703#define WUFFS_GIF__QUIRKS_COUNT 7
16704
16705// ---------------- Private Initializer Prototypes
16706
16707// ---------------- Private Function Prototypes
16708
16709static wuffs_base__status
16710wuffs_gif__config_decoder__skip_frame(
16711 wuffs_gif__config_decoder* self,
16712 wuffs_base__io_buffer* a_src);
16713
16714static wuffs_base__empty_struct
16715wuffs_gif__config_decoder__reset_gc(
16716 wuffs_gif__config_decoder* self);
16717
16718static wuffs_base__status
16719wuffs_gif__config_decoder__decode_up_to_id_part1(
16720 wuffs_gif__config_decoder* self,
16721 wuffs_base__io_buffer* a_src);
16722
16723static wuffs_base__status
16724wuffs_gif__config_decoder__decode_header(
16725 wuffs_gif__config_decoder* self,
16726 wuffs_base__io_buffer* a_src);
16727
16728static wuffs_base__status
16729wuffs_gif__config_decoder__decode_lsd(
16730 wuffs_gif__config_decoder* self,
16731 wuffs_base__io_buffer* a_src);
16732
16733static wuffs_base__status
16734wuffs_gif__config_decoder__decode_extension(
16735 wuffs_gif__config_decoder* self,
16736 wuffs_base__io_buffer* a_src);
16737
16738static wuffs_base__status
16739wuffs_gif__config_decoder__skip_blocks(
16740 wuffs_gif__config_decoder* self,
16741 wuffs_base__io_buffer* a_src);
16742
16743static wuffs_base__status
16744wuffs_gif__config_decoder__decode_ae(
16745 wuffs_gif__config_decoder* self,
16746 wuffs_base__io_buffer* a_src);
16747
16748static wuffs_base__status
16749wuffs_gif__config_decoder__decode_gc(
16750 wuffs_gif__config_decoder* self,
16751 wuffs_base__io_buffer* a_src);
16752
16753static wuffs_base__status
16754wuffs_gif__config_decoder__decode_id_part0(
16755 wuffs_gif__config_decoder* self,
16756 wuffs_base__io_buffer* a_src);
16757
16758static wuffs_base__status
16759wuffs_gif__decoder__skip_frame(
16760 wuffs_gif__decoder* self,
16761 wuffs_base__io_buffer* a_src);
16762
16763static wuffs_base__empty_struct
16764wuffs_gif__decoder__reset_gc(
16765 wuffs_gif__decoder* self);
16766
16767static wuffs_base__status
16768wuffs_gif__decoder__decode_up_to_id_part1(
16769 wuffs_gif__decoder* self,
16770 wuffs_base__io_buffer* a_src);
16771
16772static wuffs_base__status
16773wuffs_gif__decoder__decode_header(
16774 wuffs_gif__decoder* self,
16775 wuffs_base__io_buffer* a_src);
16776
16777static wuffs_base__status
16778wuffs_gif__decoder__decode_lsd(
16779 wuffs_gif__decoder* self,
16780 wuffs_base__io_buffer* a_src);
16781
16782static wuffs_base__status
16783wuffs_gif__decoder__decode_extension(
16784 wuffs_gif__decoder* self,
16785 wuffs_base__io_buffer* a_src);
16786
16787static wuffs_base__status
16788wuffs_gif__decoder__skip_blocks(
16789 wuffs_gif__decoder* self,
16790 wuffs_base__io_buffer* a_src);
16791
16792static wuffs_base__status
16793wuffs_gif__decoder__decode_ae(
16794 wuffs_gif__decoder* self,
16795 wuffs_base__io_buffer* a_src);
16796
16797static wuffs_base__status
16798wuffs_gif__decoder__decode_gc(
16799 wuffs_gif__decoder* self,
16800 wuffs_base__io_buffer* a_src);
16801
16802static wuffs_base__status
16803wuffs_gif__decoder__decode_id_part0(
16804 wuffs_gif__decoder* self,
16805 wuffs_base__io_buffer* a_src);
16806
16807static wuffs_base__status
16808wuffs_gif__decoder__decode_id_part1(
16809 wuffs_gif__decoder* self,
16810 wuffs_base__pixel_buffer* a_dst,
16811 wuffs_base__io_buffer* a_src,
16812 wuffs_base__pixel_blend a_blend);
16813
16814static wuffs_base__status
16815wuffs_gif__decoder__decode_id_part2(
16816 wuffs_gif__decoder* self,
16817 wuffs_base__pixel_buffer* a_dst,
16818 wuffs_base__io_buffer* a_src,
16819 wuffs_base__slice_u8 a_workbuf);
16820
16821static wuffs_base__status
16822wuffs_gif__decoder__copy_to_image_buffer(
16823 wuffs_gif__decoder* self,
16824 wuffs_base__pixel_buffer* a_pb,
16825 wuffs_base__slice_u8 a_src);
16826
16827// ---------------- VTables
16828
16829const wuffs_base__image_decoder__func_ptrs
16830wuffs_gif__config_decoder__func_ptrs_for__wuffs_base__image_decoder = {
16831 (wuffs_base__status(*)(void*,
16832 wuffs_base__pixel_buffer*,
16833 wuffs_base__io_buffer*,
16834 wuffs_base__pixel_blend,
16835 wuffs_base__slice_u8,
16836 wuffs_base__decode_frame_options*))(&wuffs_gif__config_decoder__decode_frame),
16837 (wuffs_base__status(*)(void*,
16838 wuffs_base__frame_config*,
16839 wuffs_base__io_buffer*))(&wuffs_gif__config_decoder__decode_frame_config),
16840 (wuffs_base__status(*)(void*,
16841 wuffs_base__image_config*,
16842 wuffs_base__io_buffer*))(&wuffs_gif__config_decoder__decode_image_config),
16843 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__config_decoder__frame_dirty_rect),
16844 (uint32_t(*)(const void*))(&wuffs_gif__config_decoder__num_animation_loops),
16845 (uint64_t(*)(const void*))(&wuffs_gif__config_decoder__num_decoded_frame_configs),
16846 (uint64_t(*)(const void*))(&wuffs_gif__config_decoder__num_decoded_frames),
16847 (wuffs_base__status(*)(void*,
16848 uint64_t,
16849 uint64_t))(&wuffs_gif__config_decoder__restart_frame),
16850 (wuffs_base__empty_struct(*)(void*,
16851 uint32_t,
16852 bool))(&wuffs_gif__config_decoder__set_quirk_enabled),
16853 (wuffs_base__empty_struct(*)(void*,
16854 uint32_t,
16855 bool))(&wuffs_gif__config_decoder__set_report_metadata),
16856 (wuffs_base__status(*)(void*,
16857 wuffs_base__io_buffer*,
16858 wuffs_base__more_information*,
16859 wuffs_base__io_buffer*))(&wuffs_gif__config_decoder__tell_me_more),
16860 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__config_decoder__workbuf_len),
16861};
16862
16863const wuffs_base__image_decoder__func_ptrs
16864wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = {
16865 (wuffs_base__status(*)(void*,
16866 wuffs_base__pixel_buffer*,
16867 wuffs_base__io_buffer*,
16868 wuffs_base__pixel_blend,
16869 wuffs_base__slice_u8,
16870 wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame),
16871 (wuffs_base__status(*)(void*,
16872 wuffs_base__frame_config*,
16873 wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config),
16874 (wuffs_base__status(*)(void*,
16875 wuffs_base__image_config*,
16876 wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config),
16877 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect),
16878 (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops),
16879 (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs),
16880 (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames),
16881 (wuffs_base__status(*)(void*,
16882 uint64_t,
16883 uint64_t))(&wuffs_gif__decoder__restart_frame),
16884 (wuffs_base__empty_struct(*)(void*,
16885 uint32_t,
16886 bool))(&wuffs_gif__decoder__set_quirk_enabled),
16887 (wuffs_base__empty_struct(*)(void*,
16888 uint32_t,
16889 bool))(&wuffs_gif__decoder__set_report_metadata),
16890 (wuffs_base__status(*)(void*,
16891 wuffs_base__io_buffer*,
16892 wuffs_base__more_information*,
16893 wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more),
16894 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len),
16895};
16896
16897// ---------------- Initializer Implementations
16898
16899wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
16900wuffs_gif__config_decoder__initialize(
16901 wuffs_gif__config_decoder* self,
16902 size_t sizeof_star_self,
16903 uint64_t wuffs_version,
16904 uint32_t initialize_flags){
16905 if (!self) {
16906 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16907 }
16908 if (sizeof(*self) != sizeof_star_self) {
16909 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
16910 }
16911 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
16912 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
16913 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
16914 }
16915
16916 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
16917 // The whole point of this if-check is to detect an uninitialized *self.
16918 // We disable the warning on GCC. Clang-5.0 does not have this warning.
16919#if !defined(__clang__) && defined(__GNUC__)
16920#pragma GCC diagnostic push
16921#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
16922#endif
16923 if (self->private_impl.magic != 0) {
16924 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
16925 }
16926#if !defined(__clang__) && defined(__GNUC__)
16927#pragma GCC diagnostic pop
16928#endif
16929 } else {
16930 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
16931 memset(self, 0, sizeof(*self));
16932 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
16933 } else {
16934 memset(&(self->private_impl), 0, sizeof(self->private_impl));
16935 }
16936 }
16937
16938 self->private_impl.magic = WUFFS_BASE__MAGIC;
16939 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
16940 wuffs_base__image_decoder__vtable_name;
16941 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
16942 (const void*)(&wuffs_gif__config_decoder__func_ptrs_for__wuffs_base__image_decoder);
16943 return wuffs_base__make_status(NULL);
16944}
16945
16946wuffs_gif__config_decoder*
16947wuffs_gif__config_decoder__alloc() {
16948 wuffs_gif__config_decoder* x =
16949 (wuffs_gif__config_decoder*)(calloc(sizeof(wuffs_gif__config_decoder), 1));
16950 if (!x) {
16951 return NULL;
16952 }
16953 if (wuffs_gif__config_decoder__initialize(
16954 x, sizeof(wuffs_gif__config_decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
16955 free(x);
16956 return NULL;
16957 }
16958 return x;
16959}
16960
16961size_t
16962sizeof__wuffs_gif__config_decoder() {
16963 return sizeof(wuffs_gif__config_decoder);
16964}
16965
16966wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
16967wuffs_gif__decoder__initialize(
16968 wuffs_gif__decoder* self,
16969 size_t sizeof_star_self,
16970 uint64_t wuffs_version,
16971 uint32_t initialize_flags){
16972 if (!self) {
16973 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16974 }
16975 if (sizeof(*self) != sizeof_star_self) {
16976 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
16977 }
16978 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
16979 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
16980 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
16981 }
16982
16983 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
16984 // The whole point of this if-check is to detect an uninitialized *self.
16985 // We disable the warning on GCC. Clang-5.0 does not have this warning.
16986#if !defined(__clang__) && defined(__GNUC__)
16987#pragma GCC diagnostic push
16988#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
16989#endif
16990 if (self->private_impl.magic != 0) {
16991 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
16992 }
16993#if !defined(__clang__) && defined(__GNUC__)
16994#pragma GCC diagnostic pop
16995#endif
16996 } else {
16997 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
16998 memset(self, 0, sizeof(*self));
16999 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
17000 } else {
17001 memset(&(self->private_impl), 0, sizeof(self->private_impl));
17002 }
17003 }
17004
17005 {
17006 wuffs_base__status z = wuffs_lzw__decoder__initialize(
17007 &self->private_data.f_lzw, sizeof(self->private_data.f_lzw), WUFFS_VERSION, initialize_flags);
17008 if (z.repr) {
17009 return z;
17010 }
17011 }
17012 self->private_impl.magic = WUFFS_BASE__MAGIC;
17013 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
17014 wuffs_base__image_decoder__vtable_name;
17015 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
17016 (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder);
17017 return wuffs_base__make_status(NULL);
17018}
17019
17020wuffs_gif__decoder*
17021wuffs_gif__decoder__alloc() {
17022 wuffs_gif__decoder* x =
17023 (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
17024 if (!x) {
17025 return NULL;
17026 }
17027 if (wuffs_gif__decoder__initialize(
17028 x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
17029 free(x);
17030 return NULL;
17031 }
17032 return x;
17033}
17034
17035size_t
17036sizeof__wuffs_gif__decoder() {
17037 return sizeof(wuffs_gif__decoder);
17038}
17039
17040// ---------------- Function Implementations
17041
17042// -------- func gif.config_decoder.set_quirk_enabled
17043
17044WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
17045wuffs_gif__config_decoder__set_quirk_enabled(
17046 wuffs_gif__config_decoder* self,
17047 uint32_t a_quirk,
17048 bool a_enabled) {
17049 if (!self) {
17050 return wuffs_base__make_empty_struct();
17051 }
17052 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17053 return wuffs_base__make_empty_struct();
17054 }
17055
17056 if ((self->private_impl.f_call_sequence == 0) && (a_quirk >= 1041635328)) {
17057 a_quirk -= 1041635328;
17058 if (a_quirk < 7) {
17059 self->private_impl.f_quirks[a_quirk] = a_enabled;
17060 }
17061 }
17062 return wuffs_base__make_empty_struct();
17063}
17064
17065// -------- func gif.config_decoder.decode_image_config
17066
17067WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17068wuffs_gif__config_decoder__decode_image_config(
17069 wuffs_gif__config_decoder* self,
17070 wuffs_base__image_config* a_dst,
17071 wuffs_base__io_buffer* a_src) {
17072 if (!self) {
17073 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17074 }
17075 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17076 return wuffs_base__make_status(
17077 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17078 ? wuffs_base__error__disabled_by_previous_error
17079 : wuffs_base__error__initialize_not_called);
17080 }
17081 if (!a_src) {
17082 self->private_impl.magic = WUFFS_BASE__DISABLED;
17083 return wuffs_base__make_status(wuffs_base__error__bad_argument);
17084 }
17085 if ((self->private_impl.active_coroutine != 0) &&
17086 (self->private_impl.active_coroutine != 1)) {
17087 self->private_impl.magic = WUFFS_BASE__DISABLED;
17088 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
17089 }
17090 self->private_impl.active_coroutine = 0;
17091 wuffs_base__status status = wuffs_base__make_status(NULL);
17092
17093 bool v_ffio = false;
17094
17095 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
17096 switch (coro_susp_point) {
17097 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
17098
17099 if (self->private_impl.f_call_sequence == 0) {
17100 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
17101 status = wuffs_gif__config_decoder__decode_header(self, a_src);
17102 if (status.repr) {
17103 goto suspend;
17104 }
17105 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
17106 status = wuffs_gif__config_decoder__decode_lsd(self, a_src);
17107 if (status.repr) {
17108 goto suspend;
17109 }
17110 } else if (self->private_impl.f_call_sequence != 2) {
17111 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
17112 goto exit;
17113 }
17114 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
17115 status = wuffs_gif__config_decoder__decode_up_to_id_part1(self, a_src);
17116 if (status.repr) {
17117 goto suspend;
17118 }
17119 v_ffio = ! self->private_impl.f_gc_has_transparent_index;
17120 if ( ! self->private_impl.f_quirks[2]) {
17121 v_ffio = (v_ffio &&
17122 (self->private_impl.f_frame_rect_x0 == 0) &&
17123 (self->private_impl.f_frame_rect_y0 == 0) &&
17124 (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
17125 (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
17126 } else if (v_ffio) {
17127 self->private_impl.f_black_color_u32_argb_premul = 4278190080;
17128 }
17129 if (self->private_impl.f_background_color_u32_argb_premul == 77) {
17130 self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
17131 }
17132 if (a_dst != NULL) {
17133 wuffs_base__image_config__set(
17134 a_dst,
17135 2198077448,
17136 0,
17137 self->private_impl.f_width,
17138 self->private_impl.f_height,
17139 self->private_impl.f_frame_config_io_position,
17140 v_ffio);
17141 }
17142 self->private_impl.f_call_sequence = 3;
17143
17144 goto ok;
17145 ok:
17146 self->private_impl.p_decode_image_config[0] = 0;
17147 goto exit;
17148 }
17149
17150 goto suspend;
17151 suspend:
17152 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
17153 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
17154
17155 goto exit;
17156 exit:
17157 if (wuffs_base__status__is_error(&status)) {
17158 self->private_impl.magic = WUFFS_BASE__DISABLED;
17159 }
17160 return status;
17161}
17162
17163// -------- func gif.config_decoder.set_report_metadata
17164
17165WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
17166wuffs_gif__config_decoder__set_report_metadata(
17167 wuffs_gif__config_decoder* self,
17168 uint32_t a_fourcc,
17169 bool a_report) {
17170 if (!self) {
17171 return wuffs_base__make_empty_struct();
17172 }
17173 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17174 return wuffs_base__make_empty_struct();
17175 }
17176
17177 if (a_fourcc == 1229144912) {
17178 self->private_impl.f_report_metadata_iccp = a_report;
17179 } else if (a_fourcc == 1481461792) {
17180 self->private_impl.f_report_metadata_xmp = a_report;
17181 }
17182 return wuffs_base__make_empty_struct();
17183}
17184
17185// -------- func gif.config_decoder.tell_me_more
17186
17187WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17188wuffs_gif__config_decoder__tell_me_more(
17189 wuffs_gif__config_decoder* self,
17190 wuffs_base__io_buffer* a_dst,
17191 wuffs_base__more_information* a_minfo,
17192 wuffs_base__io_buffer* a_src) {
17193 if (!self) {
17194 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17195 }
17196 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17197 return wuffs_base__make_status(
17198 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17199 ? wuffs_base__error__disabled_by_previous_error
17200 : wuffs_base__error__initialize_not_called);
17201 }
17202 if (!a_dst || !a_src) {
17203 self->private_impl.magic = WUFFS_BASE__DISABLED;
17204 return wuffs_base__make_status(wuffs_base__error__bad_argument);
17205 }
17206 if ((self->private_impl.active_coroutine != 0) &&
17207 (self->private_impl.active_coroutine != 2)) {
17208 self->private_impl.magic = WUFFS_BASE__DISABLED;
17209 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
17210 }
17211 self->private_impl.active_coroutine = 0;
17212 wuffs_base__status status = wuffs_base__make_status(NULL);
17213
17214 uint64_t v_chunk_length = 0;
17215
17216 const uint8_t* iop_a_src = NULL;
17217 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17218 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17219 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17220 if (a_src) {
17221 io0_a_src = a_src->data.ptr;
17222 io1_a_src = io0_a_src + a_src->meta.ri;
17223 iop_a_src = io1_a_src;
17224 io2_a_src = io0_a_src + a_src->meta.wi;
17225 }
17226
17227 uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
17228 switch (coro_susp_point) {
17229 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
17230
17231 if (self->private_impl.f_call_sequence != 1) {
17232 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
17233 goto exit;
17234 }
17235 if (self->private_impl.f_metadata_fourcc == 0) {
17236 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
17237 goto exit;
17238 }
17239 while (true) {
17240 label__0__continue:;
17241 while (true) {
17242 if (wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_io_position) {
17243 if (a_minfo != NULL) {
17244 wuffs_base__more_information__set(a_minfo,
17245 2,
17246 0,
17247 self->private_impl.f_metadata_io_position,
17248 0,
17249 0);
17250 }
17251 status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
17252 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
17253 goto label__0__continue;
17254 }
17255 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
17256 if (a_minfo != NULL) {
17257 wuffs_base__more_information__set(a_minfo,
17258 0,
17259 0,
17260 0,
17261 0,
17262 0);
17263 }
17264 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17265 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
17266 goto label__0__continue;
17267 }
17268 goto label__0__break;
17269 }
17270 label__0__break:;
17271 v_chunk_length = ((uint64_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src)));
17272 if (v_chunk_length <= 0) {
17273 (iop_a_src += 1, wuffs_base__make_empty_struct());
17274 goto label__1__break;
17275 }
17276 if (self->private_impl.f_metadata_fourcc == 1481461792) {
17277 v_chunk_length += 1;
17278 } else {
17279 (iop_a_src += 1, wuffs_base__make_empty_struct());
17280 }
17281 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src))), v_chunk_length);
17282 if (a_minfo != NULL) {
17283 wuffs_base__more_information__set(a_minfo,
17284 3,
17285 self->private_impl.f_metadata_fourcc,
17286 0,
17287 wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src))),
17288 self->private_impl.f_metadata_io_position);
17289 }
17290 status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
17291 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
17292 }
17293 label__1__break:;
17294 if (a_minfo != NULL) {
17295 wuffs_base__more_information__set(a_minfo,
17296 3,
17297 self->private_impl.f_metadata_fourcc,
17298 0,
17299 self->private_impl.f_metadata_io_position,
17300 self->private_impl.f_metadata_io_position);
17301 }
17302 self->private_impl.f_call_sequence = 2;
17303 self->private_impl.f_metadata_fourcc = 0;
17304 self->private_impl.f_metadata_io_position = 0;
17305 status = wuffs_base__make_status(NULL);
17306 goto ok;
17307
17308 goto ok;
17309 ok:
17310 self->private_impl.p_tell_me_more[0] = 0;
17311 goto exit;
17312 }
17313
17314 goto suspend;
17315 suspend:
17316 self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
17317 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
17318
17319 goto exit;
17320 exit:
17321 if (a_src) {
17322 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17323 }
17324
17325 if (wuffs_base__status__is_error(&status)) {
17326 self->private_impl.magic = WUFFS_BASE__DISABLED;
17327 }
17328 return status;
17329}
17330
17331// -------- func gif.config_decoder.num_animation_loops
17332
17333WUFFS_BASE__MAYBE_STATIC uint32_t
17334wuffs_gif__config_decoder__num_animation_loops(
17335 const wuffs_gif__config_decoder* self) {
17336 if (!self) {
17337 return 0;
17338 }
17339 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17340 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17341 return 0;
17342 }
17343
17344 if (self->private_impl.f_seen_num_loops) {
17345 return self->private_impl.f_num_loops;
17346 }
17347 return 1;
17348}
17349
17350// -------- func gif.config_decoder.num_decoded_frame_configs
17351
17352WUFFS_BASE__MAYBE_STATIC uint64_t
17353wuffs_gif__config_decoder__num_decoded_frame_configs(
17354 const wuffs_gif__config_decoder* self) {
17355 if (!self) {
17356 return 0;
17357 }
17358 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17359 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17360 return 0;
17361 }
17362
17363 return self->private_impl.f_num_decoded_frame_configs_value;
17364}
17365
17366// -------- func gif.config_decoder.num_decoded_frames
17367
17368WUFFS_BASE__MAYBE_STATIC uint64_t
17369wuffs_gif__config_decoder__num_decoded_frames(
17370 const wuffs_gif__config_decoder* self) {
17371 if (!self) {
17372 return 0;
17373 }
17374 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17375 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17376 return 0;
17377 }
17378
17379 return self->private_impl.f_num_decoded_frames_value;
17380}
17381
17382// -------- func gif.config_decoder.frame_dirty_rect
17383
17384WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
17385wuffs_gif__config_decoder__frame_dirty_rect(
17386 const wuffs_gif__config_decoder* self) {
17387 if (!self) {
17388 return wuffs_base__utility__empty_rect_ie_u32();
17389 }
17390 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17391 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17392 return wuffs_base__utility__empty_rect_ie_u32();
17393 }
17394
17395 return wuffs_base__utility__empty_rect_ie_u32();
17396}
17397
17398// -------- func gif.config_decoder.workbuf_len
17399
17400WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
17401wuffs_gif__config_decoder__workbuf_len(
17402 const wuffs_gif__config_decoder* self) {
17403 if (!self) {
17404 return wuffs_base__utility__empty_range_ii_u64();
17405 }
17406 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
17407 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
17408 return wuffs_base__utility__empty_range_ii_u64();
17409 }
17410
17411 return wuffs_base__utility__empty_range_ii_u64();
17412}
17413
17414// -------- func gif.config_decoder.restart_frame
17415
17416WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17417wuffs_gif__config_decoder__restart_frame(
17418 wuffs_gif__config_decoder* self,
17419 uint64_t a_index,
17420 uint64_t a_io_position) {
17421 if (!self) {
17422 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17423 }
17424 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17425 return wuffs_base__make_status(
17426 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17427 ? wuffs_base__error__disabled_by_previous_error
17428 : wuffs_base__error__initialize_not_called);
17429 }
17430
17431 if (self->private_impl.f_call_sequence == 0) {
17432 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
17433 }
17434 self->private_impl.f_delayed_num_decoded_frames = false;
17435 self->private_impl.f_end_of_data = false;
17436 self->private_impl.f_restarted = true;
17437 self->private_impl.f_frame_config_io_position = a_io_position;
17438 self->private_impl.f_num_decoded_frame_configs_value = a_index;
17439 self->private_impl.f_num_decoded_frames_value = a_index;
17440 wuffs_gif__config_decoder__reset_gc(self);
17441 return wuffs_base__make_status(NULL);
17442}
17443
17444// -------- func gif.config_decoder.decode_frame_config
17445
17446WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17447wuffs_gif__config_decoder__decode_frame_config(
17448 wuffs_gif__config_decoder* self,
17449 wuffs_base__frame_config* a_dst,
17450 wuffs_base__io_buffer* a_src) {
17451 if (!self) {
17452 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17453 }
17454 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17455 return wuffs_base__make_status(
17456 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17457 ? wuffs_base__error__disabled_by_previous_error
17458 : wuffs_base__error__initialize_not_called);
17459 }
17460 if (!a_src) {
17461 self->private_impl.magic = WUFFS_BASE__DISABLED;
17462 return wuffs_base__make_status(wuffs_base__error__bad_argument);
17463 }
17464 if ((self->private_impl.active_coroutine != 0) &&
17465 (self->private_impl.active_coroutine != 3)) {
17466 self->private_impl.magic = WUFFS_BASE__DISABLED;
17467 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
17468 }
17469 self->private_impl.active_coroutine = 0;
17470 wuffs_base__status status = wuffs_base__make_status(NULL);
17471
17472 uint32_t v_background_color = 0;
17473 uint8_t v_flags = 0;
17474
17475 const uint8_t* iop_a_src = NULL;
17476 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17477 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17478 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17479 if (a_src) {
17480 io0_a_src = a_src->data.ptr;
17481 io1_a_src = io0_a_src + a_src->meta.ri;
17482 iop_a_src = io1_a_src;
17483 io2_a_src = io0_a_src + a_src->meta.wi;
17484 }
17485
17486 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
17487 if (coro_susp_point) {
17488 v_background_color = self->private_data.s_decode_frame_config[0].v_background_color;
17489 }
17490 switch (coro_susp_point) {
17491 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
17492
17493 self->private_impl.f_ignore_metadata = true;
17494 if ( ! self->private_impl.f_end_of_data) {
17495 if (self->private_impl.f_call_sequence == 0) {
17496 if (a_src) {
17497 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17498 }
17499 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
17500 status = wuffs_gif__config_decoder__decode_image_config(self, NULL, a_src);
17501 if (a_src) {
17502 iop_a_src = a_src->data.ptr + a_src->meta.ri;
17503 }
17504 if (status.repr) {
17505 goto suspend;
17506 }
17507 } else if (self->private_impl.f_call_sequence != 3) {
17508 if (self->private_impl.f_call_sequence == 4) {
17509 if (a_src) {
17510 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17511 }
17512 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
17513 status = wuffs_gif__config_decoder__skip_frame(self, a_src);
17514 if (a_src) {
17515 iop_a_src = a_src->data.ptr + a_src->meta.ri;
17516 }
17517 if (status.repr) {
17518 goto suspend;
17519 }
17520 }
17521 if (a_src) {
17522 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17523 }
17524 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
17525 status = wuffs_gif__config_decoder__decode_up_to_id_part1(self, a_src);
17526 if (a_src) {
17527 iop_a_src = a_src->data.ptr + a_src->meta.ri;
17528 }
17529 if (status.repr) {
17530 goto suspend;
17531 }
17532 }
17533 }
17534 if (self->private_impl.f_end_of_data) {
17535 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
17536 goto ok;
17537 }
17538 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
17539 if ( ! self->private_impl.f_gc_has_transparent_index) {
17540 v_background_color = self->private_impl.f_background_color_u32_argb_premul;
17541 if (self->private_impl.f_quirks[1] && (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
17542 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
17543 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17544 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
17545 }
17546 v_flags = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
17547 if ((v_flags & 128) != 0) {
17548 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
17549 }
17550 }
17551 }
17552 if (a_dst != NULL) {
17553 wuffs_base__frame_config__set(
17554 a_dst,
17555 wuffs_base__utility__make_rect_ie_u32(
17556 wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
17557 wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
17558 wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
17559 wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
17560 ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
17561 self->private_impl.f_num_decoded_frame_configs_value,
17562 self->private_impl.f_frame_config_io_position,
17563 self->private_impl.f_gc_disposal,
17564 ! self->private_impl.f_gc_has_transparent_index,
17565 false,
17566 v_background_color);
17567 }
17568 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
17569 self->private_impl.f_call_sequence = 4;
17570
17571 goto ok;
17572 ok:
17573 self->private_impl.p_decode_frame_config[0] = 0;
17574 goto exit;
17575 }
17576
17577 goto suspend;
17578 suspend:
17579 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
17580 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
17581 self->private_data.s_decode_frame_config[0].v_background_color = v_background_color;
17582
17583 goto exit;
17584 exit:
17585 if (a_src) {
17586 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17587 }
17588
17589 if (wuffs_base__status__is_error(&status)) {
17590 self->private_impl.magic = WUFFS_BASE__DISABLED;
17591 }
17592 return status;
17593}
17594
17595// -------- func gif.config_decoder.skip_frame
17596
17597static wuffs_base__status
17598wuffs_gif__config_decoder__skip_frame(
17599 wuffs_gif__config_decoder* self,
17600 wuffs_base__io_buffer* a_src) {
17601 wuffs_base__status status = wuffs_base__make_status(NULL);
17602
17603 uint8_t v_flags = 0;
17604 uint8_t v_lw = 0;
17605
17606 const uint8_t* iop_a_src = NULL;
17607 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17608 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17609 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17610 if (a_src) {
17611 io0_a_src = a_src->data.ptr;
17612 io1_a_src = io0_a_src + a_src->meta.ri;
17613 iop_a_src = io1_a_src;
17614 io2_a_src = io0_a_src + a_src->meta.wi;
17615 }
17616
17617 uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
17618 switch (coro_susp_point) {
17619 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
17620
17621 {
17622 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
17623 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
17624 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17625 goto suspend;
17626 }
17627 uint8_t t_0 = *iop_a_src++;
17628 v_flags = t_0;
17629 }
17630 if ((v_flags & 128) != 0) {
17631 self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3)) << (1 + (v_flags & 7)));
17632 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
17633 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
17634 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
17635 iop_a_src = io2_a_src;
17636 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17637 goto suspend;
17638 }
17639 iop_a_src += self->private_data.s_skip_frame[0].scratch;
17640 }
17641 {
17642 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
17643 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
17644 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17645 goto suspend;
17646 }
17647 uint8_t t_1 = *iop_a_src++;
17648 v_lw = t_1;
17649 }
17650 if (v_lw > 8) {
17651 status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
17652 goto exit;
17653 }
17654 if (a_src) {
17655 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17656 }
17657 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
17658 status = wuffs_gif__config_decoder__skip_blocks(self, a_src);
17659 if (a_src) {
17660 iop_a_src = a_src->data.ptr + a_src->meta.ri;
17661 }
17662 if (status.repr) {
17663 goto suspend;
17664 }
17665 if (self->private_impl.f_quirks[0]) {
17666 self->private_impl.f_delayed_num_decoded_frames = true;
17667 } else {
17668 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
17669 }
17670 wuffs_gif__config_decoder__reset_gc(self);
17671
17672 goto ok;
17673 ok:
17674 self->private_impl.p_skip_frame[0] = 0;
17675 goto exit;
17676 }
17677
17678 goto suspend;
17679 suspend:
17680 self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
17681
17682 goto exit;
17683 exit:
17684 if (a_src) {
17685 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17686 }
17687
17688 return status;
17689}
17690
17691// -------- func gif.config_decoder.decode_frame
17692
17693WUFFS_BASE__MAYBE_STATIC wuffs_base__status
17694wuffs_gif__config_decoder__decode_frame(
17695 wuffs_gif__config_decoder* self,
17696 wuffs_base__pixel_buffer* a_dst,
17697 wuffs_base__io_buffer* a_src,
17698 wuffs_base__pixel_blend a_blend,
17699 wuffs_base__slice_u8 a_workbuf,
17700 wuffs_base__decode_frame_options* a_opts) {
17701 if (!self) {
17702 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
17703 }
17704 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
17705 return wuffs_base__make_status(
17706 (self->private_impl.magic == WUFFS_BASE__DISABLED)
17707 ? wuffs_base__error__disabled_by_previous_error
17708 : wuffs_base__error__initialize_not_called);
17709 }
17710 if (!a_dst || !a_src) {
17711 self->private_impl.magic = WUFFS_BASE__DISABLED;
17712 return wuffs_base__make_status(wuffs_base__error__bad_argument);
17713 }
17714 if ((self->private_impl.active_coroutine != 0) &&
17715 (self->private_impl.active_coroutine != 4)) {
17716 self->private_impl.magic = WUFFS_BASE__DISABLED;
17717 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
17718 }
17719 self->private_impl.active_coroutine = 0;
17720 wuffs_base__status status = wuffs_base__make_status(NULL);
17721
17722 status = wuffs_base__make_status(wuffs_base__error__unsupported_method);
17723 goto exit;
17724
17725 goto ok;
17726 ok:
17727 goto exit;
17728 exit:
17729 if (wuffs_base__status__is_error(&status)) {
17730 self->private_impl.magic = WUFFS_BASE__DISABLED;
17731 }
17732 return status;
17733}
17734
17735// -------- func gif.config_decoder.reset_gc
17736
17737static wuffs_base__empty_struct
17738wuffs_gif__config_decoder__reset_gc(
17739 wuffs_gif__config_decoder* self) {
17740 self->private_impl.f_call_sequence = 5;
17741 self->private_impl.f_gc_has_transparent_index = false;
17742 self->private_impl.f_gc_transparent_index = 0;
17743 self->private_impl.f_gc_disposal = 0;
17744 self->private_impl.f_gc_duration = 0;
17745 return wuffs_base__make_empty_struct();
17746}
17747
17748// -------- func gif.config_decoder.decode_up_to_id_part1
17749
17750static wuffs_base__status
17751wuffs_gif__config_decoder__decode_up_to_id_part1(
17752 wuffs_gif__config_decoder* self,
17753 wuffs_base__io_buffer* a_src) {
17754 wuffs_base__status status = wuffs_base__make_status(NULL);
17755
17756 uint8_t v_block_type = 0;
17757
17758 const uint8_t* iop_a_src = NULL;
17759 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17760 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17761 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17762 if (a_src) {
17763 io0_a_src = a_src->data.ptr;
17764 io1_a_src = io0_a_src + a_src->meta.ri;
17765 iop_a_src = io1_a_src;
17766 io2_a_src = io0_a_src + a_src->meta.wi;
17767 }
17768
17769 uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
17770 switch (coro_susp_point) {
17771 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
17772
17773 if ( ! self->private_impl.f_restarted) {
17774 if (self->private_impl.f_call_sequence != 2) {
17775 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
17776 }
17777 } else if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)))) {
17778 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
17779 goto exit;
17780 } else {
17781 self->private_impl.f_restarted = false;
17782 }
17783 while (true) {
17784 {
17785 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
17786 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
17787 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17788 goto suspend;
17789 }
17790 uint8_t t_0 = *iop_a_src++;
17791 v_block_type = t_0;
17792 }
17793 if (v_block_type == 33) {
17794 if (a_src) {
17795 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17796 }
17797 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
17798 status = wuffs_gif__config_decoder__decode_extension(self, a_src);
17799 if (a_src) {
17800 iop_a_src = a_src->data.ptr + a_src->meta.ri;
17801 }
17802 if (status.repr) {
17803 goto suspend;
17804 }
17805 } else if (v_block_type == 44) {
17806 if (self->private_impl.f_delayed_num_decoded_frames) {
17807 self->private_impl.f_delayed_num_decoded_frames = false;
17808 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
17809 }
17810 if (a_src) {
17811 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17812 }
17813 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
17814 status = wuffs_gif__config_decoder__decode_id_part0(self, a_src);
17815 if (a_src) {
17816 iop_a_src = a_src->data.ptr + a_src->meta.ri;
17817 }
17818 if (status.repr) {
17819 goto suspend;
17820 }
17821 goto label__0__break;
17822 } else {
17823 if (self->private_impl.f_delayed_num_decoded_frames) {
17824 self->private_impl.f_delayed_num_decoded_frames = false;
17825 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
17826 }
17827 self->private_impl.f_end_of_data = true;
17828 goto label__0__break;
17829 }
17830 }
17831 label__0__break:;
17832
17833 goto ok;
17834 ok:
17835 self->private_impl.p_decode_up_to_id_part1[0] = 0;
17836 goto exit;
17837 }
17838
17839 goto suspend;
17840 suspend:
17841 self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
17842
17843 goto exit;
17844 exit:
17845 if (a_src) {
17846 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17847 }
17848
17849 return status;
17850}
17851
17852// -------- func gif.config_decoder.decode_header
17853
17854static wuffs_base__status
17855wuffs_gif__config_decoder__decode_header(
17856 wuffs_gif__config_decoder* self,
17857 wuffs_base__io_buffer* a_src) {
17858 wuffs_base__status status = wuffs_base__make_status(NULL);
17859
17860 uint8_t v_c[6] = {0};
17861 uint32_t v_i = 0;
17862
17863 const uint8_t* iop_a_src = NULL;
17864 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17865 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17866 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17867 if (a_src) {
17868 io0_a_src = a_src->data.ptr;
17869 io1_a_src = io0_a_src + a_src->meta.ri;
17870 iop_a_src = io1_a_src;
17871 io2_a_src = io0_a_src + a_src->meta.wi;
17872 }
17873
17874 uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
17875 if (coro_susp_point) {
17876 memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
17877 v_i = self->private_data.s_decode_header[0].v_i;
17878 }
17879 switch (coro_susp_point) {
17880 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
17881
17882 while (v_i < 6) {
17883 {
17884 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
17885 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
17886 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17887 goto suspend;
17888 }
17889 uint8_t t_0 = *iop_a_src++;
17890 v_c[v_i] = t_0;
17891 }
17892 v_i += 1;
17893 }
17894 if ((v_c[0] != 71) ||
17895 (v_c[1] != 73) ||
17896 (v_c[2] != 70) ||
17897 (v_c[3] != 56) ||
17898 ((v_c[4] != 55) && (v_c[4] != 57)) ||
17899 (v_c[5] != 97)) {
17900 status = wuffs_base__make_status(wuffs_gif__error__bad_header);
17901 goto exit;
17902 }
17903
17904 goto ok;
17905 ok:
17906 self->private_impl.p_decode_header[0] = 0;
17907 goto exit;
17908 }
17909
17910 goto suspend;
17911 suspend:
17912 self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
17913 memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
17914 self->private_data.s_decode_header[0].v_i = v_i;
17915
17916 goto exit;
17917 exit:
17918 if (a_src) {
17919 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
17920 }
17921
17922 return status;
17923}
17924
17925// -------- func gif.config_decoder.decode_lsd
17926
17927static wuffs_base__status
17928wuffs_gif__config_decoder__decode_lsd(
17929 wuffs_gif__config_decoder* self,
17930 wuffs_base__io_buffer* a_src) {
17931 wuffs_base__status status = wuffs_base__make_status(NULL);
17932
17933 uint8_t v_flags = 0;
17934 uint8_t v_background_color_index = 0;
17935 uint32_t v_num_palette_entries = 0;
17936 uint32_t v_i = 0;
17937 uint32_t v_j = 0;
17938 uint32_t v_argb = 0;
17939
17940 const uint8_t* iop_a_src = NULL;
17941 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17942 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17943 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
17944 if (a_src) {
17945 io0_a_src = a_src->data.ptr;
17946 io1_a_src = io0_a_src + a_src->meta.ri;
17947 iop_a_src = io1_a_src;
17948 io2_a_src = io0_a_src + a_src->meta.wi;
17949 }
17950
17951 uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
17952 if (coro_susp_point) {
17953 v_flags = self->private_data.s_decode_lsd[0].v_flags;
17954 v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index;
17955 v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries;
17956 v_i = self->private_data.s_decode_lsd[0].v_i;
17957 }
17958 switch (coro_susp_point) {
17959 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
17960
17961 {
17962 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
17963 uint32_t t_0;
17964 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
17965 t_0 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
17966 iop_a_src += 2;
17967 } else {
17968 self->private_data.s_decode_lsd[0].scratch = 0;
17969 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
17970 while (true) {
17971 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
17972 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
17973 goto suspend;
17974 }
17975 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
17976 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
17977 *scratch <<= 8;
17978 *scratch >>= 8;
17979 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
17980 if (num_bits_0 == 8) {
17981 t_0 = ((uint32_t)(*scratch));
17982 break;
17983 }
17984 num_bits_0 += 8;
17985 *scratch |= ((uint64_t)(num_bits_0)) << 56;
17986 }
17987 }
17988 self->private_impl.f_width = t_0;
17989 }
17990 {
17991 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
17992 uint32_t t_1;
17993 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
17994 t_1 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
17995 iop_a_src += 2;
17996 } else {
17997 self->private_data.s_decode_lsd[0].scratch = 0;
17998 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
17999 while (true) {
18000 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18001 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18002 goto suspend;
18003 }
18004 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
18005 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
18006 *scratch <<= 8;
18007 *scratch >>= 8;
18008 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
18009 if (num_bits_1 == 8) {
18010 t_1 = ((uint32_t)(*scratch));
18011 break;
18012 }
18013 num_bits_1 += 8;
18014 *scratch |= ((uint64_t)(num_bits_1)) << 56;
18015 }
18016 }
18017 self->private_impl.f_height = t_1;
18018 }
18019 {
18020 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
18021 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18022 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18023 goto suspend;
18024 }
18025 uint8_t t_2 = *iop_a_src++;
18026 v_flags = t_2;
18027 }
18028 {
18029 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
18030 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18031 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18032 goto suspend;
18033 }
18034 uint8_t t_3 = *iop_a_src++;
18035 v_background_color_index = t_3;
18036 }
18037 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
18038 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18039 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18040 goto suspend;
18041 }
18042 iop_a_src++;
18043 v_i = 0;
18044 self->private_impl.f_has_global_palette = ((v_flags & 128) != 0);
18045 if (self->private_impl.f_has_global_palette) {
18046 v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
18047 while (v_i < v_num_palette_entries) {
18048 {
18049 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
18050 uint32_t t_4;
18051 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
18052 t_4 = ((uint32_t)(wuffs_base__load_u24be__no_bounds_check(iop_a_src)));
18053 iop_a_src += 3;
18054 } else {
18055 self->private_data.s_decode_lsd[0].scratch = 0;
18056 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
18057 while (true) {
18058 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18059 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18060 goto suspend;
18061 }
18062 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
18063 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
18064 *scratch >>= 8;
18065 *scratch <<= 8;
18066 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
18067 if (num_bits_4 == 16) {
18068 t_4 = ((uint32_t)(*scratch >> 40));
18069 break;
18070 }
18071 num_bits_4 += 8;
18072 *scratch |= ((uint64_t)(num_bits_4));
18073 }
18074 }
18075 v_argb = t_4;
18076 }
18077 v_argb |= 4278190080;
18078 self->private_data.f_palettes[0][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
18079 self->private_data.f_palettes[0][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
18080 self->private_data.f_palettes[0][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
18081 self->private_data.f_palettes[0][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
18082 v_i += 1;
18083 }
18084 if (self->private_impl.f_quirks[2]) {
18085 if ((v_background_color_index != 0) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
18086 v_j = (4 * ((uint32_t)(v_background_color_index)));
18087 self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0][(v_j + 0)])) << 0) |
18088 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 1)])) << 8) |
18089 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 2)])) << 16) |
18090 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 3)])) << 24));
18091 } else {
18092 self->private_impl.f_background_color_u32_argb_premul = 77;
18093 }
18094 }
18095 }
18096 while (v_i < 256) {
18097 self->private_data.f_palettes[0][((4 * v_i) + 0)] = 0;
18098 self->private_data.f_palettes[0][((4 * v_i) + 1)] = 0;
18099 self->private_data.f_palettes[0][((4 * v_i) + 2)] = 0;
18100 self->private_data.f_palettes[0][((4 * v_i) + 3)] = 255;
18101 v_i += 1;
18102 }
18103
18104 goto ok;
18105 ok:
18106 self->private_impl.p_decode_lsd[0] = 0;
18107 goto exit;
18108 }
18109
18110 goto suspend;
18111 suspend:
18112 self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
18113 self->private_data.s_decode_lsd[0].v_flags = v_flags;
18114 self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index;
18115 self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries;
18116 self->private_data.s_decode_lsd[0].v_i = v_i;
18117
18118 goto exit;
18119 exit:
18120 if (a_src) {
18121 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18122 }
18123
18124 return status;
18125}
18126
18127// -------- func gif.config_decoder.decode_extension
18128
18129static wuffs_base__status
18130wuffs_gif__config_decoder__decode_extension(
18131 wuffs_gif__config_decoder* self,
18132 wuffs_base__io_buffer* a_src) {
18133 wuffs_base__status status = wuffs_base__make_status(NULL);
18134
18135 uint8_t v_label = 0;
18136
18137 const uint8_t* iop_a_src = NULL;
18138 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18139 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18140 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18141 if (a_src) {
18142 io0_a_src = a_src->data.ptr;
18143 io1_a_src = io0_a_src + a_src->meta.ri;
18144 iop_a_src = io1_a_src;
18145 io2_a_src = io0_a_src + a_src->meta.wi;
18146 }
18147
18148 uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
18149 switch (coro_susp_point) {
18150 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
18151
18152 {
18153 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
18154 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18155 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18156 goto suspend;
18157 }
18158 uint8_t t_0 = *iop_a_src++;
18159 v_label = t_0;
18160 }
18161 if (v_label == 249) {
18162 if (a_src) {
18163 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18164 }
18165 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
18166 status = wuffs_gif__config_decoder__decode_gc(self, a_src);
18167 if (a_src) {
18168 iop_a_src = a_src->data.ptr + a_src->meta.ri;
18169 }
18170 if (status.repr) {
18171 goto suspend;
18172 }
18173 status = wuffs_base__make_status(NULL);
18174 goto ok;
18175 } else if (v_label == 255) {
18176 if (a_src) {
18177 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18178 }
18179 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
18180 status = wuffs_gif__config_decoder__decode_ae(self, a_src);
18181 if (a_src) {
18182 iop_a_src = a_src->data.ptr + a_src->meta.ri;
18183 }
18184 if (status.repr) {
18185 goto suspend;
18186 }
18187 status = wuffs_base__make_status(NULL);
18188 goto ok;
18189 }
18190 if (a_src) {
18191 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18192 }
18193 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
18194 status = wuffs_gif__config_decoder__skip_blocks(self, a_src);
18195 if (a_src) {
18196 iop_a_src = a_src->data.ptr + a_src->meta.ri;
18197 }
18198 if (status.repr) {
18199 goto suspend;
18200 }
18201
18202 goto ok;
18203 ok:
18204 self->private_impl.p_decode_extension[0] = 0;
18205 goto exit;
18206 }
18207
18208 goto suspend;
18209 suspend:
18210 self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
18211
18212 goto exit;
18213 exit:
18214 if (a_src) {
18215 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18216 }
18217
18218 return status;
18219}
18220
18221// -------- func gif.config_decoder.skip_blocks
18222
18223static wuffs_base__status
18224wuffs_gif__config_decoder__skip_blocks(
18225 wuffs_gif__config_decoder* self,
18226 wuffs_base__io_buffer* a_src) {
18227 wuffs_base__status status = wuffs_base__make_status(NULL);
18228
18229 uint8_t v_block_size = 0;
18230
18231 const uint8_t* iop_a_src = NULL;
18232 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18233 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18234 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18235 if (a_src) {
18236 io0_a_src = a_src->data.ptr;
18237 io1_a_src = io0_a_src + a_src->meta.ri;
18238 iop_a_src = io1_a_src;
18239 io2_a_src = io0_a_src + a_src->meta.wi;
18240 }
18241
18242 uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
18243 switch (coro_susp_point) {
18244 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
18245
18246 while (true) {
18247 {
18248 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
18249 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18250 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18251 goto suspend;
18252 }
18253 uint8_t t_0 = *iop_a_src++;
18254 v_block_size = t_0;
18255 }
18256 if (v_block_size == 0) {
18257 status = wuffs_base__make_status(NULL);
18258 goto ok;
18259 }
18260 self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
18261 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
18262 if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
18263 self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
18264 iop_a_src = io2_a_src;
18265 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18266 goto suspend;
18267 }
18268 iop_a_src += self->private_data.s_skip_blocks[0].scratch;
18269 }
18270
18271 goto ok;
18272 ok:
18273 self->private_impl.p_skip_blocks[0] = 0;
18274 goto exit;
18275 }
18276
18277 goto suspend;
18278 suspend:
18279 self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
18280
18281 goto exit;
18282 exit:
18283 if (a_src) {
18284 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18285 }
18286
18287 return status;
18288}
18289
18290// -------- func gif.config_decoder.decode_ae
18291
18292static wuffs_base__status
18293wuffs_gif__config_decoder__decode_ae(
18294 wuffs_gif__config_decoder* self,
18295 wuffs_base__io_buffer* a_src) {
18296 wuffs_base__status status = wuffs_base__make_status(NULL);
18297
18298 uint8_t v_c = 0;
18299 uint8_t v_block_size = 0;
18300 bool v_is_animexts = false;
18301 bool v_is_netscape = false;
18302 bool v_is_iccp = false;
18303 bool v_is_xmp = false;
18304
18305 const uint8_t* iop_a_src = NULL;
18306 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18307 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18308 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18309 if (a_src) {
18310 io0_a_src = a_src->data.ptr;
18311 io1_a_src = io0_a_src + a_src->meta.ri;
18312 iop_a_src = io1_a_src;
18313 io2_a_src = io0_a_src + a_src->meta.wi;
18314 }
18315
18316 uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
18317 if (coro_susp_point) {
18318 v_block_size = self->private_data.s_decode_ae[0].v_block_size;
18319 v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
18320 v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
18321 v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
18322 v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
18323 }
18324 switch (coro_susp_point) {
18325 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
18326
18327 while (true) {
18328 if (self->private_impl.f_metadata_fourcc != 0) {
18329 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
18330 goto ok;
18331 }
18332 {
18333 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
18334 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18335 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18336 goto suspend;
18337 }
18338 uint8_t t_0 = *iop_a_src++;
18339 v_block_size = t_0;
18340 }
18341 if (v_block_size == 0) {
18342 status = wuffs_base__make_status(NULL);
18343 goto ok;
18344 }
18345 if (v_block_size != 11) {
18346 self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
18347 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
18348 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
18349 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
18350 iop_a_src = io2_a_src;
18351 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18352 goto suspend;
18353 }
18354 iop_a_src += self->private_data.s_decode_ae[0].scratch;
18355 goto label__goto_done__break;
18356 }
18357 v_is_animexts = true;
18358 v_is_netscape = true;
18359 v_is_iccp = true;
18360 v_is_xmp = true;
18361 v_block_size = 0;
18362 while (v_block_size < 11) {
18363 {
18364 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
18365 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18366 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18367 goto suspend;
18368 }
18369 uint8_t t_1 = *iop_a_src++;
18370 v_c = t_1;
18371 }
18372 v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
18373 v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
18374 v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size]));
18375 v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size]));
18376#if defined(__GNUC__)
18377#pragma GCC diagnostic push
18378#pragma GCC diagnostic ignored "-Wconversion"
18379#endif
18380 v_block_size += 1;
18381#if defined(__GNUC__)
18382#pragma GCC diagnostic pop
18383#endif
18384 }
18385 if (v_is_animexts || v_is_netscape) {
18386 {
18387 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
18388 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18389 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18390 goto suspend;
18391 }
18392 uint8_t t_2 = *iop_a_src++;
18393 v_block_size = t_2;
18394 }
18395 if (v_block_size != 3) {
18396 self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
18397 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
18398 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
18399 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
18400 iop_a_src = io2_a_src;
18401 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18402 goto suspend;
18403 }
18404 iop_a_src += self->private_data.s_decode_ae[0].scratch;
18405 goto label__goto_done__break;
18406 }
18407 {
18408 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
18409 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18410 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18411 goto suspend;
18412 }
18413 uint8_t t_3 = *iop_a_src++;
18414 v_c = t_3;
18415 }
18416 if (v_c != 1) {
18417 self->private_data.s_decode_ae[0].scratch = 2;
18418 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
18419 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
18420 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
18421 iop_a_src = io2_a_src;
18422 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18423 goto suspend;
18424 }
18425 iop_a_src += self->private_data.s_decode_ae[0].scratch;
18426 goto label__goto_done__break;
18427 }
18428 {
18429 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
18430 uint32_t t_4;
18431 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
18432 t_4 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
18433 iop_a_src += 2;
18434 } else {
18435 self->private_data.s_decode_ae[0].scratch = 0;
18436 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
18437 while (true) {
18438 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18439 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18440 goto suspend;
18441 }
18442 uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
18443 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
18444 *scratch <<= 8;
18445 *scratch >>= 8;
18446 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
18447 if (num_bits_4 == 8) {
18448 t_4 = ((uint32_t)(*scratch));
18449 break;
18450 }
18451 num_bits_4 += 8;
18452 *scratch |= ((uint64_t)(num_bits_4)) << 56;
18453 }
18454 }
18455 self->private_impl.f_num_loops = t_4;
18456 }
18457 self->private_impl.f_seen_num_loops = true;
18458 if ((0 < self->private_impl.f_num_loops) && (self->private_impl.f_num_loops <= 65535)) {
18459 self->private_impl.f_num_loops += 1;
18460 }
18461 } else if (self->private_impl.f_ignore_metadata) {
18462 } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
18463 self->private_impl.f_metadata_fourcc = 1229144912;
18464 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
18465 self->private_impl.f_call_sequence = 1;
18466 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
18467 goto ok;
18468 } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
18469 self->private_impl.f_metadata_fourcc = 1481461792;
18470 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
18471 self->private_impl.f_call_sequence = 1;
18472 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
18473 goto ok;
18474 }
18475 goto label__goto_done__break;
18476 }
18477 label__goto_done__break:;
18478 if (a_src) {
18479 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18480 }
18481 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
18482 status = wuffs_gif__config_decoder__skip_blocks(self, a_src);
18483 if (a_src) {
18484 iop_a_src = a_src->data.ptr + a_src->meta.ri;
18485 }
18486 if (status.repr) {
18487 goto suspend;
18488 }
18489
18490 goto ok;
18491 ok:
18492 self->private_impl.p_decode_ae[0] = 0;
18493 goto exit;
18494 }
18495
18496 goto suspend;
18497 suspend:
18498 self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
18499 self->private_data.s_decode_ae[0].v_block_size = v_block_size;
18500 self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
18501 self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
18502 self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
18503 self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
18504
18505 goto exit;
18506 exit:
18507 if (a_src) {
18508 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18509 }
18510
18511 return status;
18512}
18513
18514// -------- func gif.config_decoder.decode_gc
18515
18516static wuffs_base__status
18517wuffs_gif__config_decoder__decode_gc(
18518 wuffs_gif__config_decoder* self,
18519 wuffs_base__io_buffer* a_src) {
18520 wuffs_base__status status = wuffs_base__make_status(NULL);
18521
18522 uint8_t v_c = 0;
18523 uint8_t v_flags = 0;
18524 uint16_t v_gc_duration_centiseconds = 0;
18525
18526 const uint8_t* iop_a_src = NULL;
18527 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18528 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18529 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18530 if (a_src) {
18531 io0_a_src = a_src->data.ptr;
18532 io1_a_src = io0_a_src + a_src->meta.ri;
18533 iop_a_src = io1_a_src;
18534 io2_a_src = io0_a_src + a_src->meta.wi;
18535 }
18536
18537 uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
18538 switch (coro_susp_point) {
18539 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
18540
18541 {
18542 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
18543 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18544 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18545 goto suspend;
18546 }
18547 uint8_t t_0 = *iop_a_src++;
18548 v_c = t_0;
18549 }
18550 if (v_c != 4) {
18551 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
18552 goto exit;
18553 }
18554 {
18555 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
18556 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18557 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18558 goto suspend;
18559 }
18560 uint8_t t_1 = *iop_a_src++;
18561 v_flags = t_1;
18562 }
18563 self->private_impl.f_gc_has_transparent_index = ((v_flags & 1) != 0);
18564 v_flags = ((v_flags >> 2) & 7);
18565 if (v_flags == 2) {
18566 self->private_impl.f_gc_disposal = 1;
18567 } else if ((v_flags == 3) || (v_flags == 4)) {
18568 self->private_impl.f_gc_disposal = 2;
18569 } else {
18570 self->private_impl.f_gc_disposal = 0;
18571 }
18572 {
18573 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
18574 uint16_t t_2;
18575 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
18576 t_2 = wuffs_base__load_u16le__no_bounds_check(iop_a_src);
18577 iop_a_src += 2;
18578 } else {
18579 self->private_data.s_decode_gc[0].scratch = 0;
18580 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
18581 while (true) {
18582 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18583 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18584 goto suspend;
18585 }
18586 uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
18587 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
18588 *scratch <<= 8;
18589 *scratch >>= 8;
18590 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
18591 if (num_bits_2 == 8) {
18592 t_2 = ((uint16_t)(*scratch));
18593 break;
18594 }
18595 num_bits_2 += 8;
18596 *scratch |= ((uint64_t)(num_bits_2)) << 56;
18597 }
18598 }
18599 v_gc_duration_centiseconds = t_2;
18600 }
18601 self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000);
18602 {
18603 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
18604 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18605 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18606 goto suspend;
18607 }
18608 uint8_t t_3 = *iop_a_src++;
18609 self->private_impl.f_gc_transparent_index = t_3;
18610 }
18611 {
18612 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
18613 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18614 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18615 goto suspend;
18616 }
18617 uint8_t t_4 = *iop_a_src++;
18618 v_c = t_4;
18619 }
18620 if (v_c != 0) {
18621 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
18622 goto exit;
18623 }
18624
18625 goto ok;
18626 ok:
18627 self->private_impl.p_decode_gc[0] = 0;
18628 goto exit;
18629 }
18630
18631 goto suspend;
18632 suspend:
18633 self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
18634
18635 goto exit;
18636 exit:
18637 if (a_src) {
18638 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18639 }
18640
18641 return status;
18642}
18643
18644// -------- func gif.config_decoder.decode_id_part0
18645
18646static wuffs_base__status
18647wuffs_gif__config_decoder__decode_id_part0(
18648 wuffs_gif__config_decoder* self,
18649 wuffs_base__io_buffer* a_src) {
18650 wuffs_base__status status = wuffs_base__make_status(NULL);
18651
18652 const uint8_t* iop_a_src = NULL;
18653 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18654 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18655 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18656 if (a_src) {
18657 io0_a_src = a_src->data.ptr;
18658 io1_a_src = io0_a_src + a_src->meta.ri;
18659 iop_a_src = io1_a_src;
18660 io2_a_src = io0_a_src + a_src->meta.wi;
18661 }
18662
18663 uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
18664 switch (coro_susp_point) {
18665 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
18666
18667 {
18668 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
18669 uint32_t t_0;
18670 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
18671 t_0 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
18672 iop_a_src += 2;
18673 } else {
18674 self->private_data.s_decode_id_part0[0].scratch = 0;
18675 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
18676 while (true) {
18677 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18678 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18679 goto suspend;
18680 }
18681 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
18682 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
18683 *scratch <<= 8;
18684 *scratch >>= 8;
18685 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
18686 if (num_bits_0 == 8) {
18687 t_0 = ((uint32_t)(*scratch));
18688 break;
18689 }
18690 num_bits_0 += 8;
18691 *scratch |= ((uint64_t)(num_bits_0)) << 56;
18692 }
18693 }
18694 self->private_impl.f_frame_rect_x0 = t_0;
18695 }
18696 {
18697 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
18698 uint32_t t_1;
18699 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
18700 t_1 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
18701 iop_a_src += 2;
18702 } else {
18703 self->private_data.s_decode_id_part0[0].scratch = 0;
18704 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
18705 while (true) {
18706 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18707 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18708 goto suspend;
18709 }
18710 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
18711 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
18712 *scratch <<= 8;
18713 *scratch >>= 8;
18714 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
18715 if (num_bits_1 == 8) {
18716 t_1 = ((uint32_t)(*scratch));
18717 break;
18718 }
18719 num_bits_1 += 8;
18720 *scratch |= ((uint64_t)(num_bits_1)) << 56;
18721 }
18722 }
18723 self->private_impl.f_frame_rect_y0 = t_1;
18724 }
18725 {
18726 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
18727 uint32_t t_2;
18728 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
18729 t_2 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
18730 iop_a_src += 2;
18731 } else {
18732 self->private_data.s_decode_id_part0[0].scratch = 0;
18733 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
18734 while (true) {
18735 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18736 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18737 goto suspend;
18738 }
18739 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
18740 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
18741 *scratch <<= 8;
18742 *scratch >>= 8;
18743 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
18744 if (num_bits_2 == 8) {
18745 t_2 = ((uint32_t)(*scratch));
18746 break;
18747 }
18748 num_bits_2 += 8;
18749 *scratch |= ((uint64_t)(num_bits_2)) << 56;
18750 }
18751 }
18752 self->private_impl.f_frame_rect_x1 = t_2;
18753 }
18754 self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
18755 {
18756 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
18757 uint32_t t_3;
18758 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
18759 t_3 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
18760 iop_a_src += 2;
18761 } else {
18762 self->private_data.s_decode_id_part0[0].scratch = 0;
18763 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
18764 while (true) {
18765 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
18766 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
18767 goto suspend;
18768 }
18769 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
18770 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
18771 *scratch <<= 8;
18772 *scratch >>= 8;
18773 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
18774 if (num_bits_3 == 8) {
18775 t_3 = ((uint32_t)(*scratch));
18776 break;
18777 }
18778 num_bits_3 += 8;
18779 *scratch |= ((uint64_t)(num_bits_3)) << 56;
18780 }
18781 }
18782 self->private_impl.f_frame_rect_y1 = t_3;
18783 }
18784 self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
18785 if ((self->private_impl.f_call_sequence == 0) && ! self->private_impl.f_quirks[4]) {
18786 self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
18787 self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
18788 }
18789
18790 goto ok;
18791 ok:
18792 self->private_impl.p_decode_id_part0[0] = 0;
18793 goto exit;
18794 }
18795
18796 goto suspend;
18797 suspend:
18798 self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
18799
18800 goto exit;
18801 exit:
18802 if (a_src) {
18803 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
18804 }
18805
18806 return status;
18807}
18808
18809// -------- func gif.decoder.set_quirk_enabled
18810
18811WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
18812wuffs_gif__decoder__set_quirk_enabled(
18813 wuffs_gif__decoder* self,
18814 uint32_t a_quirk,
18815 bool a_enabled) {
18816 if (!self) {
18817 return wuffs_base__make_empty_struct();
18818 }
18819 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18820 return wuffs_base__make_empty_struct();
18821 }
18822
18823 if ((self->private_impl.f_call_sequence == 0) && (a_quirk >= 1041635328)) {
18824 a_quirk -= 1041635328;
18825 if (a_quirk < 7) {
18826 self->private_impl.f_quirks[a_quirk] = a_enabled;
18827 }
18828 }
18829 return wuffs_base__make_empty_struct();
18830}
18831
18832// -------- func gif.decoder.decode_image_config
18833
18834WUFFS_BASE__MAYBE_STATIC wuffs_base__status
18835wuffs_gif__decoder__decode_image_config(
18836 wuffs_gif__decoder* self,
18837 wuffs_base__image_config* a_dst,
18838 wuffs_base__io_buffer* a_src) {
18839 if (!self) {
18840 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
18841 }
18842 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18843 return wuffs_base__make_status(
18844 (self->private_impl.magic == WUFFS_BASE__DISABLED)
18845 ? wuffs_base__error__disabled_by_previous_error
18846 : wuffs_base__error__initialize_not_called);
18847 }
18848 if (!a_src) {
18849 self->private_impl.magic = WUFFS_BASE__DISABLED;
18850 return wuffs_base__make_status(wuffs_base__error__bad_argument);
18851 }
18852 if ((self->private_impl.active_coroutine != 0) &&
18853 (self->private_impl.active_coroutine != 1)) {
18854 self->private_impl.magic = WUFFS_BASE__DISABLED;
18855 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
18856 }
18857 self->private_impl.active_coroutine = 0;
18858 wuffs_base__status status = wuffs_base__make_status(NULL);
18859
18860 bool v_ffio = false;
18861
18862 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
18863 switch (coro_susp_point) {
18864 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
18865
18866 if (self->private_impl.f_call_sequence == 0) {
18867 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
18868 status = wuffs_gif__decoder__decode_header(self, a_src);
18869 if (status.repr) {
18870 goto suspend;
18871 }
18872 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
18873 status = wuffs_gif__decoder__decode_lsd(self, a_src);
18874 if (status.repr) {
18875 goto suspend;
18876 }
18877 } else if (self->private_impl.f_call_sequence != 2) {
18878 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
18879 goto exit;
18880 }
18881 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
18882 status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
18883 if (status.repr) {
18884 goto suspend;
18885 }
18886 v_ffio = ! self->private_impl.f_gc_has_transparent_index;
18887 if ( ! self->private_impl.f_quirks[2]) {
18888 v_ffio = (v_ffio &&
18889 (self->private_impl.f_frame_rect_x0 == 0) &&
18890 (self->private_impl.f_frame_rect_y0 == 0) &&
18891 (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
18892 (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
18893 } else if (v_ffio) {
18894 self->private_impl.f_black_color_u32_argb_premul = 4278190080;
18895 }
18896 if (self->private_impl.f_background_color_u32_argb_premul == 77) {
18897 self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
18898 }
18899 if (a_dst != NULL) {
18900 wuffs_base__image_config__set(
18901 a_dst,
18902 2198077448,
18903 0,
18904 self->private_impl.f_width,
18905 self->private_impl.f_height,
18906 self->private_impl.f_frame_config_io_position,
18907 v_ffio);
18908 }
18909 self->private_impl.f_call_sequence = 3;
18910
18911 goto ok;
18912 ok:
18913 self->private_impl.p_decode_image_config[0] = 0;
18914 goto exit;
18915 }
18916
18917 goto suspend;
18918 suspend:
18919 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
18920 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
18921
18922 goto exit;
18923 exit:
18924 if (wuffs_base__status__is_error(&status)) {
18925 self->private_impl.magic = WUFFS_BASE__DISABLED;
18926 }
18927 return status;
18928}
18929
18930// -------- func gif.decoder.set_report_metadata
18931
18932WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
18933wuffs_gif__decoder__set_report_metadata(
18934 wuffs_gif__decoder* self,
18935 uint32_t a_fourcc,
18936 bool a_report) {
18937 if (!self) {
18938 return wuffs_base__make_empty_struct();
18939 }
18940 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18941 return wuffs_base__make_empty_struct();
18942 }
18943
18944 if (a_fourcc == 1229144912) {
18945 self->private_impl.f_report_metadata_iccp = a_report;
18946 } else if (a_fourcc == 1481461792) {
18947 self->private_impl.f_report_metadata_xmp = a_report;
18948 }
18949 return wuffs_base__make_empty_struct();
18950}
18951
18952// -------- func gif.decoder.tell_me_more
18953
18954WUFFS_BASE__MAYBE_STATIC wuffs_base__status
18955wuffs_gif__decoder__tell_me_more(
18956 wuffs_gif__decoder* self,
18957 wuffs_base__io_buffer* a_dst,
18958 wuffs_base__more_information* a_minfo,
18959 wuffs_base__io_buffer* a_src) {
18960 if (!self) {
18961 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
18962 }
18963 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
18964 return wuffs_base__make_status(
18965 (self->private_impl.magic == WUFFS_BASE__DISABLED)
18966 ? wuffs_base__error__disabled_by_previous_error
18967 : wuffs_base__error__initialize_not_called);
18968 }
18969 if (!a_dst || !a_src) {
18970 self->private_impl.magic = WUFFS_BASE__DISABLED;
18971 return wuffs_base__make_status(wuffs_base__error__bad_argument);
18972 }
18973 if ((self->private_impl.active_coroutine != 0) &&
18974 (self->private_impl.active_coroutine != 2)) {
18975 self->private_impl.magic = WUFFS_BASE__DISABLED;
18976 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
18977 }
18978 self->private_impl.active_coroutine = 0;
18979 wuffs_base__status status = wuffs_base__make_status(NULL);
18980
18981 uint64_t v_chunk_length = 0;
18982
18983 const uint8_t* iop_a_src = NULL;
18984 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18985 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18986 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
18987 if (a_src) {
18988 io0_a_src = a_src->data.ptr;
18989 io1_a_src = io0_a_src + a_src->meta.ri;
18990 iop_a_src = io1_a_src;
18991 io2_a_src = io0_a_src + a_src->meta.wi;
18992 }
18993
18994 uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
18995 switch (coro_susp_point) {
18996 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
18997
18998 if (self->private_impl.f_call_sequence != 1) {
18999 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
19000 goto exit;
19001 }
19002 if (self->private_impl.f_metadata_fourcc == 0) {
19003 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
19004 goto exit;
19005 }
19006 while (true) {
19007 label__0__continue:;
19008 while (true) {
19009 if (wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_io_position) {
19010 if (a_minfo != NULL) {
19011 wuffs_base__more_information__set(a_minfo,
19012 2,
19013 0,
19014 self->private_impl.f_metadata_io_position,
19015 0,
19016 0);
19017 }
19018 status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
19019 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
19020 goto label__0__continue;
19021 }
19022 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
19023 if (a_minfo != NULL) {
19024 wuffs_base__more_information__set(a_minfo,
19025 0,
19026 0,
19027 0,
19028 0,
19029 0);
19030 }
19031 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19032 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
19033 goto label__0__continue;
19034 }
19035 goto label__0__break;
19036 }
19037 label__0__break:;
19038 v_chunk_length = ((uint64_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src)));
19039 if (v_chunk_length <= 0) {
19040 (iop_a_src += 1, wuffs_base__make_empty_struct());
19041 goto label__1__break;
19042 }
19043 if (self->private_impl.f_metadata_fourcc == 1481461792) {
19044 v_chunk_length += 1;
19045 } else {
19046 (iop_a_src += 1, wuffs_base__make_empty_struct());
19047 }
19048 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src))), v_chunk_length);
19049 if (a_minfo != NULL) {
19050 wuffs_base__more_information__set(a_minfo,
19051 3,
19052 self->private_impl.f_metadata_fourcc,
19053 0,
19054 wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src))),
19055 self->private_impl.f_metadata_io_position);
19056 }
19057 status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
19058 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
19059 }
19060 label__1__break:;
19061 if (a_minfo != NULL) {
19062 wuffs_base__more_information__set(a_minfo,
19063 3,
19064 self->private_impl.f_metadata_fourcc,
19065 0,
19066 self->private_impl.f_metadata_io_position,
19067 self->private_impl.f_metadata_io_position);
19068 }
19069 self->private_impl.f_call_sequence = 2;
19070 self->private_impl.f_metadata_fourcc = 0;
19071 self->private_impl.f_metadata_io_position = 0;
19072 status = wuffs_base__make_status(NULL);
19073 goto ok;
19074
19075 goto ok;
19076 ok:
19077 self->private_impl.p_tell_me_more[0] = 0;
19078 goto exit;
19079 }
19080
19081 goto suspend;
19082 suspend:
19083 self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
19084 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
19085
19086 goto exit;
19087 exit:
19088 if (a_src) {
19089 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19090 }
19091
19092 if (wuffs_base__status__is_error(&status)) {
19093 self->private_impl.magic = WUFFS_BASE__DISABLED;
19094 }
19095 return status;
19096}
19097
19098// -------- func gif.decoder.num_animation_loops
19099
19100WUFFS_BASE__MAYBE_STATIC uint32_t
19101wuffs_gif__decoder__num_animation_loops(
19102 const wuffs_gif__decoder* self) {
19103 if (!self) {
19104 return 0;
19105 }
19106 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
19107 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
19108 return 0;
19109 }
19110
19111 if (self->private_impl.f_seen_num_loops) {
19112 return self->private_impl.f_num_loops;
19113 }
19114 return 1;
19115}
19116
19117// -------- func gif.decoder.num_decoded_frame_configs
19118
19119WUFFS_BASE__MAYBE_STATIC uint64_t
19120wuffs_gif__decoder__num_decoded_frame_configs(
19121 const wuffs_gif__decoder* self) {
19122 if (!self) {
19123 return 0;
19124 }
19125 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
19126 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
19127 return 0;
19128 }
19129
19130 return self->private_impl.f_num_decoded_frame_configs_value;
19131}
19132
19133// -------- func gif.decoder.num_decoded_frames
19134
19135WUFFS_BASE__MAYBE_STATIC uint64_t
19136wuffs_gif__decoder__num_decoded_frames(
19137 const wuffs_gif__decoder* self) {
19138 if (!self) {
19139 return 0;
19140 }
19141 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
19142 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
19143 return 0;
19144 }
19145
19146 return self->private_impl.f_num_decoded_frames_value;
19147}
19148
19149// -------- func gif.decoder.frame_dirty_rect
19150
19151WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
19152wuffs_gif__decoder__frame_dirty_rect(
19153 const wuffs_gif__decoder* self) {
19154 if (!self) {
19155 return wuffs_base__utility__empty_rect_ie_u32();
19156 }
19157 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
19158 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
19159 return wuffs_base__utility__empty_rect_ie_u32();
19160 }
19161
19162 return wuffs_base__utility__make_rect_ie_u32(
19163 wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
19164 wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
19165 wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
19166 wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height));
19167}
19168
19169// -------- func gif.decoder.workbuf_len
19170
19171WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
19172wuffs_gif__decoder__workbuf_len(
19173 const wuffs_gif__decoder* self) {
19174 if (!self) {
19175 return wuffs_base__utility__empty_range_ii_u64();
19176 }
19177 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
19178 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
19179 return wuffs_base__utility__empty_range_ii_u64();
19180 }
19181
19182 return wuffs_base__utility__make_range_ii_u64(0, 0);
19183}
19184
19185// -------- func gif.decoder.restart_frame
19186
19187WUFFS_BASE__MAYBE_STATIC wuffs_base__status
19188wuffs_gif__decoder__restart_frame(
19189 wuffs_gif__decoder* self,
19190 uint64_t a_index,
19191 uint64_t a_io_position) {
19192 if (!self) {
19193 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
19194 }
19195 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
19196 return wuffs_base__make_status(
19197 (self->private_impl.magic == WUFFS_BASE__DISABLED)
19198 ? wuffs_base__error__disabled_by_previous_error
19199 : wuffs_base__error__initialize_not_called);
19200 }
19201
19202 if (self->private_impl.f_call_sequence == 0) {
19203 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
19204 }
19205 self->private_impl.f_delayed_num_decoded_frames = false;
19206 self->private_impl.f_end_of_data = false;
19207 self->private_impl.f_restarted = true;
19208 self->private_impl.f_frame_config_io_position = a_io_position;
19209 self->private_impl.f_num_decoded_frame_configs_value = a_index;
19210 self->private_impl.f_num_decoded_frames_value = a_index;
19211 wuffs_gif__decoder__reset_gc(self);
19212 return wuffs_base__make_status(NULL);
19213}
19214
19215// -------- func gif.decoder.decode_frame_config
19216
19217WUFFS_BASE__MAYBE_STATIC wuffs_base__status
19218wuffs_gif__decoder__decode_frame_config(
19219 wuffs_gif__decoder* self,
19220 wuffs_base__frame_config* a_dst,
19221 wuffs_base__io_buffer* a_src) {
19222 if (!self) {
19223 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
19224 }
19225 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
19226 return wuffs_base__make_status(
19227 (self->private_impl.magic == WUFFS_BASE__DISABLED)
19228 ? wuffs_base__error__disabled_by_previous_error
19229 : wuffs_base__error__initialize_not_called);
19230 }
19231 if (!a_src) {
19232 self->private_impl.magic = WUFFS_BASE__DISABLED;
19233 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19234 }
19235 if ((self->private_impl.active_coroutine != 0) &&
19236 (self->private_impl.active_coroutine != 3)) {
19237 self->private_impl.magic = WUFFS_BASE__DISABLED;
19238 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
19239 }
19240 self->private_impl.active_coroutine = 0;
19241 wuffs_base__status status = wuffs_base__make_status(NULL);
19242
19243 uint32_t v_background_color = 0;
19244 uint8_t v_flags = 0;
19245
19246 const uint8_t* iop_a_src = NULL;
19247 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19248 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19249 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19250 if (a_src) {
19251 io0_a_src = a_src->data.ptr;
19252 io1_a_src = io0_a_src + a_src->meta.ri;
19253 iop_a_src = io1_a_src;
19254 io2_a_src = io0_a_src + a_src->meta.wi;
19255 }
19256
19257 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
19258 if (coro_susp_point) {
19259 v_background_color = self->private_data.s_decode_frame_config[0].v_background_color;
19260 }
19261 switch (coro_susp_point) {
19262 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
19263
19264 self->private_impl.f_ignore_metadata = true;
19265 self->private_impl.f_dirty_max_excl_y = 0;
19266 if ( ! self->private_impl.f_end_of_data) {
19267 if (self->private_impl.f_call_sequence == 0) {
19268 if (a_src) {
19269 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19270 }
19271 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
19272 status = wuffs_gif__decoder__decode_image_config(self, NULL, a_src);
19273 if (a_src) {
19274 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19275 }
19276 if (status.repr) {
19277 goto suspend;
19278 }
19279 } else if (self->private_impl.f_call_sequence != 3) {
19280 if (self->private_impl.f_call_sequence == 4) {
19281 if (a_src) {
19282 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19283 }
19284 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
19285 status = wuffs_gif__decoder__skip_frame(self, a_src);
19286 if (a_src) {
19287 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19288 }
19289 if (status.repr) {
19290 goto suspend;
19291 }
19292 }
19293 if (a_src) {
19294 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19295 }
19296 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
19297 status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
19298 if (a_src) {
19299 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19300 }
19301 if (status.repr) {
19302 goto suspend;
19303 }
19304 }
19305 }
19306 if (self->private_impl.f_end_of_data) {
19307 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
19308 goto ok;
19309 }
19310 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
19311 if ( ! self->private_impl.f_gc_has_transparent_index) {
19312 v_background_color = self->private_impl.f_background_color_u32_argb_premul;
19313 if (self->private_impl.f_quirks[1] && (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
19314 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
19315 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19316 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
19317 }
19318 v_flags = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
19319 if ((v_flags & 128) != 0) {
19320 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
19321 }
19322 }
19323 }
19324 if (a_dst != NULL) {
19325 wuffs_base__frame_config__set(
19326 a_dst,
19327 wuffs_base__utility__make_rect_ie_u32(
19328 wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
19329 wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
19330 wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
19331 wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
19332 ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
19333 self->private_impl.f_num_decoded_frame_configs_value,
19334 self->private_impl.f_frame_config_io_position,
19335 self->private_impl.f_gc_disposal,
19336 ! self->private_impl.f_gc_has_transparent_index,
19337 false,
19338 v_background_color);
19339 }
19340 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
19341 self->private_impl.f_call_sequence = 4;
19342
19343 goto ok;
19344 ok:
19345 self->private_impl.p_decode_frame_config[0] = 0;
19346 goto exit;
19347 }
19348
19349 goto suspend;
19350 suspend:
19351 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
19352 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
19353 self->private_data.s_decode_frame_config[0].v_background_color = v_background_color;
19354
19355 goto exit;
19356 exit:
19357 if (a_src) {
19358 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19359 }
19360
19361 if (wuffs_base__status__is_error(&status)) {
19362 self->private_impl.magic = WUFFS_BASE__DISABLED;
19363 }
19364 return status;
19365}
19366
19367// -------- func gif.decoder.skip_frame
19368
19369static wuffs_base__status
19370wuffs_gif__decoder__skip_frame(
19371 wuffs_gif__decoder* self,
19372 wuffs_base__io_buffer* a_src) {
19373 wuffs_base__status status = wuffs_base__make_status(NULL);
19374
19375 uint8_t v_flags = 0;
19376 uint8_t v_lw = 0;
19377
19378 const uint8_t* iop_a_src = NULL;
19379 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19380 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19381 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19382 if (a_src) {
19383 io0_a_src = a_src->data.ptr;
19384 io1_a_src = io0_a_src + a_src->meta.ri;
19385 iop_a_src = io1_a_src;
19386 io2_a_src = io0_a_src + a_src->meta.wi;
19387 }
19388
19389 uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
19390 switch (coro_susp_point) {
19391 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
19392
19393 {
19394 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
19395 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19396 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19397 goto suspend;
19398 }
19399 uint8_t t_0 = *iop_a_src++;
19400 v_flags = t_0;
19401 }
19402 if ((v_flags & 128) != 0) {
19403 self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3)) << (1 + (v_flags & 7)));
19404 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
19405 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
19406 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
19407 iop_a_src = io2_a_src;
19408 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19409 goto suspend;
19410 }
19411 iop_a_src += self->private_data.s_skip_frame[0].scratch;
19412 }
19413 {
19414 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
19415 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19416 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19417 goto suspend;
19418 }
19419 uint8_t t_1 = *iop_a_src++;
19420 v_lw = t_1;
19421 }
19422 if (v_lw > 8) {
19423 status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
19424 goto exit;
19425 }
19426 if (a_src) {
19427 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19428 }
19429 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
19430 status = wuffs_gif__decoder__skip_blocks(self, a_src);
19431 if (a_src) {
19432 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19433 }
19434 if (status.repr) {
19435 goto suspend;
19436 }
19437 if (self->private_impl.f_quirks[0]) {
19438 self->private_impl.f_delayed_num_decoded_frames = true;
19439 } else {
19440 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
19441 }
19442 wuffs_gif__decoder__reset_gc(self);
19443
19444 goto ok;
19445 ok:
19446 self->private_impl.p_skip_frame[0] = 0;
19447 goto exit;
19448 }
19449
19450 goto suspend;
19451 suspend:
19452 self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
19453
19454 goto exit;
19455 exit:
19456 if (a_src) {
19457 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19458 }
19459
19460 return status;
19461}
19462
19463// -------- func gif.decoder.decode_frame
19464
19465WUFFS_BASE__MAYBE_STATIC wuffs_base__status
19466wuffs_gif__decoder__decode_frame(
19467 wuffs_gif__decoder* self,
19468 wuffs_base__pixel_buffer* a_dst,
19469 wuffs_base__io_buffer* a_src,
19470 wuffs_base__pixel_blend a_blend,
19471 wuffs_base__slice_u8 a_workbuf,
19472 wuffs_base__decode_frame_options* a_opts) {
19473 if (!self) {
19474 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
19475 }
19476 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
19477 return wuffs_base__make_status(
19478 (self->private_impl.magic == WUFFS_BASE__DISABLED)
19479 ? wuffs_base__error__disabled_by_previous_error
19480 : wuffs_base__error__initialize_not_called);
19481 }
19482 if (!a_dst || !a_src) {
19483 self->private_impl.magic = WUFFS_BASE__DISABLED;
19484 return wuffs_base__make_status(wuffs_base__error__bad_argument);
19485 }
19486 if ((self->private_impl.active_coroutine != 0) &&
19487 (self->private_impl.active_coroutine != 4)) {
19488 self->private_impl.magic = WUFFS_BASE__DISABLED;
19489 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
19490 }
19491 self->private_impl.active_coroutine = 0;
19492 wuffs_base__status status = wuffs_base__make_status(NULL);
19493
19494 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
19495 switch (coro_susp_point) {
19496 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
19497
19498 self->private_impl.f_ignore_metadata = true;
19499 if (self->private_impl.f_call_sequence != 4) {
19500 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
19501 status = wuffs_gif__decoder__decode_frame_config(self, NULL, a_src);
19502 if (status.repr) {
19503 goto suspend;
19504 }
19505 }
19506 if (self->private_impl.f_quirks[5] && ((self->private_impl.f_frame_rect_x0 == self->private_impl.f_frame_rect_x1) || (self->private_impl.f_frame_rect_y0 == self->private_impl.f_frame_rect_y1))) {
19507 status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size);
19508 goto exit;
19509 }
19510 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
19511 status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
19512 if (status.repr) {
19513 goto suspend;
19514 }
19515 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
19516 status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
19517 if (status.repr) {
19518 goto suspend;
19519 }
19520 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
19521 wuffs_gif__decoder__reset_gc(self);
19522
19523 goto ok;
19524 ok:
19525 self->private_impl.p_decode_frame[0] = 0;
19526 goto exit;
19527 }
19528
19529 goto suspend;
19530 suspend:
19531 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
19532 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
19533
19534 goto exit;
19535 exit:
19536 if (wuffs_base__status__is_error(&status)) {
19537 self->private_impl.magic = WUFFS_BASE__DISABLED;
19538 }
19539 return status;
19540}
19541
19542// -------- func gif.decoder.reset_gc
19543
19544static wuffs_base__empty_struct
19545wuffs_gif__decoder__reset_gc(
19546 wuffs_gif__decoder* self) {
19547 self->private_impl.f_call_sequence = 5;
19548 self->private_impl.f_gc_has_transparent_index = false;
19549 self->private_impl.f_gc_transparent_index = 0;
19550 self->private_impl.f_gc_disposal = 0;
19551 self->private_impl.f_gc_duration = 0;
19552 return wuffs_base__make_empty_struct();
19553}
19554
19555// -------- func gif.decoder.decode_up_to_id_part1
19556
19557static wuffs_base__status
19558wuffs_gif__decoder__decode_up_to_id_part1(
19559 wuffs_gif__decoder* self,
19560 wuffs_base__io_buffer* a_src) {
19561 wuffs_base__status status = wuffs_base__make_status(NULL);
19562
19563 uint8_t v_block_type = 0;
19564
19565 const uint8_t* iop_a_src = NULL;
19566 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19567 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19568 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19569 if (a_src) {
19570 io0_a_src = a_src->data.ptr;
19571 io1_a_src = io0_a_src + a_src->meta.ri;
19572 iop_a_src = io1_a_src;
19573 io2_a_src = io0_a_src + a_src->meta.wi;
19574 }
19575
19576 uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
19577 switch (coro_susp_point) {
19578 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
19579
19580 if ( ! self->private_impl.f_restarted) {
19581 if (self->private_impl.f_call_sequence != 2) {
19582 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
19583 }
19584 } else if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)))) {
19585 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
19586 goto exit;
19587 } else {
19588 self->private_impl.f_restarted = false;
19589 }
19590 while (true) {
19591 {
19592 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
19593 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19594 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19595 goto suspend;
19596 }
19597 uint8_t t_0 = *iop_a_src++;
19598 v_block_type = t_0;
19599 }
19600 if (v_block_type == 33) {
19601 if (a_src) {
19602 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19603 }
19604 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
19605 status = wuffs_gif__decoder__decode_extension(self, a_src);
19606 if (a_src) {
19607 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19608 }
19609 if (status.repr) {
19610 goto suspend;
19611 }
19612 } else if (v_block_type == 44) {
19613 if (self->private_impl.f_delayed_num_decoded_frames) {
19614 self->private_impl.f_delayed_num_decoded_frames = false;
19615 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
19616 }
19617 if (a_src) {
19618 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19619 }
19620 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
19621 status = wuffs_gif__decoder__decode_id_part0(self, a_src);
19622 if (a_src) {
19623 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19624 }
19625 if (status.repr) {
19626 goto suspend;
19627 }
19628 goto label__0__break;
19629 } else {
19630 if (self->private_impl.f_delayed_num_decoded_frames) {
19631 self->private_impl.f_delayed_num_decoded_frames = false;
19632 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
19633 }
19634 self->private_impl.f_end_of_data = true;
19635 goto label__0__break;
19636 }
19637 }
19638 label__0__break:;
19639
19640 goto ok;
19641 ok:
19642 self->private_impl.p_decode_up_to_id_part1[0] = 0;
19643 goto exit;
19644 }
19645
19646 goto suspend;
19647 suspend:
19648 self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
19649
19650 goto exit;
19651 exit:
19652 if (a_src) {
19653 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19654 }
19655
19656 return status;
19657}
19658
19659// -------- func gif.decoder.decode_header
19660
19661static wuffs_base__status
19662wuffs_gif__decoder__decode_header(
19663 wuffs_gif__decoder* self,
19664 wuffs_base__io_buffer* a_src) {
19665 wuffs_base__status status = wuffs_base__make_status(NULL);
19666
19667 uint8_t v_c[6] = {0};
19668 uint32_t v_i = 0;
19669
19670 const uint8_t* iop_a_src = NULL;
19671 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19672 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19673 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19674 if (a_src) {
19675 io0_a_src = a_src->data.ptr;
19676 io1_a_src = io0_a_src + a_src->meta.ri;
19677 iop_a_src = io1_a_src;
19678 io2_a_src = io0_a_src + a_src->meta.wi;
19679 }
19680
19681 uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
19682 if (coro_susp_point) {
19683 memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
19684 v_i = self->private_data.s_decode_header[0].v_i;
19685 }
19686 switch (coro_susp_point) {
19687 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
19688
19689 while (v_i < 6) {
19690 {
19691 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
19692 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19693 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19694 goto suspend;
19695 }
19696 uint8_t t_0 = *iop_a_src++;
19697 v_c[v_i] = t_0;
19698 }
19699 v_i += 1;
19700 }
19701 if ((v_c[0] != 71) ||
19702 (v_c[1] != 73) ||
19703 (v_c[2] != 70) ||
19704 (v_c[3] != 56) ||
19705 ((v_c[4] != 55) && (v_c[4] != 57)) ||
19706 (v_c[5] != 97)) {
19707 status = wuffs_base__make_status(wuffs_gif__error__bad_header);
19708 goto exit;
19709 }
19710
19711 goto ok;
19712 ok:
19713 self->private_impl.p_decode_header[0] = 0;
19714 goto exit;
19715 }
19716
19717 goto suspend;
19718 suspend:
19719 self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
19720 memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
19721 self->private_data.s_decode_header[0].v_i = v_i;
19722
19723 goto exit;
19724 exit:
19725 if (a_src) {
19726 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19727 }
19728
19729 return status;
19730}
19731
19732// -------- func gif.decoder.decode_lsd
19733
19734static wuffs_base__status
19735wuffs_gif__decoder__decode_lsd(
19736 wuffs_gif__decoder* self,
19737 wuffs_base__io_buffer* a_src) {
19738 wuffs_base__status status = wuffs_base__make_status(NULL);
19739
19740 uint8_t v_flags = 0;
19741 uint8_t v_background_color_index = 0;
19742 uint32_t v_num_palette_entries = 0;
19743 uint32_t v_i = 0;
19744 uint32_t v_j = 0;
19745 uint32_t v_argb = 0;
19746
19747 const uint8_t* iop_a_src = NULL;
19748 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19749 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19750 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19751 if (a_src) {
19752 io0_a_src = a_src->data.ptr;
19753 io1_a_src = io0_a_src + a_src->meta.ri;
19754 iop_a_src = io1_a_src;
19755 io2_a_src = io0_a_src + a_src->meta.wi;
19756 }
19757
19758 uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
19759 if (coro_susp_point) {
19760 v_flags = self->private_data.s_decode_lsd[0].v_flags;
19761 v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index;
19762 v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries;
19763 v_i = self->private_data.s_decode_lsd[0].v_i;
19764 }
19765 switch (coro_susp_point) {
19766 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
19767
19768 {
19769 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
19770 uint32_t t_0;
19771 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
19772 t_0 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
19773 iop_a_src += 2;
19774 } else {
19775 self->private_data.s_decode_lsd[0].scratch = 0;
19776 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
19777 while (true) {
19778 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19779 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19780 goto suspend;
19781 }
19782 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
19783 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
19784 *scratch <<= 8;
19785 *scratch >>= 8;
19786 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
19787 if (num_bits_0 == 8) {
19788 t_0 = ((uint32_t)(*scratch));
19789 break;
19790 }
19791 num_bits_0 += 8;
19792 *scratch |= ((uint64_t)(num_bits_0)) << 56;
19793 }
19794 }
19795 self->private_impl.f_width = t_0;
19796 }
19797 {
19798 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
19799 uint32_t t_1;
19800 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
19801 t_1 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
19802 iop_a_src += 2;
19803 } else {
19804 self->private_data.s_decode_lsd[0].scratch = 0;
19805 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
19806 while (true) {
19807 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19808 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19809 goto suspend;
19810 }
19811 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
19812 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
19813 *scratch <<= 8;
19814 *scratch >>= 8;
19815 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
19816 if (num_bits_1 == 8) {
19817 t_1 = ((uint32_t)(*scratch));
19818 break;
19819 }
19820 num_bits_1 += 8;
19821 *scratch |= ((uint64_t)(num_bits_1)) << 56;
19822 }
19823 }
19824 self->private_impl.f_height = t_1;
19825 }
19826 {
19827 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
19828 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19829 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19830 goto suspend;
19831 }
19832 uint8_t t_2 = *iop_a_src++;
19833 v_flags = t_2;
19834 }
19835 {
19836 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
19837 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19838 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19839 goto suspend;
19840 }
19841 uint8_t t_3 = *iop_a_src++;
19842 v_background_color_index = t_3;
19843 }
19844 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
19845 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19846 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19847 goto suspend;
19848 }
19849 iop_a_src++;
19850 v_i = 0;
19851 self->private_impl.f_has_global_palette = ((v_flags & 128) != 0);
19852 if (self->private_impl.f_has_global_palette) {
19853 v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
19854 while (v_i < v_num_palette_entries) {
19855 {
19856 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
19857 uint32_t t_4;
19858 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
19859 t_4 = ((uint32_t)(wuffs_base__load_u24be__no_bounds_check(iop_a_src)));
19860 iop_a_src += 3;
19861 } else {
19862 self->private_data.s_decode_lsd[0].scratch = 0;
19863 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
19864 while (true) {
19865 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19866 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19867 goto suspend;
19868 }
19869 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
19870 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
19871 *scratch >>= 8;
19872 *scratch <<= 8;
19873 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
19874 if (num_bits_4 == 16) {
19875 t_4 = ((uint32_t)(*scratch >> 40));
19876 break;
19877 }
19878 num_bits_4 += 8;
19879 *scratch |= ((uint64_t)(num_bits_4));
19880 }
19881 }
19882 v_argb = t_4;
19883 }
19884 v_argb |= 4278190080;
19885 self->private_data.f_palettes[0][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
19886 self->private_data.f_palettes[0][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
19887 self->private_data.f_palettes[0][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
19888 self->private_data.f_palettes[0][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
19889 v_i += 1;
19890 }
19891 if (self->private_impl.f_quirks[2]) {
19892 if ((v_background_color_index != 0) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
19893 v_j = (4 * ((uint32_t)(v_background_color_index)));
19894 self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0][(v_j + 0)])) << 0) |
19895 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 1)])) << 8) |
19896 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 2)])) << 16) |
19897 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 3)])) << 24));
19898 } else {
19899 self->private_impl.f_background_color_u32_argb_premul = 77;
19900 }
19901 }
19902 }
19903 while (v_i < 256) {
19904 self->private_data.f_palettes[0][((4 * v_i) + 0)] = 0;
19905 self->private_data.f_palettes[0][((4 * v_i) + 1)] = 0;
19906 self->private_data.f_palettes[0][((4 * v_i) + 2)] = 0;
19907 self->private_data.f_palettes[0][((4 * v_i) + 3)] = 255;
19908 v_i += 1;
19909 }
19910
19911 goto ok;
19912 ok:
19913 self->private_impl.p_decode_lsd[0] = 0;
19914 goto exit;
19915 }
19916
19917 goto suspend;
19918 suspend:
19919 self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
19920 self->private_data.s_decode_lsd[0].v_flags = v_flags;
19921 self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index;
19922 self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries;
19923 self->private_data.s_decode_lsd[0].v_i = v_i;
19924
19925 goto exit;
19926 exit:
19927 if (a_src) {
19928 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19929 }
19930
19931 return status;
19932}
19933
19934// -------- func gif.decoder.decode_extension
19935
19936static wuffs_base__status
19937wuffs_gif__decoder__decode_extension(
19938 wuffs_gif__decoder* self,
19939 wuffs_base__io_buffer* a_src) {
19940 wuffs_base__status status = wuffs_base__make_status(NULL);
19941
19942 uint8_t v_label = 0;
19943
19944 const uint8_t* iop_a_src = NULL;
19945 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19946 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19947 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
19948 if (a_src) {
19949 io0_a_src = a_src->data.ptr;
19950 io1_a_src = io0_a_src + a_src->meta.ri;
19951 iop_a_src = io1_a_src;
19952 io2_a_src = io0_a_src + a_src->meta.wi;
19953 }
19954
19955 uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
19956 switch (coro_susp_point) {
19957 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
19958
19959 {
19960 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
19961 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
19962 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
19963 goto suspend;
19964 }
19965 uint8_t t_0 = *iop_a_src++;
19966 v_label = t_0;
19967 }
19968 if (v_label == 249) {
19969 if (a_src) {
19970 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19971 }
19972 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
19973 status = wuffs_gif__decoder__decode_gc(self, a_src);
19974 if (a_src) {
19975 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19976 }
19977 if (status.repr) {
19978 goto suspend;
19979 }
19980 status = wuffs_base__make_status(NULL);
19981 goto ok;
19982 } else if (v_label == 255) {
19983 if (a_src) {
19984 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19985 }
19986 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
19987 status = wuffs_gif__decoder__decode_ae(self, a_src);
19988 if (a_src) {
19989 iop_a_src = a_src->data.ptr + a_src->meta.ri;
19990 }
19991 if (status.repr) {
19992 goto suspend;
19993 }
19994 status = wuffs_base__make_status(NULL);
19995 goto ok;
19996 }
19997 if (a_src) {
19998 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
19999 }
20000 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
20001 status = wuffs_gif__decoder__skip_blocks(self, a_src);
20002 if (a_src) {
20003 iop_a_src = a_src->data.ptr + a_src->meta.ri;
20004 }
20005 if (status.repr) {
20006 goto suspend;
20007 }
20008
20009 goto ok;
20010 ok:
20011 self->private_impl.p_decode_extension[0] = 0;
20012 goto exit;
20013 }
20014
20015 goto suspend;
20016 suspend:
20017 self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
20018
20019 goto exit;
20020 exit:
20021 if (a_src) {
20022 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20023 }
20024
20025 return status;
20026}
20027
20028// -------- func gif.decoder.skip_blocks
20029
20030static wuffs_base__status
20031wuffs_gif__decoder__skip_blocks(
20032 wuffs_gif__decoder* self,
20033 wuffs_base__io_buffer* a_src) {
20034 wuffs_base__status status = wuffs_base__make_status(NULL);
20035
20036 uint8_t v_block_size = 0;
20037
20038 const uint8_t* iop_a_src = NULL;
20039 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20040 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20041 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20042 if (a_src) {
20043 io0_a_src = a_src->data.ptr;
20044 io1_a_src = io0_a_src + a_src->meta.ri;
20045 iop_a_src = io1_a_src;
20046 io2_a_src = io0_a_src + a_src->meta.wi;
20047 }
20048
20049 uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
20050 switch (coro_susp_point) {
20051 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
20052
20053 while (true) {
20054 {
20055 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
20056 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20057 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20058 goto suspend;
20059 }
20060 uint8_t t_0 = *iop_a_src++;
20061 v_block_size = t_0;
20062 }
20063 if (v_block_size == 0) {
20064 status = wuffs_base__make_status(NULL);
20065 goto ok;
20066 }
20067 self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
20068 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
20069 if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
20070 self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
20071 iop_a_src = io2_a_src;
20072 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20073 goto suspend;
20074 }
20075 iop_a_src += self->private_data.s_skip_blocks[0].scratch;
20076 }
20077
20078 goto ok;
20079 ok:
20080 self->private_impl.p_skip_blocks[0] = 0;
20081 goto exit;
20082 }
20083
20084 goto suspend;
20085 suspend:
20086 self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
20087
20088 goto exit;
20089 exit:
20090 if (a_src) {
20091 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20092 }
20093
20094 return status;
20095}
20096
20097// -------- func gif.decoder.decode_ae
20098
20099static wuffs_base__status
20100wuffs_gif__decoder__decode_ae(
20101 wuffs_gif__decoder* self,
20102 wuffs_base__io_buffer* a_src) {
20103 wuffs_base__status status = wuffs_base__make_status(NULL);
20104
20105 uint8_t v_c = 0;
20106 uint8_t v_block_size = 0;
20107 bool v_is_animexts = false;
20108 bool v_is_netscape = false;
20109 bool v_is_iccp = false;
20110 bool v_is_xmp = false;
20111
20112 const uint8_t* iop_a_src = NULL;
20113 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20114 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20115 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20116 if (a_src) {
20117 io0_a_src = a_src->data.ptr;
20118 io1_a_src = io0_a_src + a_src->meta.ri;
20119 iop_a_src = io1_a_src;
20120 io2_a_src = io0_a_src + a_src->meta.wi;
20121 }
20122
20123 uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
20124 if (coro_susp_point) {
20125 v_block_size = self->private_data.s_decode_ae[0].v_block_size;
20126 v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
20127 v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
20128 v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
20129 v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
20130 }
20131 switch (coro_susp_point) {
20132 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
20133
20134 while (true) {
20135 if (self->private_impl.f_metadata_fourcc != 0) {
20136 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
20137 goto ok;
20138 }
20139 {
20140 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
20141 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20142 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20143 goto suspend;
20144 }
20145 uint8_t t_0 = *iop_a_src++;
20146 v_block_size = t_0;
20147 }
20148 if (v_block_size == 0) {
20149 status = wuffs_base__make_status(NULL);
20150 goto ok;
20151 }
20152 if (v_block_size != 11) {
20153 self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
20154 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
20155 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
20156 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
20157 iop_a_src = io2_a_src;
20158 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20159 goto suspend;
20160 }
20161 iop_a_src += self->private_data.s_decode_ae[0].scratch;
20162 goto label__goto_done__break;
20163 }
20164 v_is_animexts = true;
20165 v_is_netscape = true;
20166 v_is_iccp = true;
20167 v_is_xmp = true;
20168 v_block_size = 0;
20169 while (v_block_size < 11) {
20170 {
20171 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
20172 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20173 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20174 goto suspend;
20175 }
20176 uint8_t t_1 = *iop_a_src++;
20177 v_c = t_1;
20178 }
20179 v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
20180 v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
20181 v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size]));
20182 v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size]));
20183#if defined(__GNUC__)
20184#pragma GCC diagnostic push
20185#pragma GCC diagnostic ignored "-Wconversion"
20186#endif
20187 v_block_size += 1;
20188#if defined(__GNUC__)
20189#pragma GCC diagnostic pop
20190#endif
20191 }
20192 if (v_is_animexts || v_is_netscape) {
20193 {
20194 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
20195 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20196 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20197 goto suspend;
20198 }
20199 uint8_t t_2 = *iop_a_src++;
20200 v_block_size = t_2;
20201 }
20202 if (v_block_size != 3) {
20203 self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
20204 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
20205 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
20206 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
20207 iop_a_src = io2_a_src;
20208 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20209 goto suspend;
20210 }
20211 iop_a_src += self->private_data.s_decode_ae[0].scratch;
20212 goto label__goto_done__break;
20213 }
20214 {
20215 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
20216 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20217 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20218 goto suspend;
20219 }
20220 uint8_t t_3 = *iop_a_src++;
20221 v_c = t_3;
20222 }
20223 if (v_c != 1) {
20224 self->private_data.s_decode_ae[0].scratch = 2;
20225 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
20226 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
20227 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
20228 iop_a_src = io2_a_src;
20229 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20230 goto suspend;
20231 }
20232 iop_a_src += self->private_data.s_decode_ae[0].scratch;
20233 goto label__goto_done__break;
20234 }
20235 {
20236 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
20237 uint32_t t_4;
20238 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
20239 t_4 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
20240 iop_a_src += 2;
20241 } else {
20242 self->private_data.s_decode_ae[0].scratch = 0;
20243 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
20244 while (true) {
20245 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20246 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20247 goto suspend;
20248 }
20249 uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
20250 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
20251 *scratch <<= 8;
20252 *scratch >>= 8;
20253 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
20254 if (num_bits_4 == 8) {
20255 t_4 = ((uint32_t)(*scratch));
20256 break;
20257 }
20258 num_bits_4 += 8;
20259 *scratch |= ((uint64_t)(num_bits_4)) << 56;
20260 }
20261 }
20262 self->private_impl.f_num_loops = t_4;
20263 }
20264 self->private_impl.f_seen_num_loops = true;
20265 if ((0 < self->private_impl.f_num_loops) && (self->private_impl.f_num_loops <= 65535)) {
20266 self->private_impl.f_num_loops += 1;
20267 }
20268 } else if (self->private_impl.f_ignore_metadata) {
20269 } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
20270 self->private_impl.f_metadata_fourcc = 1229144912;
20271 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
20272 self->private_impl.f_call_sequence = 1;
20273 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
20274 goto ok;
20275 } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
20276 self->private_impl.f_metadata_fourcc = 1481461792;
20277 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
20278 self->private_impl.f_call_sequence = 1;
20279 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
20280 goto ok;
20281 }
20282 goto label__goto_done__break;
20283 }
20284 label__goto_done__break:;
20285 if (a_src) {
20286 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20287 }
20288 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
20289 status = wuffs_gif__decoder__skip_blocks(self, a_src);
20290 if (a_src) {
20291 iop_a_src = a_src->data.ptr + a_src->meta.ri;
20292 }
20293 if (status.repr) {
20294 goto suspend;
20295 }
20296
20297 goto ok;
20298 ok:
20299 self->private_impl.p_decode_ae[0] = 0;
20300 goto exit;
20301 }
20302
20303 goto suspend;
20304 suspend:
20305 self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
20306 self->private_data.s_decode_ae[0].v_block_size = v_block_size;
20307 self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
20308 self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
20309 self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
20310 self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
20311
20312 goto exit;
20313 exit:
20314 if (a_src) {
20315 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20316 }
20317
20318 return status;
20319}
20320
20321// -------- func gif.decoder.decode_gc
20322
20323static wuffs_base__status
20324wuffs_gif__decoder__decode_gc(
20325 wuffs_gif__decoder* self,
20326 wuffs_base__io_buffer* a_src) {
20327 wuffs_base__status status = wuffs_base__make_status(NULL);
20328
20329 uint8_t v_c = 0;
20330 uint8_t v_flags = 0;
20331 uint16_t v_gc_duration_centiseconds = 0;
20332
20333 const uint8_t* iop_a_src = NULL;
20334 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20335 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20336 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20337 if (a_src) {
20338 io0_a_src = a_src->data.ptr;
20339 io1_a_src = io0_a_src + a_src->meta.ri;
20340 iop_a_src = io1_a_src;
20341 io2_a_src = io0_a_src + a_src->meta.wi;
20342 }
20343
20344 uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
20345 switch (coro_susp_point) {
20346 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
20347
20348 {
20349 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
20350 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20351 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20352 goto suspend;
20353 }
20354 uint8_t t_0 = *iop_a_src++;
20355 v_c = t_0;
20356 }
20357 if (v_c != 4) {
20358 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
20359 goto exit;
20360 }
20361 {
20362 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
20363 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20364 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20365 goto suspend;
20366 }
20367 uint8_t t_1 = *iop_a_src++;
20368 v_flags = t_1;
20369 }
20370 self->private_impl.f_gc_has_transparent_index = ((v_flags & 1) != 0);
20371 v_flags = ((v_flags >> 2) & 7);
20372 if (v_flags == 2) {
20373 self->private_impl.f_gc_disposal = 1;
20374 } else if ((v_flags == 3) || (v_flags == 4)) {
20375 self->private_impl.f_gc_disposal = 2;
20376 } else {
20377 self->private_impl.f_gc_disposal = 0;
20378 }
20379 {
20380 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
20381 uint16_t t_2;
20382 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
20383 t_2 = wuffs_base__load_u16le__no_bounds_check(iop_a_src);
20384 iop_a_src += 2;
20385 } else {
20386 self->private_data.s_decode_gc[0].scratch = 0;
20387 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
20388 while (true) {
20389 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20390 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20391 goto suspend;
20392 }
20393 uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
20394 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
20395 *scratch <<= 8;
20396 *scratch >>= 8;
20397 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
20398 if (num_bits_2 == 8) {
20399 t_2 = ((uint16_t)(*scratch));
20400 break;
20401 }
20402 num_bits_2 += 8;
20403 *scratch |= ((uint64_t)(num_bits_2)) << 56;
20404 }
20405 }
20406 v_gc_duration_centiseconds = t_2;
20407 }
20408 self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000);
20409 {
20410 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
20411 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20412 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20413 goto suspend;
20414 }
20415 uint8_t t_3 = *iop_a_src++;
20416 self->private_impl.f_gc_transparent_index = t_3;
20417 }
20418 {
20419 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
20420 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20421 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20422 goto suspend;
20423 }
20424 uint8_t t_4 = *iop_a_src++;
20425 v_c = t_4;
20426 }
20427 if (v_c != 0) {
20428 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
20429 goto exit;
20430 }
20431
20432 goto ok;
20433 ok:
20434 self->private_impl.p_decode_gc[0] = 0;
20435 goto exit;
20436 }
20437
20438 goto suspend;
20439 suspend:
20440 self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
20441
20442 goto exit;
20443 exit:
20444 if (a_src) {
20445 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20446 }
20447
20448 return status;
20449}
20450
20451// -------- func gif.decoder.decode_id_part0
20452
20453static wuffs_base__status
20454wuffs_gif__decoder__decode_id_part0(
20455 wuffs_gif__decoder* self,
20456 wuffs_base__io_buffer* a_src) {
20457 wuffs_base__status status = wuffs_base__make_status(NULL);
20458
20459 const uint8_t* iop_a_src = NULL;
20460 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20461 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20462 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20463 if (a_src) {
20464 io0_a_src = a_src->data.ptr;
20465 io1_a_src = io0_a_src + a_src->meta.ri;
20466 iop_a_src = io1_a_src;
20467 io2_a_src = io0_a_src + a_src->meta.wi;
20468 }
20469
20470 uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
20471 switch (coro_susp_point) {
20472 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
20473
20474 {
20475 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
20476 uint32_t t_0;
20477 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
20478 t_0 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
20479 iop_a_src += 2;
20480 } else {
20481 self->private_data.s_decode_id_part0[0].scratch = 0;
20482 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
20483 while (true) {
20484 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20485 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20486 goto suspend;
20487 }
20488 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
20489 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
20490 *scratch <<= 8;
20491 *scratch >>= 8;
20492 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
20493 if (num_bits_0 == 8) {
20494 t_0 = ((uint32_t)(*scratch));
20495 break;
20496 }
20497 num_bits_0 += 8;
20498 *scratch |= ((uint64_t)(num_bits_0)) << 56;
20499 }
20500 }
20501 self->private_impl.f_frame_rect_x0 = t_0;
20502 }
20503 {
20504 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
20505 uint32_t t_1;
20506 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
20507 t_1 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
20508 iop_a_src += 2;
20509 } else {
20510 self->private_data.s_decode_id_part0[0].scratch = 0;
20511 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
20512 while (true) {
20513 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20514 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20515 goto suspend;
20516 }
20517 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
20518 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
20519 *scratch <<= 8;
20520 *scratch >>= 8;
20521 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
20522 if (num_bits_1 == 8) {
20523 t_1 = ((uint32_t)(*scratch));
20524 break;
20525 }
20526 num_bits_1 += 8;
20527 *scratch |= ((uint64_t)(num_bits_1)) << 56;
20528 }
20529 }
20530 self->private_impl.f_frame_rect_y0 = t_1;
20531 }
20532 {
20533 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
20534 uint32_t t_2;
20535 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
20536 t_2 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
20537 iop_a_src += 2;
20538 } else {
20539 self->private_data.s_decode_id_part0[0].scratch = 0;
20540 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
20541 while (true) {
20542 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20543 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20544 goto suspend;
20545 }
20546 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
20547 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
20548 *scratch <<= 8;
20549 *scratch >>= 8;
20550 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
20551 if (num_bits_2 == 8) {
20552 t_2 = ((uint32_t)(*scratch));
20553 break;
20554 }
20555 num_bits_2 += 8;
20556 *scratch |= ((uint64_t)(num_bits_2)) << 56;
20557 }
20558 }
20559 self->private_impl.f_frame_rect_x1 = t_2;
20560 }
20561 self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
20562 {
20563 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
20564 uint32_t t_3;
20565 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
20566 t_3 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
20567 iop_a_src += 2;
20568 } else {
20569 self->private_data.s_decode_id_part0[0].scratch = 0;
20570 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
20571 while (true) {
20572 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20573 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20574 goto suspend;
20575 }
20576 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
20577 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
20578 *scratch <<= 8;
20579 *scratch >>= 8;
20580 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
20581 if (num_bits_3 == 8) {
20582 t_3 = ((uint32_t)(*scratch));
20583 break;
20584 }
20585 num_bits_3 += 8;
20586 *scratch |= ((uint64_t)(num_bits_3)) << 56;
20587 }
20588 }
20589 self->private_impl.f_frame_rect_y1 = t_3;
20590 }
20591 self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
20592 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
20593 self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
20594 if ((self->private_impl.f_call_sequence == 0) && ! self->private_impl.f_quirks[4]) {
20595 self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
20596 self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
20597 }
20598
20599 goto ok;
20600 ok:
20601 self->private_impl.p_decode_id_part0[0] = 0;
20602 goto exit;
20603 }
20604
20605 goto suspend;
20606 suspend:
20607 self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
20608
20609 goto exit;
20610 exit:
20611 if (a_src) {
20612 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20613 }
20614
20615 return status;
20616}
20617
20618// -------- func gif.decoder.decode_id_part1
20619
20620static wuffs_base__status
20621wuffs_gif__decoder__decode_id_part1(
20622 wuffs_gif__decoder* self,
20623 wuffs_base__pixel_buffer* a_dst,
20624 wuffs_base__io_buffer* a_src,
20625 wuffs_base__pixel_blend a_blend) {
20626 wuffs_base__status status = wuffs_base__make_status(NULL);
20627
20628 uint8_t v_flags = 0;
20629 uint8_t v_which_palette = 0;
20630 uint32_t v_num_palette_entries = 0;
20631 uint32_t v_i = 0;
20632 uint32_t v_argb = 0;
20633 wuffs_base__slice_u8 v_dst_palette = {0};
20634 wuffs_base__status v_status = wuffs_base__make_status(NULL);
20635 uint8_t v_lw = 0;
20636
20637 const uint8_t* iop_a_src = NULL;
20638 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20639 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20640 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20641 if (a_src) {
20642 io0_a_src = a_src->data.ptr;
20643 io1_a_src = io0_a_src + a_src->meta.ri;
20644 iop_a_src = io1_a_src;
20645 io2_a_src = io0_a_src + a_src->meta.wi;
20646 }
20647
20648 uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0];
20649 if (coro_susp_point) {
20650 v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette;
20651 v_num_palette_entries = self->private_data.s_decode_id_part1[0].v_num_palette_entries;
20652 v_i = self->private_data.s_decode_id_part1[0].v_i;
20653 }
20654 switch (coro_susp_point) {
20655 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
20656
20657 {
20658 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
20659 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20660 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20661 goto suspend;
20662 }
20663 uint8_t t_0 = *iop_a_src++;
20664 v_flags = t_0;
20665 }
20666 if ((v_flags & 64) != 0) {
20667 self->private_impl.f_interlace = 4;
20668 } else {
20669 self->private_impl.f_interlace = 0;
20670 }
20671 v_which_palette = 1;
20672 if ((v_flags & 128) != 0) {
20673 v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
20674 v_i = 0;
20675 while (v_i < v_num_palette_entries) {
20676 {
20677 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
20678 uint32_t t_1;
20679 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
20680 t_1 = ((uint32_t)(wuffs_base__load_u24be__no_bounds_check(iop_a_src)));
20681 iop_a_src += 3;
20682 } else {
20683 self->private_data.s_decode_id_part1[0].scratch = 0;
20684 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
20685 while (true) {
20686 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20687 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20688 goto suspend;
20689 }
20690 uint64_t* scratch = &self->private_data.s_decode_id_part1[0].scratch;
20691 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
20692 *scratch >>= 8;
20693 *scratch <<= 8;
20694 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
20695 if (num_bits_1 == 16) {
20696 t_1 = ((uint32_t)(*scratch >> 40));
20697 break;
20698 }
20699 num_bits_1 += 8;
20700 *scratch |= ((uint64_t)(num_bits_1));
20701 }
20702 }
20703 v_argb = t_1;
20704 }
20705 v_argb |= 4278190080;
20706 self->private_data.f_palettes[1][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
20707 self->private_data.f_palettes[1][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
20708 self->private_data.f_palettes[1][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
20709 self->private_data.f_palettes[1][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
20710 v_i += 1;
20711 }
20712 while (v_i < 256) {
20713 self->private_data.f_palettes[1][((4 * v_i) + 0)] = 0;
20714 self->private_data.f_palettes[1][((4 * v_i) + 1)] = 0;
20715 self->private_data.f_palettes[1][((4 * v_i) + 2)] = 0;
20716 self->private_data.f_palettes[1][((4 * v_i) + 3)] = 255;
20717 v_i += 1;
20718 }
20719 } else if (self->private_impl.f_quirks[6] && ! self->private_impl.f_has_global_palette) {
20720 status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
20721 goto exit;
20722 } else if (self->private_impl.f_gc_has_transparent_index) {
20723 wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_palettes[1], 1024), wuffs_base__make_slice_u8(self->private_data.f_palettes[0], 1024));
20724 } else {
20725 v_which_palette = 0;
20726 }
20727 if (self->private_impl.f_gc_has_transparent_index) {
20728 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0)] = 0;
20729 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1)] = 0;
20730 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2)] = 0;
20731 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3)] = 0;
20732 }
20733 v_dst_palette = wuffs_base__pixel_buffer__palette(a_dst);
20734 if (((uint64_t)(v_dst_palette.len)) == 0) {
20735 v_dst_palette = wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024);
20736 }
20737 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
20738 wuffs_base__pixel_buffer__pixel_format(a_dst),
20739 v_dst_palette,
20740 wuffs_base__utility__make_pixel_format(2198077448),
20741 wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024),
20742 a_blend);
20743 if ( ! wuffs_base__status__is_ok(&v_status)) {
20744 status = v_status;
20745 if (wuffs_base__status__is_error(&status)) {
20746 goto exit;
20747 } else if (wuffs_base__status__is_suspension(&status)) {
20748 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
20749 goto exit;
20750 }
20751 goto ok;
20752 }
20753 if (self->private_impl.f_previous_lzw_decode_ended_abruptly) {
20754 wuffs_base__ignore_status(wuffs_lzw__decoder__initialize(&self->private_data.f_lzw, sizeof (wuffs_lzw__decoder), WUFFS_VERSION, 0));
20755 }
20756 {
20757 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
20758 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20759 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20760 goto suspend;
20761 }
20762 uint8_t t_2 = *iop_a_src++;
20763 v_lw = t_2;
20764 }
20765 if (v_lw > 8) {
20766 status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
20767 goto exit;
20768 }
20769 wuffs_lzw__decoder__set_literal_width(&self->private_data.f_lzw, ((uint32_t)(v_lw)));
20770 self->private_impl.f_previous_lzw_decode_ended_abruptly = true;
20771
20772 goto ok;
20773 ok:
20774 self->private_impl.p_decode_id_part1[0] = 0;
20775 goto exit;
20776 }
20777
20778 goto suspend;
20779 suspend:
20780 self->private_impl.p_decode_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
20781 self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette;
20782 self->private_data.s_decode_id_part1[0].v_num_palette_entries = v_num_palette_entries;
20783 self->private_data.s_decode_id_part1[0].v_i = v_i;
20784
20785 goto exit;
20786 exit:
20787 if (a_src) {
20788 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20789 }
20790
20791 return status;
20792}
20793
20794// -------- func gif.decoder.decode_id_part2
20795
20796static wuffs_base__status
20797wuffs_gif__decoder__decode_id_part2(
20798 wuffs_gif__decoder* self,
20799 wuffs_base__pixel_buffer* a_dst,
20800 wuffs_base__io_buffer* a_src,
20801 wuffs_base__slice_u8 a_workbuf) {
20802 wuffs_base__io_buffer empty_io_buffer = wuffs_base__empty_io_buffer();
20803
20804 wuffs_base__status status = wuffs_base__make_status(NULL);
20805
20806 uint64_t v_block_size = 0;
20807 bool v_need_block_size = false;
20808 uint32_t v_n_copied = 0;
20809 uint64_t v_n_compressed = 0;
20810 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
20811 wuffs_base__io_buffer* v_r = &u_r;
20812 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20813 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20814 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20815 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20816 uint64_t v_mark = 0;
20817 wuffs_base__status v_lzw_status = wuffs_base__make_status(NULL);
20818 wuffs_base__status v_copy_status = wuffs_base__make_status(NULL);
20819 wuffs_base__slice_u8 v_uncompressed = {0};
20820
20821 const uint8_t* iop_a_src = NULL;
20822 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20823 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20824 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
20825 if (a_src) {
20826 io0_a_src = a_src->data.ptr;
20827 io1_a_src = io0_a_src + a_src->meta.ri;
20828 iop_a_src = io1_a_src;
20829 io2_a_src = io0_a_src + a_src->meta.wi;
20830 }
20831
20832 uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0];
20833 if (coro_susp_point) {
20834 v_block_size = self->private_data.s_decode_id_part2[0].v_block_size;
20835 v_need_block_size = self->private_data.s_decode_id_part2[0].v_need_block_size;
20836 v_lzw_status = self->private_data.s_decode_id_part2[0].v_lzw_status;
20837 }
20838 switch (coro_susp_point) {
20839 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
20840
20841 v_need_block_size = true;
20842 label__outer__continue:;
20843 while (true) {
20844 if (v_need_block_size) {
20845 v_need_block_size = false;
20846 {
20847 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
20848 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
20849 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20850 goto suspend;
20851 }
20852 uint64_t t_0 = *iop_a_src++;
20853 v_block_size = t_0;
20854 }
20855 }
20856 if (v_block_size == 0) {
20857 goto label__outer__break;
20858 }
20859 while (((uint64_t)(io2_a_src - iop_a_src)) == 0) {
20860 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20861 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
20862 }
20863 if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) {
20864 self->private_impl.f_compressed_ri = 0;
20865 self->private_impl.f_compressed_wi = 0;
20866 }
20867 while (self->private_impl.f_compressed_wi <= 3841) {
20868 v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
20869 if (v_n_compressed <= 0) {
20870 goto label__0__break;
20871 }
20872 v_n_copied = wuffs_base__io_reader__limited_copy_u32_to_slice(
20873 &iop_a_src, io2_a_src,((uint32_t)((v_n_compressed & 4294967295))), wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_compressed, 4096), self->private_impl.f_compressed_wi));
20874 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied)));
20875 wuffs_base__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied)));
20876 if (v_block_size > 0) {
20877 goto label__0__break;
20878 }
20879 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
20880 v_need_block_size = true;
20881 goto label__0__break;
20882 }
20883 v_block_size = ((uint64_t)(wuffs_base__load_u8be__no_bounds_check(iop_a_src)));
20884 (iop_a_src += 1, wuffs_base__make_empty_struct());
20885 }
20886 label__0__break:;
20887 label__inner__continue:;
20888 while (true) {
20889 if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096)) {
20890 status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
20891 goto exit;
20892 }
20893 {
20894 wuffs_base__io_buffer* o_0_v_r = v_r;
20895 const uint8_t *o_0_iop_v_r = iop_v_r;
20896 const uint8_t *o_0_io0_v_r = io0_v_r;
20897 const uint8_t *o_0_io1_v_r = io1_v_r;
20898 const uint8_t *o_0_io2_v_r = io2_v_r;
20899 v_r = wuffs_base__io_reader__set(
20900 &u_r,
20901 &iop_v_r,
20902 &io0_v_r,
20903 &io1_v_r,
20904 &io2_v_r,
20905 wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_compressed,
20906 4096),
20907 self->private_impl.f_compressed_ri,
20908 self->private_impl.f_compressed_wi));
20909 v_mark = ((uint64_t)(iop_v_r - io0_v_r));
20910 {
20911 u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
20912 wuffs_base__status t_1 = wuffs_lzw__decoder__transform_io(&self->private_data.f_lzw, &empty_io_buffer, v_r, wuffs_base__utility__empty_slice_u8());
20913 iop_v_r = u_r.data.ptr + u_r.meta.ri;
20914 v_lzw_status = t_1;
20915 }
20916 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r))));
20917 v_r = o_0_v_r;
20918 iop_v_r = o_0_iop_v_r;
20919 io0_v_r = o_0_io0_v_r;
20920 io1_v_r = o_0_io1_v_r;
20921 io2_v_r = o_0_io2_v_r;
20922 }
20923 v_uncompressed = wuffs_lzw__decoder__flush(&self->private_data.f_lzw);
20924 if (((uint64_t)(v_uncompressed.len)) > 0) {
20925 v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(self, a_dst, v_uncompressed);
20926 if (wuffs_base__status__is_error(&v_copy_status)) {
20927 status = v_copy_status;
20928 goto exit;
20929 }
20930 }
20931 if (wuffs_base__status__is_ok(&v_lzw_status)) {
20932 self->private_impl.f_previous_lzw_decode_ended_abruptly = false;
20933 if (v_need_block_size || (v_block_size > 0)) {
20934 self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
20935 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
20936 if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
20937 self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
20938 iop_a_src = io2_a_src;
20939 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
20940 goto suspend;
20941 }
20942 iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
20943 if (a_src) {
20944 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20945 }
20946 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
20947 status = wuffs_gif__decoder__skip_blocks(self, a_src);
20948 if (a_src) {
20949 iop_a_src = a_src->data.ptr + a_src->meta.ri;
20950 }
20951 if (status.repr) {
20952 goto suspend;
20953 }
20954 }
20955 goto label__outer__break;
20956 } else if (v_lzw_status.repr == wuffs_base__suspension__short_read) {
20957 goto label__outer__continue;
20958 } else if (v_lzw_status.repr == wuffs_base__suspension__short_write) {
20959 goto label__inner__continue;
20960 }
20961 status = v_lzw_status;
20962 if (wuffs_base__status__is_error(&status)) {
20963 goto exit;
20964 } else if (wuffs_base__status__is_suspension(&status)) {
20965 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
20966 goto exit;
20967 }
20968 goto ok;
20969 }
20970 }
20971 label__outer__break:;
20972 self->private_impl.f_compressed_ri = 0;
20973 self->private_impl.f_compressed_wi = 0;
20974 if ((self->private_impl.f_dst_y < self->private_impl.f_frame_rect_y1) && (self->private_impl.f_frame_rect_x0 != self->private_impl.f_frame_rect_x1) && (self->private_impl.f_frame_rect_y0 != self->private_impl.f_frame_rect_y1)) {
20975 status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
20976 goto exit;
20977 }
20978
20979 goto ok;
20980 ok:
20981 self->private_impl.p_decode_id_part2[0] = 0;
20982 goto exit;
20983 }
20984
20985 goto suspend;
20986 suspend:
20987 self->private_impl.p_decode_id_part2[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
20988 self->private_data.s_decode_id_part2[0].v_block_size = v_block_size;
20989 self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size;
20990 self->private_data.s_decode_id_part2[0].v_lzw_status = v_lzw_status;
20991
20992 goto exit;
20993 exit:
20994 if (a_src) {
20995 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
20996 }
20997
20998 return status;
20999}
21000
21001// -------- func gif.decoder.copy_to_image_buffer
21002
21003static wuffs_base__status
21004wuffs_gif__decoder__copy_to_image_buffer(
21005 wuffs_gif__decoder* self,
21006 wuffs_base__pixel_buffer* a_pb,
21007 wuffs_base__slice_u8 a_src) {
21008 wuffs_base__slice_u8 v_dst = {0};
21009 wuffs_base__slice_u8 v_src = {0};
21010 uint64_t v_width_in_bytes = 0;
21011 uint64_t v_n = 0;
21012 uint64_t v_src_ri = 0;
21013 wuffs_base__pixel_format v_pixfmt = {0};
21014 uint32_t v_bytes_per_pixel = 0;
21015 uint32_t v_bits_per_pixel = 0;
21016 wuffs_base__table_u8 v_tab = {0};
21017 uint64_t v_i = 0;
21018 uint64_t v_j = 0;
21019 uint32_t v_replicate_y0 = 0;
21020 uint32_t v_replicate_y1 = 0;
21021 wuffs_base__slice_u8 v_replicate_dst = {0};
21022 wuffs_base__slice_u8 v_replicate_src = {0};
21023
21024 v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
21025 v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt);
21026 if ((v_bits_per_pixel & 7) != 0) {
21027 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
21028 }
21029 v_bytes_per_pixel = (v_bits_per_pixel >> 3);
21030 v_width_in_bytes = (((uint64_t)(self->private_impl.f_width)) * ((uint64_t)(v_bytes_per_pixel)));
21031 v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0);
21032 label__0__continue:;
21033 while (v_src_ri < ((uint64_t)(a_src.len))) {
21034 v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
21035 if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
21036 if (self->private_impl.f_quirks[3]) {
21037 return wuffs_base__make_status(NULL);
21038 }
21039 return wuffs_base__make_status(wuffs_base__error__too_much_data);
21040 }
21041 v_dst = wuffs_base__table_u8__row(v_tab, self->private_impl.f_dst_y);
21042 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
21043 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0);
21044 } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) {
21045 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes);
21046 }
21047 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel)));
21048 if (v_i < ((uint64_t)(v_dst.len))) {
21049 v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel)));
21050 if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
21051 v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
21052 } else {
21053 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
21054 }
21055 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024), v_src);
21056 wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
21057 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
21058 self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1));
21059 }
21060 if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
21061 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
21062 if (self->private_impl.f_interlace == 0) {
21063 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1);
21064 goto label__0__continue;
21065 }
21066 if ((self->private_impl.f_num_decoded_frames_value == 0) && ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1)) {
21067 v_replicate_src = wuffs_base__table_u8__row(v_tab, self->private_impl.f_dst_y);
21068 v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1);
21069 v_replicate_y1 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_COUNT[self->private_impl.f_interlace])));
21070 v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1);
21071 while (v_replicate_y0 < v_replicate_y1) {
21072 v_replicate_dst = wuffs_base__table_u8__row(v_tab, v_replicate_y0);
21073 wuffs_base__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src);
21074 v_replicate_y0 += 1;
21075 }
21076 self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1);
21077 }
21078 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
21079 while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
21080#if defined(__GNUC__)
21081#pragma GCC diagnostic push
21082#pragma GCC diagnostic ignored "-Wconversion"
21083#endif
21084 self->private_impl.f_interlace -= 1;
21085#if defined(__GNUC__)
21086#pragma GCC diagnostic pop
21087#endif
21088 self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]);
21089 }
21090 goto label__0__continue;
21091 }
21092 if (((uint64_t)(a_src.len)) == v_src_ri) {
21093 goto label__0__break;
21094 } else if (((uint64_t)(a_src.len)) < v_src_ri) {
21095 return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
21096 }
21097 v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
21098 v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
21099 wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
21100 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
21101 if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
21102 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
21103 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
21104 while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
21105#if defined(__GNUC__)
21106#pragma GCC diagnostic push
21107#pragma GCC diagnostic ignored "-Wconversion"
21108#endif
21109 self->private_impl.f_interlace -= 1;
21110#if defined(__GNUC__)
21111#pragma GCC diagnostic pop
21112#endif
21113 self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]);
21114 }
21115 goto label__0__continue;
21116 }
21117 if (v_src_ri != ((uint64_t)(a_src.len))) {
21118 return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
21119 }
21120 goto label__0__break;
21121 }
21122 label__0__break:;
21123 return wuffs_base__make_status(NULL);
21124}
21125
21126#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
21127
21128#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
21129
21130// ---------------- Status Codes Implementations
21131
21132const char* wuffs_gzip__error__bad_checksum = "#gzip: bad checksum";
21133const char* wuffs_gzip__error__bad_compression_method = "#gzip: bad compression method";
21134const char* wuffs_gzip__error__bad_encoding_flags = "#gzip: bad encoding flags";
21135const char* wuffs_gzip__error__bad_header = "#gzip: bad header";
21136
21137// ---------------- Private Consts
21138
21139// ---------------- Private Initializer Prototypes
21140
21141// ---------------- Private Function Prototypes
21142
21143// ---------------- VTables
21144
21145const wuffs_base__io_transformer__func_ptrs
21146wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
21147 (wuffs_base__empty_struct(*)(void*,
21148 uint32_t,
21149 bool))(&wuffs_gzip__decoder__set_quirk_enabled),
21150 (wuffs_base__status(*)(void*,
21151 wuffs_base__io_buffer*,
21152 wuffs_base__io_buffer*,
21153 wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io),
21154 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len),
21155};
21156
21157// ---------------- Initializer Implementations
21158
21159wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
21160wuffs_gzip__decoder__initialize(
21161 wuffs_gzip__decoder* self,
21162 size_t sizeof_star_self,
21163 uint64_t wuffs_version,
21164 uint32_t initialize_flags){
21165 if (!self) {
21166 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21167 }
21168 if (sizeof(*self) != sizeof_star_self) {
21169 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
21170 }
21171 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
21172 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
21173 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
21174 }
21175
21176 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
21177 // The whole point of this if-check is to detect an uninitialized *self.
21178 // We disable the warning on GCC. Clang-5.0 does not have this warning.
21179#if !defined(__clang__) && defined(__GNUC__)
21180#pragma GCC diagnostic push
21181#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
21182#endif
21183 if (self->private_impl.magic != 0) {
21184 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
21185 }
21186#if !defined(__clang__) && defined(__GNUC__)
21187#pragma GCC diagnostic pop
21188#endif
21189 } else {
21190 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
21191 memset(self, 0, sizeof(*self));
21192 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
21193 } else {
21194 memset(&(self->private_impl), 0, sizeof(self->private_impl));
21195 }
21196 }
21197
21198 {
21199 wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
21200 &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, initialize_flags);
21201 if (z.repr) {
21202 return z;
21203 }
21204 }
21205 {
21206 wuffs_base__status z = wuffs_deflate__decoder__initialize(
21207 &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, initialize_flags);
21208 if (z.repr) {
21209 return z;
21210 }
21211 }
21212 self->private_impl.magic = WUFFS_BASE__MAGIC;
21213 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
21214 wuffs_base__io_transformer__vtable_name;
21215 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
21216 (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
21217 return wuffs_base__make_status(NULL);
21218}
21219
21220wuffs_gzip__decoder*
21221wuffs_gzip__decoder__alloc() {
21222 wuffs_gzip__decoder* x =
21223 (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
21224 if (!x) {
21225 return NULL;
21226 }
21227 if (wuffs_gzip__decoder__initialize(
21228 x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
21229 free(x);
21230 return NULL;
21231 }
21232 return x;
21233}
21234
21235size_t
21236sizeof__wuffs_gzip__decoder() {
21237 return sizeof(wuffs_gzip__decoder);
21238}
21239
21240// ---------------- Function Implementations
21241
21242// -------- func gzip.decoder.set_ignore_checksum
21243
21244WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
21245wuffs_gzip__decoder__set_ignore_checksum(
21246 wuffs_gzip__decoder* self,
21247 bool a_ic) {
21248 if (!self) {
21249 return wuffs_base__make_empty_struct();
21250 }
21251 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
21252 return wuffs_base__make_empty_struct();
21253 }
21254
21255 self->private_impl.f_ignore_checksum = a_ic;
21256 return wuffs_base__make_empty_struct();
21257}
21258
21259// -------- func gzip.decoder.set_quirk_enabled
21260
21261WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
21262wuffs_gzip__decoder__set_quirk_enabled(
21263 wuffs_gzip__decoder* self,
21264 uint32_t a_quirk,
21265 bool a_enabled) {
21266 return wuffs_base__make_empty_struct();
21267}
21268
21269// -------- func gzip.decoder.workbuf_len
21270
21271WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
21272wuffs_gzip__decoder__workbuf_len(
21273 const wuffs_gzip__decoder* self) {
21274 if (!self) {
21275 return wuffs_base__utility__empty_range_ii_u64();
21276 }
21277 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
21278 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
21279 return wuffs_base__utility__empty_range_ii_u64();
21280 }
21281
21282 return wuffs_base__utility__make_range_ii_u64(1, 1);
21283}
21284
21285// -------- func gzip.decoder.transform_io
21286
21287WUFFS_BASE__MAYBE_STATIC wuffs_base__status
21288wuffs_gzip__decoder__transform_io(
21289 wuffs_gzip__decoder* self,
21290 wuffs_base__io_buffer* a_dst,
21291 wuffs_base__io_buffer* a_src,
21292 wuffs_base__slice_u8 a_workbuf) {
21293 if (!self) {
21294 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21295 }
21296 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
21297 return wuffs_base__make_status(
21298 (self->private_impl.magic == WUFFS_BASE__DISABLED)
21299 ? wuffs_base__error__disabled_by_previous_error
21300 : wuffs_base__error__initialize_not_called);
21301 }
21302 if (!a_dst || !a_src) {
21303 self->private_impl.magic = WUFFS_BASE__DISABLED;
21304 return wuffs_base__make_status(wuffs_base__error__bad_argument);
21305 }
21306 if ((self->private_impl.active_coroutine != 0) &&
21307 (self->private_impl.active_coroutine != 1)) {
21308 self->private_impl.magic = WUFFS_BASE__DISABLED;
21309 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
21310 }
21311 self->private_impl.active_coroutine = 0;
21312 wuffs_base__status status = wuffs_base__make_status(NULL);
21313
21314 uint8_t v_c = 0;
21315 uint8_t v_flags = 0;
21316 uint16_t v_xlen = 0;
21317 uint64_t v_mark = 0;
21318 uint32_t v_checksum_got = 0;
21319 uint32_t v_decoded_length_got = 0;
21320 wuffs_base__status v_status = wuffs_base__make_status(NULL);
21321 uint32_t v_checksum_want = 0;
21322 uint32_t v_decoded_length_want = 0;
21323
21324 uint8_t* iop_a_dst = NULL;
21325 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21326 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21327 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21328 if (a_dst) {
21329 io0_a_dst = a_dst->data.ptr;
21330 io1_a_dst = io0_a_dst + a_dst->meta.wi;
21331 iop_a_dst = io1_a_dst;
21332 io2_a_dst = io0_a_dst + a_dst->data.len;
21333 if (a_dst->meta.closed) {
21334 io2_a_dst = iop_a_dst;
21335 }
21336 }
21337 const uint8_t* iop_a_src = NULL;
21338 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21339 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21340 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
21341 if (a_src) {
21342 io0_a_src = a_src->data.ptr;
21343 io1_a_src = io0_a_src + a_src->meta.ri;
21344 iop_a_src = io1_a_src;
21345 io2_a_src = io0_a_src + a_src->meta.wi;
21346 }
21347
21348 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
21349 if (coro_susp_point) {
21350 v_flags = self->private_data.s_transform_io[0].v_flags;
21351 v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
21352 v_decoded_length_got = self->private_data.s_transform_io[0].v_decoded_length_got;
21353 v_checksum_want = self->private_data.s_transform_io[0].v_checksum_want;
21354 }
21355 switch (coro_susp_point) {
21356 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
21357
21358 {
21359 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
21360 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21361 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21362 goto suspend;
21363 }
21364 uint8_t t_0 = *iop_a_src++;
21365 v_c = t_0;
21366 }
21367 if (v_c != 31) {
21368 status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
21369 goto exit;
21370 }
21371 {
21372 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
21373 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21374 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21375 goto suspend;
21376 }
21377 uint8_t t_1 = *iop_a_src++;
21378 v_c = t_1;
21379 }
21380 if (v_c != 139) {
21381 status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
21382 goto exit;
21383 }
21384 {
21385 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
21386 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21387 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21388 goto suspend;
21389 }
21390 uint8_t t_2 = *iop_a_src++;
21391 v_c = t_2;
21392 }
21393 if (v_c != 8) {
21394 status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method);
21395 goto exit;
21396 }
21397 {
21398 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
21399 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21400 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21401 goto suspend;
21402 }
21403 uint8_t t_3 = *iop_a_src++;
21404 v_flags = t_3;
21405 }
21406 self->private_data.s_transform_io[0].scratch = 6;
21407 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
21408 if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
21409 self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
21410 iop_a_src = io2_a_src;
21411 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21412 goto suspend;
21413 }
21414 iop_a_src += self->private_data.s_transform_io[0].scratch;
21415 if ((v_flags & 4) != 0) {
21416 {
21417 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
21418 uint16_t t_4;
21419 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
21420 t_4 = wuffs_base__load_u16le__no_bounds_check(iop_a_src);
21421 iop_a_src += 2;
21422 } else {
21423 self->private_data.s_transform_io[0].scratch = 0;
21424 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
21425 while (true) {
21426 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21427 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21428 goto suspend;
21429 }
21430 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
21431 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
21432 *scratch <<= 8;
21433 *scratch >>= 8;
21434 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
21435 if (num_bits_4 == 8) {
21436 t_4 = ((uint16_t)(*scratch));
21437 break;
21438 }
21439 num_bits_4 += 8;
21440 *scratch |= ((uint64_t)(num_bits_4)) << 56;
21441 }
21442 }
21443 v_xlen = t_4;
21444 }
21445 self->private_data.s_transform_io[0].scratch = ((uint32_t)(v_xlen));
21446 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
21447 if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
21448 self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
21449 iop_a_src = io2_a_src;
21450 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21451 goto suspend;
21452 }
21453 iop_a_src += self->private_data.s_transform_io[0].scratch;
21454 }
21455 if ((v_flags & 8) != 0) {
21456 while (true) {
21457 {
21458 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
21459 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21460 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21461 goto suspend;
21462 }
21463 uint8_t t_5 = *iop_a_src++;
21464 v_c = t_5;
21465 }
21466 if (v_c == 0) {
21467 goto label__0__break;
21468 }
21469 }
21470 label__0__break:;
21471 }
21472 if ((v_flags & 16) != 0) {
21473 while (true) {
21474 {
21475 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
21476 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21477 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21478 goto suspend;
21479 }
21480 uint8_t t_6 = *iop_a_src++;
21481 v_c = t_6;
21482 }
21483 if (v_c == 0) {
21484 goto label__1__break;
21485 }
21486 }
21487 label__1__break:;
21488 }
21489 if ((v_flags & 2) != 0) {
21490 self->private_data.s_transform_io[0].scratch = 2;
21491 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
21492 if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
21493 self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
21494 iop_a_src = io2_a_src;
21495 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21496 goto suspend;
21497 }
21498 iop_a_src += self->private_data.s_transform_io[0].scratch;
21499 }
21500 if ((v_flags & 224) != 0) {
21501 status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags);
21502 goto exit;
21503 }
21504 while (true) {
21505 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
21506 {
21507 if (a_dst) {
21508 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
21509 }
21510 if (a_src) {
21511 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
21512 }
21513 wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
21514 if (a_dst) {
21515 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
21516 }
21517 if (a_src) {
21518 iop_a_src = a_src->data.ptr + a_src->meta.ri;
21519 }
21520 v_status = t_7;
21521 }
21522 if ( ! self->private_impl.f_ignore_checksum) {
21523 v_checksum_got = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
21524 v_decoded_length_got += ((uint32_t)((wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))) & 4294967295)));
21525 }
21526 if (wuffs_base__status__is_ok(&v_status)) {
21527 goto label__2__break;
21528 }
21529 status = v_status;
21530 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
21531 }
21532 label__2__break:;
21533 {
21534 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
21535 uint32_t t_8;
21536 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
21537 t_8 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
21538 iop_a_src += 4;
21539 } else {
21540 self->private_data.s_transform_io[0].scratch = 0;
21541 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
21542 while (true) {
21543 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21544 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21545 goto suspend;
21546 }
21547 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
21548 uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
21549 *scratch <<= 8;
21550 *scratch >>= 8;
21551 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
21552 if (num_bits_8 == 24) {
21553 t_8 = ((uint32_t)(*scratch));
21554 break;
21555 }
21556 num_bits_8 += 8;
21557 *scratch |= ((uint64_t)(num_bits_8)) << 56;
21558 }
21559 }
21560 v_checksum_want = t_8;
21561 }
21562 {
21563 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
21564 uint32_t t_9;
21565 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
21566 t_9 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
21567 iop_a_src += 4;
21568 } else {
21569 self->private_data.s_transform_io[0].scratch = 0;
21570 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
21571 while (true) {
21572 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
21573 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
21574 goto suspend;
21575 }
21576 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
21577 uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
21578 *scratch <<= 8;
21579 *scratch >>= 8;
21580 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
21581 if (num_bits_9 == 24) {
21582 t_9 = ((uint32_t)(*scratch));
21583 break;
21584 }
21585 num_bits_9 += 8;
21586 *scratch |= ((uint64_t)(num_bits_9)) << 56;
21587 }
21588 }
21589 v_decoded_length_want = t_9;
21590 }
21591 if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_got != v_checksum_want) || (v_decoded_length_got != v_decoded_length_want))) {
21592 status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum);
21593 goto exit;
21594 }
21595
21596 goto ok;
21597 ok:
21598 self->private_impl.p_transform_io[0] = 0;
21599 goto exit;
21600 }
21601
21602 goto suspend;
21603 suspend:
21604 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
21605 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
21606 self->private_data.s_transform_io[0].v_flags = v_flags;
21607 self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
21608 self->private_data.s_transform_io[0].v_decoded_length_got = v_decoded_length_got;
21609 self->private_data.s_transform_io[0].v_checksum_want = v_checksum_want;
21610
21611 goto exit;
21612 exit:
21613 if (a_dst) {
21614 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
21615 }
21616 if (a_src) {
21617 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
21618 }
21619
21620 if (wuffs_base__status__is_error(&status)) {
21621 self->private_impl.magic = WUFFS_BASE__DISABLED;
21622 }
21623 return status;
21624}
21625
21626#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
21627
21628#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
21629
21630// ---------------- Status Codes Implementations
21631
21632const char* wuffs_json__error__bad_c0_control_code = "#json: bad C0 control code";
21633const char* wuffs_json__error__bad_utf_8 = "#json: bad UTF-8";
21634const char* wuffs_json__error__bad_backslash_escape = "#json: bad backslash-escape";
21635const char* wuffs_json__error__bad_input = "#json: bad input";
21636const char* wuffs_json__error__unsupported_number_length = "#json: unsupported number length";
21637const char* wuffs_json__error__unsupported_recursion_depth = "#json: unsupported recursion depth";
21638const char* wuffs_json__error__internal_error_inconsistent_i_o = "#json: internal error: inconsistent I/O";
21639
21640// ---------------- Private Consts
21641
21642#define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99
21643
21644static const uint8_t
21645WUFFS_JSON__LUT_BACKSLASHES[256]WUFFS_BASE__POTENTIALLY_UNUSED = {
21646 0, 0, 0, 0, 0, 0, 0, 0,
21647 0, 0, 3, 0, 0, 0, 0, 0,
21648 0, 0, 0, 0, 0, 0, 0, 0,
21649 0, 0, 0, 0, 0, 0, 0, 0,
21650 0, 0, 162, 0, 0, 0, 0, 5,
21651 0, 0, 0, 0, 0, 0, 0, 175,
21652 7, 0, 0, 0, 0, 0, 0, 0,
21653 0, 0, 0, 0, 0, 0, 0, 4,
21654 0, 0, 0, 0, 0, 0, 0, 0,
21655 0, 0, 0, 0, 0, 0, 0, 0,
21656 0, 0, 0, 0, 0, 0, 0, 0,
21657 0, 0, 0, 0, 220, 0, 0, 0,
21658 0, 1, 136, 0, 0, 2, 140, 0,
21659 0, 0, 0, 0, 0, 0, 138, 0,
21660 0, 0, 141, 0, 137, 0, 6, 0,
21661 0, 0, 0, 0, 0, 0, 0, 0,
21662 0, 0, 0, 0, 0, 0, 0, 0,
21663 0, 0, 0, 0, 0, 0, 0, 0,
21664 0, 0, 0, 0, 0, 0, 0, 0,
21665 0, 0, 0, 0, 0, 0, 0, 0,
21666 0, 0, 0, 0, 0, 0, 0, 0,
21667 0, 0, 0, 0, 0, 0, 0, 0,
21668 0, 0, 0, 0, 0, 0, 0, 0,
21669 0, 0, 0, 0, 0, 0, 0, 0,
21670 0, 0, 0, 0, 0, 0, 0, 0,
21671 0, 0, 0, 0, 0, 0, 0, 0,
21672 0, 0, 0, 0, 0, 0, 0, 0,
21673 0, 0, 0, 0, 0, 0, 0, 0,
21674 0, 0, 0, 0, 0, 0, 0, 0,
21675 0, 0, 0, 0, 0, 0, 0, 0,
21676 0, 0, 0, 0, 0, 0, 0, 0,
21677 0, 0, 0, 0, 0, 0, 0, 0,
21678};
21679
21680static const uint8_t
21681WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8]WUFFS_BASE__POTENTIALLY_UNUSED = {
21682 0, 1, 3, 4, 5, 6, 7, 9,
21683};
21684
21685static const uint8_t
21686WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8]WUFFS_BASE__POTENTIALLY_UNUSED = {
21687 0, 7, 27, 10, 63, 39, 11, 0,
21688};
21689
21690static const uint8_t
21691WUFFS_JSON__LUT_CHARS[256]WUFFS_BASE__POTENTIALLY_UNUSED = {
21692 128, 129, 130, 131, 132, 133, 134, 135,
21693 136, 137, 138, 139, 140, 141, 142, 143,
21694 144, 145, 146, 147, 148, 149, 150, 151,
21695 152, 153, 154, 155, 156, 157, 158, 159,
21696 0, 0, 1, 0, 0, 0, 0, 0,
21697 0, 0, 0, 0, 0, 0, 0, 0,
21698 0, 0, 0, 0, 0, 0, 0, 0,
21699 0, 0, 0, 0, 0, 0, 0, 0,
21700 0, 0, 0, 0, 0, 0, 0, 0,
21701 0, 0, 0, 0, 0, 0, 0, 0,
21702 0, 0, 0, 0, 0, 0, 0, 0,
21703 0, 0, 0, 0, 2, 0, 0, 0,
21704 0, 0, 0, 0, 0, 0, 0, 0,
21705 0, 0, 0, 0, 0, 0, 0, 0,
21706 0, 0, 0, 0, 0, 0, 0, 0,
21707 0, 0, 0, 0, 0, 0, 0, 0,
21708 16, 16, 16, 16, 16, 16, 16, 16,
21709 16, 16, 16, 16, 16, 16, 16, 16,
21710 16, 16, 16, 16, 16, 16, 16, 16,
21711 16, 16, 16, 16, 16, 16, 16, 16,
21712 16, 16, 16, 16, 16, 16, 16, 16,
21713 16, 16, 16, 16, 16, 16, 16, 16,
21714 16, 16, 16, 16, 16, 16, 16, 16,
21715 16, 16, 16, 16, 16, 16, 16, 16,
21716 32, 32, 3, 3, 3, 3, 3, 3,
21717 3, 3, 3, 3, 3, 3, 3, 3,
21718 3, 3, 3, 3, 3, 3, 3, 3,
21719 3, 3, 3, 3, 3, 3, 3, 3,
21720 4, 4, 4, 4, 4, 4, 4, 4,
21721 4, 4, 4, 4, 4, 4, 4, 4,
21722 5, 5, 5, 5, 5, 32, 32, 32,
21723 32, 32, 32, 32, 32, 32, 32, 32,
21724};
21725
21726#define WUFFS_JSON__CLASS_WHITESPACE 0
21727
21728#define WUFFS_JSON__CLASS_STRING 1
21729
21730#define WUFFS_JSON__CLASS_COMMA 2
21731
21732#define WUFFS_JSON__CLASS_COLON 3
21733
21734#define WUFFS_JSON__CLASS_NUMBER 4
21735
21736#define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5
21737
21738#define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6
21739
21740#define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7
21741
21742#define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8
21743
21744#define WUFFS_JSON__CLASS_FALSE 9
21745
21746#define WUFFS_JSON__CLASS_TRUE 10
21747
21748#define WUFFS_JSON__CLASS_NULL_NAN_INF 11
21749
21750#define WUFFS_JSON__CLASS_COMMENT 12
21751
21752#define WUFFS_JSON__EXPECT_VALUE 7858
21753
21754#define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856
21755
21756#define WUFFS_JSON__EXPECT_STRING 4098
21757
21758#define WUFFS_JSON__EXPECT_COMMA 4100
21759
21760#define WUFFS_JSON__EXPECT_COLON 4104
21761
21762#define WUFFS_JSON__EXPECT_NUMBER 4112
21763
21764#define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160
21765
21766#define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352
21767
21768static const uint8_t
21769WUFFS_JSON__LUT_CLASSES[256]WUFFS_BASE__POTENTIALLY_UNUSED = {
21770 15, 15, 15, 15, 15, 15, 15, 15,
21771 15, 0, 0, 15, 15, 0, 15, 15,
21772 15, 15, 15, 15, 15, 15, 15, 15,
21773 15, 15, 15, 15, 15, 15, 15, 15,
21774 0, 15, 1, 15, 15, 15, 15, 15,
21775 15, 15, 15, 11, 2, 4, 15, 12,
21776 4, 4, 4, 4, 4, 4, 4, 4,
21777 4, 4, 3, 15, 15, 15, 15, 15,
21778 15, 15, 15, 15, 15, 15, 15, 15,
21779 15, 11, 15, 15, 15, 15, 11, 15,
21780 15, 15, 15, 15, 15, 15, 15, 15,
21781 15, 15, 15, 7, 15, 8, 15, 15,
21782 15, 15, 15, 15, 15, 15, 9, 15,
21783 15, 11, 15, 15, 15, 15, 11, 15,
21784 15, 15, 15, 15, 10, 15, 15, 15,
21785 15, 15, 15, 5, 15, 6, 15, 15,
21786 15, 15, 15, 15, 15, 15, 15, 15,
21787 15, 15, 15, 15, 15, 15, 15, 15,
21788 15, 15, 15, 15, 15, 15, 15, 15,
21789 15, 15, 15, 15, 15, 15, 15, 15,
21790 15, 15, 15, 15, 15, 15, 15, 15,
21791 15, 15, 15, 15, 15, 15, 15, 15,
21792 15, 15, 15, 15, 15, 15, 15, 15,
21793 15, 15, 15, 15, 15, 15, 15, 15,
21794 15, 15, 15, 15, 15, 15, 15, 15,
21795 15, 15, 15, 15, 15, 15, 15, 15,
21796 15, 15, 15, 15, 15, 15, 15, 15,
21797 15, 15, 15, 15, 15, 15, 15, 15,
21798 15, 15, 15, 15, 15, 15, 15, 15,
21799 15, 15, 15, 15, 15, 15, 15, 15,
21800 15, 15, 15, 15, 15, 15, 15, 15,
21801 15, 15, 15, 15, 15, 15, 15, 15,
21802};
21803
21804static const uint8_t
21805WUFFS_JSON__LUT_DECIMAL_DIGITS[256]WUFFS_BASE__POTENTIALLY_UNUSED = {
21806 0, 0, 0, 0, 0, 0, 0, 0,
21807 0, 0, 0, 0, 0, 0, 0, 0,
21808 0, 0, 0, 0, 0, 0, 0, 0,
21809 0, 0, 0, 0, 0, 0, 0, 0,
21810 0, 0, 0, 0, 0, 0, 0, 0,
21811 0, 0, 0, 0, 0, 0, 0, 0,
21812 128, 129, 130, 131, 132, 133, 134, 135,
21813 136, 137, 0, 0, 0, 0, 0, 0,
21814 0, 0, 0, 0, 0, 0, 0, 0,
21815 0, 0, 0, 0, 0, 0, 0, 0,
21816 0, 0, 0, 0, 0, 0, 0, 0,
21817 0, 0, 0, 0, 0, 0, 0, 0,
21818 0, 0, 0, 0, 0, 0, 0, 0,
21819 0, 0, 0, 0, 0, 0, 0, 0,
21820 0, 0, 0, 0, 0, 0, 0, 0,
21821 0, 0, 0, 0, 0, 0, 0, 0,
21822 0, 0, 0, 0, 0, 0, 0, 0,
21823 0, 0, 0, 0, 0, 0, 0, 0,
21824 0, 0, 0, 0, 0, 0, 0, 0,
21825 0, 0, 0, 0, 0, 0, 0, 0,
21826 0, 0, 0, 0, 0, 0, 0, 0,
21827 0, 0, 0, 0, 0, 0, 0, 0,
21828 0, 0, 0, 0, 0, 0, 0, 0,
21829 0, 0, 0, 0, 0, 0, 0, 0,
21830 0, 0, 0, 0, 0, 0, 0, 0,
21831 0, 0, 0, 0, 0, 0, 0, 0,
21832 0, 0, 0, 0, 0, 0, 0, 0,
21833 0, 0, 0, 0, 0, 0, 0, 0,
21834 0, 0, 0, 0, 0, 0, 0, 0,
21835 0, 0, 0, 0, 0, 0, 0, 0,
21836 0, 0, 0, 0, 0, 0, 0, 0,
21837 0, 0, 0, 0, 0, 0, 0, 0,
21838};
21839
21840static const uint8_t
21841WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256]WUFFS_BASE__POTENTIALLY_UNUSED = {
21842 0, 0, 0, 0, 0, 0, 0, 0,
21843 0, 0, 0, 0, 0, 0, 0, 0,
21844 0, 0, 0, 0, 0, 0, 0, 0,
21845 0, 0, 0, 0, 0, 0, 0, 0,
21846 0, 0, 0, 0, 0, 0, 0, 0,
21847 0, 0, 0, 0, 0, 0, 0, 0,
21848 128, 129, 130, 131, 132, 133, 134, 135,
21849 136, 137, 0, 0, 0, 0, 0, 0,
21850 0, 138, 139, 140, 141, 142, 143, 0,
21851 0, 0, 0, 0, 0, 0, 0, 0,
21852 0, 0, 0, 0, 0, 0, 0, 0,
21853 0, 0, 0, 0, 0, 0, 0, 0,
21854 0, 138, 139, 140, 141, 142, 143, 0,
21855 0, 0, 0, 0, 0, 0, 0, 0,
21856 0, 0, 0, 0, 0, 0, 0, 0,
21857 0, 0, 0, 0, 0, 0, 0, 0,
21858 0, 0, 0, 0, 0, 0, 0, 0,
21859 0, 0, 0, 0, 0, 0, 0, 0,
21860 0, 0, 0, 0, 0, 0, 0, 0,
21861 0, 0, 0, 0, 0, 0, 0, 0,
21862 0, 0, 0, 0, 0, 0, 0, 0,
21863 0, 0, 0, 0, 0, 0, 0, 0,
21864 0, 0, 0, 0, 0, 0, 0, 0,
21865 0, 0, 0, 0, 0, 0, 0, 0,
21866 0, 0, 0, 0, 0, 0, 0, 0,
21867 0, 0, 0, 0, 0, 0, 0, 0,
21868 0, 0, 0, 0, 0, 0, 0, 0,
21869 0, 0, 0, 0, 0, 0, 0, 0,
21870 0, 0, 0, 0, 0, 0, 0, 0,
21871 0, 0, 0, 0, 0, 0, 0, 0,
21872 0, 0, 0, 0, 0, 0, 0, 0,
21873 0, 0, 0, 0, 0, 0, 0, 0,
21874};
21875
21876#define WUFFS_JSON__QUIRKS_BASE 1225364480
21877
21878#define WUFFS_JSON__QUIRKS_COUNT 18
21879
21880// ---------------- Private Initializer Prototypes
21881
21882// ---------------- Private Function Prototypes
21883
21884static uint32_t
21885wuffs_json__decoder__decode_number(
21886 wuffs_json__decoder* self,
21887 wuffs_base__io_buffer* a_src);
21888
21889static uint32_t
21890wuffs_json__decoder__decode_digits(
21891 wuffs_json__decoder* self,
21892 wuffs_base__io_buffer* a_src,
21893 uint32_t a_n);
21894
21895static wuffs_base__status
21896wuffs_json__decoder__decode_leading(
21897 wuffs_json__decoder* self,
21898 wuffs_base__token_buffer* a_dst,
21899 wuffs_base__io_buffer* a_src);
21900
21901static wuffs_base__status
21902wuffs_json__decoder__decode_comment(
21903 wuffs_json__decoder* self,
21904 wuffs_base__token_buffer* a_dst,
21905 wuffs_base__io_buffer* a_src);
21906
21907static wuffs_base__status
21908wuffs_json__decoder__decode_inf_nan(
21909 wuffs_json__decoder* self,
21910 wuffs_base__token_buffer* a_dst,
21911 wuffs_base__io_buffer* a_src);
21912
21913static wuffs_base__status
21914wuffs_json__decoder__decode_trailing_new_line(
21915 wuffs_json__decoder* self,
21916 wuffs_base__token_buffer* a_dst,
21917 wuffs_base__io_buffer* a_src);
21918
21919// ---------------- VTables
21920
21921const wuffs_base__token_decoder__func_ptrs
21922wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
21923 (wuffs_base__status(*)(void*,
21924 wuffs_base__token_buffer*,
21925 wuffs_base__io_buffer*,
21926 wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens),
21927 (wuffs_base__empty_struct(*)(void*,
21928 uint32_t,
21929 bool))(&wuffs_json__decoder__set_quirk_enabled),
21930 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len),
21931};
21932
21933// ---------------- Initializer Implementations
21934
21935wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
21936wuffs_json__decoder__initialize(
21937 wuffs_json__decoder* self,
21938 size_t sizeof_star_self,
21939 uint64_t wuffs_version,
21940 uint32_t initialize_flags){
21941 if (!self) {
21942 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21943 }
21944 if (sizeof(*self) != sizeof_star_self) {
21945 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
21946 }
21947 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
21948 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
21949 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
21950 }
21951
21952 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
21953 // The whole point of this if-check is to detect an uninitialized *self.
21954 // We disable the warning on GCC. Clang-5.0 does not have this warning.
21955#if !defined(__clang__) && defined(__GNUC__)
21956#pragma GCC diagnostic push
21957#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
21958#endif
21959 if (self->private_impl.magic != 0) {
21960 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
21961 }
21962#if !defined(__clang__) && defined(__GNUC__)
21963#pragma GCC diagnostic pop
21964#endif
21965 } else {
21966 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
21967 memset(self, 0, sizeof(*self));
21968 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
21969 } else {
21970 memset(&(self->private_impl), 0, sizeof(self->private_impl));
21971 }
21972 }
21973
21974 self->private_impl.magic = WUFFS_BASE__MAGIC;
21975 self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
21976 wuffs_base__token_decoder__vtable_name;
21977 self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
21978 (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
21979 return wuffs_base__make_status(NULL);
21980}
21981
21982wuffs_json__decoder*
21983wuffs_json__decoder__alloc() {
21984 wuffs_json__decoder* x =
21985 (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
21986 if (!x) {
21987 return NULL;
21988 }
21989 if (wuffs_json__decoder__initialize(
21990 x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
21991 free(x);
21992 return NULL;
21993 }
21994 return x;
21995}
21996
21997size_t
21998sizeof__wuffs_json__decoder() {
21999 return sizeof(wuffs_json__decoder);
22000}
22001
22002// ---------------- Function Implementations
22003
22004// -------- func json.decoder.set_quirk_enabled
22005
22006WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
22007wuffs_json__decoder__set_quirk_enabled(
22008 wuffs_json__decoder* self,
22009 uint32_t a_quirk,
22010 bool a_enabled) {
22011 if (!self) {
22012 return wuffs_base__make_empty_struct();
22013 }
22014 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
22015 return wuffs_base__make_empty_struct();
22016 }
22017
22018 if (a_quirk >= 1225364480) {
22019 a_quirk -= 1225364480;
22020 if (a_quirk < 18) {
22021 self->private_impl.f_quirks[a_quirk] = a_enabled;
22022 }
22023 }
22024 return wuffs_base__make_empty_struct();
22025}
22026
22027// -------- func json.decoder.workbuf_len
22028
22029WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
22030wuffs_json__decoder__workbuf_len(
22031 const wuffs_json__decoder* self) {
22032 if (!self) {
22033 return wuffs_base__utility__empty_range_ii_u64();
22034 }
22035 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
22036 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
22037 return wuffs_base__utility__empty_range_ii_u64();
22038 }
22039
22040 return wuffs_base__utility__empty_range_ii_u64();
22041}
22042
22043// -------- func json.decoder.decode_tokens
22044
22045WUFFS_BASE__MAYBE_STATIC wuffs_base__status
22046wuffs_json__decoder__decode_tokens(
22047 wuffs_json__decoder* self,
22048 wuffs_base__token_buffer* a_dst,
22049 wuffs_base__io_buffer* a_src,
22050 wuffs_base__slice_u8 a_workbuf) {
22051 if (!self) {
22052 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22053 }
22054 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
22055 return wuffs_base__make_status(
22056 (self->private_impl.magic == WUFFS_BASE__DISABLED)
22057 ? wuffs_base__error__disabled_by_previous_error
22058 : wuffs_base__error__initialize_not_called);
22059 }
22060 if (!a_dst || !a_src) {
22061 self->private_impl.magic = WUFFS_BASE__DISABLED;
22062 return wuffs_base__make_status(wuffs_base__error__bad_argument);
22063 }
22064 if ((self->private_impl.active_coroutine != 0) &&
22065 (self->private_impl.active_coroutine != 1)) {
22066 self->private_impl.magic = WUFFS_BASE__DISABLED;
22067 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
22068 }
22069 self->private_impl.active_coroutine = 0;
22070 wuffs_base__status status = wuffs_base__make_status(NULL);
22071
22072 uint32_t v_vminor = 0;
22073 uint32_t v_number_length = 0;
22074 uint32_t v_number_status = 0;
22075 uint32_t v_string_length = 0;
22076 uint32_t v_whitespace_length = 0;
22077 uint32_t v_depth = 0;
22078 uint32_t v_stack_byte = 0;
22079 uint32_t v_stack_bit = 0;
22080 uint32_t v_match = 0;
22081 uint32_t v_c4 = 0;
22082 uint8_t v_c = 0;
22083 uint8_t v_backslash = 0;
22084 uint8_t v_char = 0;
22085 uint8_t v_class = 0;
22086 uint32_t v_multi_byte_utf8 = 0;
22087 uint32_t v_backslash_x_length = 0;
22088 uint8_t v_backslash_x_ok = 0;
22089 uint32_t v_backslash_x_string = 0;
22090 uint8_t v_uni4_ok = 0;
22091 uint64_t v_uni4_string = 0;
22092 uint32_t v_uni4_value = 0;
22093 uint32_t v_uni4_high_surrogate = 0;
22094 uint8_t v_uni8_ok = 0;
22095 uint64_t v_uni8_string = 0;
22096 uint32_t v_uni8_value = 0;
22097 uint32_t v_expect = 0;
22098 uint32_t v_expect_after_value = 0;
22099
22100 wuffs_base__token* iop_a_dst = NULL;
22101 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22102 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22103 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22104 if (a_dst) {
22105 io0_a_dst = a_dst->data.ptr;
22106 io1_a_dst = io0_a_dst + a_dst->meta.wi;
22107 iop_a_dst = io1_a_dst;
22108 io2_a_dst = io0_a_dst + a_dst->data.len;
22109 if (a_dst->meta.closed) {
22110 io2_a_dst = iop_a_dst;
22111 }
22112 }
22113 const uint8_t* iop_a_src = NULL;
22114 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22115 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22116 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22117 if (a_src) {
22118 io0_a_src = a_src->data.ptr;
22119 io1_a_src = io0_a_src + a_src->meta.ri;
22120 iop_a_src = io1_a_src;
22121 io2_a_src = io0_a_src + a_src->meta.wi;
22122 }
22123
22124 uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
22125 if (coro_susp_point) {
22126 v_depth = self->private_data.s_decode_tokens[0].v_depth;
22127 v_expect = self->private_data.s_decode_tokens[0].v_expect;
22128 v_expect_after_value = self->private_data.s_decode_tokens[0].v_expect_after_value;
22129 }
22130 switch (coro_susp_point) {
22131 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
22132
22133 if (self->private_impl.f_end_of_data) {
22134 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
22135 goto ok;
22136 }
22137 if (self->private_impl.f_quirks[14] || self->private_impl.f_quirks[15]) {
22138 if (a_dst) {
22139 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
22140 }
22141 if (a_src) {
22142 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22143 }
22144 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
22145 status = wuffs_json__decoder__decode_leading(self, a_dst, a_src);
22146 if (a_dst) {
22147 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
22148 }
22149 if (a_src) {
22150 iop_a_src = a_src->data.ptr + a_src->meta.ri;
22151 }
22152 if (status.repr) {
22153 goto suspend;
22154 }
22155 }
22156 v_expect = 7858;
22157 label__outer__continue:;
22158 while (true) {
22159 while (true) {
22160 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22161 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
22162 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
22163 goto label__outer__continue;
22164 }
22165 v_whitespace_length = 0;
22166 v_c = 0;
22167 v_class = 0;
22168 while (true) {
22169 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
22170 if (v_whitespace_length > 0) {
22171 *iop_a_dst++ = wuffs_base__make_token(
22172 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22173 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22174 v_whitespace_length = 0;
22175 }
22176 if (a_src && a_src->meta.closed) {
22177 status = wuffs_base__make_status(wuffs_json__error__bad_input);
22178 goto exit;
22179 }
22180 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22181 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
22182 v_whitespace_length = 0;
22183 goto label__outer__continue;
22184 }
22185 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
22186 v_class = WUFFS_JSON__LUT_CLASSES[v_c];
22187 if (v_class != 0) {
22188 goto label__ws__break;
22189 }
22190 (iop_a_src += 1, wuffs_base__make_empty_struct());
22191 if (v_whitespace_length >= 65534) {
22192 *iop_a_dst++ = wuffs_base__make_token(
22193 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22194 (((uint64_t)(65535)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22195 v_whitespace_length = 0;
22196 goto label__outer__continue;
22197 }
22198 v_whitespace_length += 1;
22199 }
22200 label__ws__break:;
22201 if (v_whitespace_length > 0) {
22202 *iop_a_dst++ = wuffs_base__make_token(
22203 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22204 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22205 v_whitespace_length = 0;
22206 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22207 goto label__outer__continue;
22208 }
22209 }
22210 if (0 == (v_expect & (((uint32_t)(1)) << v_class))) {
22211 status = wuffs_base__make_status(wuffs_json__error__bad_input);
22212 goto exit;
22213 }
22214 if (v_class == 1) {
22215 *iop_a_dst++ = wuffs_base__make_token(
22216 (((uint64_t)(4194323)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22217 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22218 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22219 (iop_a_src += 1, wuffs_base__make_empty_struct());
22220 label__string_loop_outer__continue:;
22221 while (true) {
22222 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22223 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
22224 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
22225 goto label__string_loop_outer__continue;
22226 }
22227 v_string_length = 0;
22228 label__string_loop_inner__continue:;
22229 while (true) {
22230 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
22231 if (v_string_length > 0) {
22232 *iop_a_dst++ = wuffs_base__make_token(
22233 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22234 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22235 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22236 v_string_length = 0;
22237 }
22238 if (a_src && a_src->meta.closed) {
22239 status = wuffs_base__make_status(wuffs_json__error__bad_input);
22240 goto exit;
22241 }
22242 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22243 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
22244 v_string_length = 0;
22245 goto label__string_loop_outer__continue;
22246 }
22247 while (((uint64_t)(io2_a_src - iop_a_src)) > 4) {
22248 v_c4 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
22249 if (0 != (WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 0))] |
22250 WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 8))] |
22251 WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 16))] |
22252 WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 24))])) {
22253 goto label__0__break;
22254 }
22255 (iop_a_src += 4, wuffs_base__make_empty_struct());
22256 if (v_string_length > 65527) {
22257 *iop_a_dst++ = wuffs_base__make_token(
22258 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22259 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22260 (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22261 v_string_length = 0;
22262 goto label__string_loop_outer__continue;
22263 }
22264 v_string_length += 4;
22265 }
22266 label__0__break:;
22267 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
22268 v_char = WUFFS_JSON__LUT_CHARS[v_c];
22269 if (v_char == 0) {
22270 (iop_a_src += 1, wuffs_base__make_empty_struct());
22271 if (v_string_length >= 65531) {
22272 *iop_a_dst++ = wuffs_base__make_token(
22273 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22274 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22275 (((uint64_t)(65532)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22276 v_string_length = 0;
22277 goto label__string_loop_outer__continue;
22278 }
22279 v_string_length += 1;
22280 goto label__string_loop_inner__continue;
22281 } else if (v_char == 1) {
22282 if (v_string_length != 0) {
22283 *iop_a_dst++ = wuffs_base__make_token(
22284 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22285 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22286 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22287 v_string_length = 0;
22288 }
22289 goto label__string_loop_outer__break;
22290 } else if (v_char == 2) {
22291 if (v_string_length > 0) {
22292 *iop_a_dst++ = wuffs_base__make_token(
22293 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22294 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22295 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22296 v_string_length = 0;
22297 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22298 goto label__string_loop_outer__continue;
22299 }
22300 }
22301 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
22302 if (a_src && a_src->meta.closed) {
22303 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
22304 goto exit;
22305 }
22306 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22307 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
22308 v_string_length = 0;
22309 v_char = 0;
22310 goto label__string_loop_outer__continue;
22311 }
22312 v_c = ((uint8_t)((wuffs_base__load_u16le__no_bounds_check(iop_a_src) >> 8)));
22313 v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c];
22314 if ((v_backslash & 128) != 0) {
22315 (iop_a_src += 2, wuffs_base__make_empty_struct());
22316 *iop_a_dst++ = wuffs_base__make_token(
22317 (((uint64_t)((6291456 | ((uint32_t)((v_backslash & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22318 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22319 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22320 goto label__string_loop_outer__continue;
22321 } else if (v_backslash != 0) {
22322 if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(v_backslash & 7)]]) {
22323 (iop_a_src += 2, wuffs_base__make_empty_struct());
22324 *iop_a_dst++ = wuffs_base__make_token(
22325 (((uint64_t)((6291456 | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(v_backslash & 7)]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22326 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22327 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22328 goto label__string_loop_outer__continue;
22329 }
22330 } else if (v_c == 117) {
22331 if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
22332 if (a_src && a_src->meta.closed) {
22333 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
22334 goto exit;
22335 }
22336 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22337 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
22338 v_string_length = 0;
22339 v_char = 0;
22340 goto label__string_loop_outer__continue;
22341 }
22342 v_uni4_string = (((uint64_t)(wuffs_base__load_u48le__no_bounds_check(iop_a_src))) >> 16);
22343 v_uni4_value = 0;
22344 v_uni4_ok = 128;
22345 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
22346 v_uni4_ok &= v_c;
22347 v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
22348 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
22349 v_uni4_ok &= v_c;
22350 v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
22351 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
22352 v_uni4_ok &= v_c;
22353 v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
22354 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
22355 v_uni4_ok &= v_c;
22356 v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
22357 if (v_uni4_ok == 0) {
22358 } else if ((v_uni4_value < 55296) || (57343 < v_uni4_value)) {
22359 (iop_a_src += 6, wuffs_base__make_empty_struct());
22360 *iop_a_dst++ = wuffs_base__make_token(
22361 (((uint64_t)((6291456 | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22362 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22363 (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22364 goto label__string_loop_outer__continue;
22365 } else if (v_uni4_value >= 56320) {
22366 } else {
22367 if (((uint64_t)(io2_a_src - iop_a_src)) < 12) {
22368 if (a_src && a_src->meta.closed) {
22369 if (self->private_impl.f_quirks[17]) {
22370 (iop_a_src += 6, wuffs_base__make_empty_struct());
22371 *iop_a_dst++ = wuffs_base__make_token(
22372 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22373 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22374 (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22375 goto label__string_loop_outer__continue;
22376 }
22377 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
22378 goto exit;
22379 }
22380 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22381 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
22382 v_string_length = 0;
22383 v_uni4_value = 0;
22384 v_char = 0;
22385 goto label__string_loop_outer__continue;
22386 }
22387 v_uni4_string = (wuffs_base__load_u64le__no_bounds_check(iop_a_src + 4) >> 16);
22388 if (((255 & (v_uni4_string >> 0)) != 92) || ((255 & (v_uni4_string >> 8)) != 117)) {
22389 v_uni4_high_surrogate = 0;
22390 v_uni4_value = 0;
22391 v_uni4_ok = 0;
22392 } else {
22393 v_uni4_high_surrogate = (65536 + ((v_uni4_value - 55296) << 10));
22394 v_uni4_value = 0;
22395 v_uni4_ok = 128;
22396 v_uni4_string >>= 16;
22397 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
22398 v_uni4_ok &= v_c;
22399 v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
22400 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
22401 v_uni4_ok &= v_c;
22402 v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
22403 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
22404 v_uni4_ok &= v_c;
22405 v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
22406 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
22407 v_uni4_ok &= v_c;
22408 v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
22409 }
22410 if ((v_uni4_ok != 0) && (56320 <= v_uni4_value) && (v_uni4_value <= 57343)) {
22411 v_uni4_value -= 56320;
22412 (iop_a_src += 12, wuffs_base__make_empty_struct());
22413 *iop_a_dst++ = wuffs_base__make_token(
22414 (((uint64_t)((6291456 | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22415 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22416 (((uint64_t)(12)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22417 goto label__string_loop_outer__continue;
22418 }
22419 }
22420 if (self->private_impl.f_quirks[17]) {
22421 if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
22422 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
22423 goto exit;
22424 }
22425 (iop_a_src += 6, wuffs_base__make_empty_struct());
22426 *iop_a_dst++ = wuffs_base__make_token(
22427 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22428 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22429 (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22430 goto label__string_loop_outer__continue;
22431 }
22432 } else if ((v_c == 85) && self->private_impl.f_quirks[2]) {
22433 if (((uint64_t)(io2_a_src - iop_a_src)) < 10) {
22434 if (a_src && a_src->meta.closed) {
22435 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
22436 goto exit;
22437 }
22438 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22439 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
22440 v_string_length = 0;
22441 v_char = 0;
22442 goto label__string_loop_outer__continue;
22443 }
22444 v_uni8_string = wuffs_base__load_u64le__no_bounds_check(iop_a_src + 2);
22445 v_uni8_value = 0;
22446 v_uni8_ok = 128;
22447 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 0))];
22448 v_uni8_ok &= v_c;
22449 v_uni8_value |= (((uint32_t)((v_c & 15))) << 28);
22450 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 8))];
22451 v_uni8_ok &= v_c;
22452 v_uni8_value |= (((uint32_t)((v_c & 15))) << 24);
22453 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 16))];
22454 v_uni8_ok &= v_c;
22455 v_uni8_value |= (((uint32_t)((v_c & 15))) << 20);
22456 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 24))];
22457 v_uni8_ok &= v_c;
22458 v_uni8_value |= (((uint32_t)((v_c & 15))) << 16);
22459 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 32))];
22460 v_uni8_ok &= v_c;
22461 v_uni8_value |= (((uint32_t)((v_c & 15))) << 12);
22462 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 40))];
22463 v_uni8_ok &= v_c;
22464 v_uni8_value |= (((uint32_t)((v_c & 15))) << 8);
22465 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 48))];
22466 v_uni8_ok &= v_c;
22467 v_uni8_value |= (((uint32_t)((v_c & 15))) << 4);
22468 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 56))];
22469 v_uni8_ok &= v_c;
22470 v_uni8_value |= (((uint32_t)((v_c & 15))) << 0);
22471 if (v_uni8_ok == 0) {
22472 } else if ((v_uni8_value < 55296) || ((57343 < v_uni8_value) && (v_uni8_value <= 1114111))) {
22473 (iop_a_src += 10, wuffs_base__make_empty_struct());
22474 *iop_a_dst++ = wuffs_base__make_token(
22475 (((uint64_t)((6291456 | (v_uni8_value & 2097151)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22476 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22477 (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22478 goto label__string_loop_outer__continue;
22479 } else if (self->private_impl.f_quirks[17]) {
22480 (iop_a_src += 10, wuffs_base__make_empty_struct());
22481 *iop_a_dst++ = wuffs_base__make_token(
22482 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22483 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22484 (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22485 goto label__string_loop_outer__continue;
22486 }
22487 } else if ((v_c == 120) && self->private_impl.f_quirks[8]) {
22488 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
22489 if (a_src && a_src->meta.closed) {
22490 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
22491 goto exit;
22492 }
22493 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22494 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
22495 v_string_length = 0;
22496 v_char = 0;
22497 goto label__string_loop_outer__continue;
22498 }
22499 v_backslash_x_length = 0;
22500 while ((v_backslash_x_length <= 65531) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
22501 v_backslash_x_string = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
22502 v_backslash_x_ok = 128;
22503 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 16))];
22504 v_backslash_x_ok &= v_c;
22505 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 24))];
22506 v_backslash_x_ok &= v_c;
22507 if ((v_backslash_x_ok == 0) || ((v_backslash_x_string & 65535) != 30812)) {
22508 goto label__1__break;
22509 }
22510 (iop_a_src += 4, wuffs_base__make_empty_struct());
22511 v_backslash_x_length += 4;
22512 }
22513 label__1__break:;
22514 if (v_backslash_x_length == 0) {
22515 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
22516 goto exit;
22517 }
22518 *iop_a_dst++ = wuffs_base__make_token(
22519 (((uint64_t)(4194432)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22520 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22521 (((uint64_t)(v_backslash_x_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22522 goto label__string_loop_outer__continue;
22523 }
22524 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
22525 goto exit;
22526 } else if (v_char == 3) {
22527 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
22528 if (v_string_length > 0) {
22529 *iop_a_dst++ = wuffs_base__make_token(
22530 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22531 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22532 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22533 v_string_length = 0;
22534 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22535 goto label__string_loop_outer__continue;
22536 }
22537 }
22538 if (a_src && a_src->meta.closed) {
22539 if (self->private_impl.f_quirks[17]) {
22540 *iop_a_dst++ = wuffs_base__make_token(
22541 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22542 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22543 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22544 (iop_a_src += 1, wuffs_base__make_empty_struct());
22545 goto label__string_loop_outer__continue;
22546 }
22547 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
22548 goto exit;
22549 }
22550 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22551 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
22552 v_string_length = 0;
22553 v_char = 0;
22554 goto label__string_loop_outer__continue;
22555 }
22556 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__load_u16le__no_bounds_check(iop_a_src)));
22557 if ((v_multi_byte_utf8 & 49152) == 32768) {
22558 v_multi_byte_utf8 = ((1984 & (v_multi_byte_utf8 << 6)) | (63 & (v_multi_byte_utf8 >> 8)));
22559 (iop_a_src += 2, wuffs_base__make_empty_struct());
22560 if (v_string_length >= 65528) {
22561 *iop_a_dst++ = wuffs_base__make_token(
22562 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22563 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22564 (((uint64_t)((v_string_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22565 v_string_length = 0;
22566 goto label__string_loop_outer__continue;
22567 }
22568 v_string_length += 2;
22569 goto label__string_loop_inner__continue;
22570 }
22571 } else if (v_char == 4) {
22572 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
22573 if (v_string_length > 0) {
22574 *iop_a_dst++ = wuffs_base__make_token(
22575 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22576 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22577 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22578 v_string_length = 0;
22579 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22580 goto label__string_loop_outer__continue;
22581 }
22582 }
22583 if (a_src && a_src->meta.closed) {
22584 if (self->private_impl.f_quirks[17]) {
22585 *iop_a_dst++ = wuffs_base__make_token(
22586 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22587 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22588 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22589 (iop_a_src += 1, wuffs_base__make_empty_struct());
22590 goto label__string_loop_outer__continue;
22591 }
22592 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
22593 goto exit;
22594 }
22595 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22596 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
22597 v_string_length = 0;
22598 v_char = 0;
22599 goto label__string_loop_outer__continue;
22600 }
22601 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__load_u24le__no_bounds_check(iop_a_src)));
22602 if ((v_multi_byte_utf8 & 12632064) == 8421376) {
22603 v_multi_byte_utf8 = ((61440 & (v_multi_byte_utf8 << 12)) | (4032 & (v_multi_byte_utf8 >> 2)) | (63 & (v_multi_byte_utf8 >> 16)));
22604 if ((2047 < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296) || (57343 < v_multi_byte_utf8))) {
22605 (iop_a_src += 3, wuffs_base__make_empty_struct());
22606 if (v_string_length >= 65528) {
22607 *iop_a_dst++ = wuffs_base__make_token(
22608 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22609 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22610 (((uint64_t)((v_string_length + 3))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22611 v_string_length = 0;
22612 goto label__string_loop_outer__continue;
22613 }
22614 v_string_length += 3;
22615 goto label__string_loop_inner__continue;
22616 }
22617 }
22618 } else if (v_char == 5) {
22619 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
22620 if (v_string_length > 0) {
22621 *iop_a_dst++ = wuffs_base__make_token(
22622 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22623 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22624 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22625 v_string_length = 0;
22626 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22627 goto label__string_loop_outer__continue;
22628 }
22629 }
22630 if (a_src && a_src->meta.closed) {
22631 if (self->private_impl.f_quirks[17]) {
22632 *iop_a_dst++ = wuffs_base__make_token(
22633 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22634 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22635 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22636 (iop_a_src += 1, wuffs_base__make_empty_struct());
22637 goto label__string_loop_outer__continue;
22638 }
22639 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
22640 goto exit;
22641 }
22642 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22643 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13);
22644 v_string_length = 0;
22645 v_char = 0;
22646 goto label__string_loop_outer__continue;
22647 }
22648 v_multi_byte_utf8 = wuffs_base__load_u32le__no_bounds_check(iop_a_src);
22649 if ((v_multi_byte_utf8 & 3233857536) == 2155905024) {
22650 v_multi_byte_utf8 = ((1835008 & (v_multi_byte_utf8 << 18)) |
22651 (258048 & (v_multi_byte_utf8 << 4)) |
22652 (4032 & (v_multi_byte_utf8 >> 10)) |
22653 (63 & (v_multi_byte_utf8 >> 24)));
22654 if ((65535 < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111)) {
22655 (iop_a_src += 4, wuffs_base__make_empty_struct());
22656 if (v_string_length >= 65528) {
22657 *iop_a_dst++ = wuffs_base__make_token(
22658 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22659 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22660 (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22661 v_string_length = 0;
22662 goto label__string_loop_outer__continue;
22663 }
22664 v_string_length += 4;
22665 goto label__string_loop_inner__continue;
22666 }
22667 }
22668 }
22669 if (v_string_length > 0) {
22670 *iop_a_dst++ = wuffs_base__make_token(
22671 (((uint64_t)(4194337)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22672 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22673 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22674 v_string_length = 0;
22675 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22676 goto label__string_loop_outer__continue;
22677 }
22678 }
22679 if ((v_char & 128) != 0) {
22680 if (self->private_impl.f_quirks[0]) {
22681 *iop_a_dst++ = wuffs_base__make_token(
22682 (((uint64_t)((6291456 | ((uint32_t)((v_char & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22683 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22684 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22685 (iop_a_src += 1, wuffs_base__make_empty_struct());
22686 goto label__string_loop_outer__continue;
22687 }
22688 status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
22689 goto exit;
22690 }
22691 if (self->private_impl.f_quirks[17]) {
22692 *iop_a_dst++ = wuffs_base__make_token(
22693 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22694 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
22695 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22696 (iop_a_src += 1, wuffs_base__make_empty_struct());
22697 goto label__string_loop_outer__continue;
22698 }
22699 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
22700 goto exit;
22701 }
22702 }
22703 label__string_loop_outer__break:;
22704 label__2__continue:;
22705 while (true) {
22706 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
22707 if (a_src && a_src->meta.closed) {
22708 status = wuffs_base__make_status(wuffs_json__error__bad_input);
22709 goto exit;
22710 }
22711 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22712 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14);
22713 goto label__2__continue;
22714 }
22715 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22716 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
22717 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15);
22718 goto label__2__continue;
22719 }
22720 (iop_a_src += 1, wuffs_base__make_empty_struct());
22721 *iop_a_dst++ = wuffs_base__make_token(
22722 (((uint64_t)(4194323)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22723 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22724 goto label__2__break;
22725 }
22726 label__2__break:;
22727 if (0 == (v_expect & (((uint32_t)(1)) << 4))) {
22728 v_expect = 4104;
22729 goto label__outer__continue;
22730 }
22731 goto label__goto_parsed_a_leaf_value__break;
22732 } else if (v_class == 2) {
22733 (iop_a_src += 1, wuffs_base__make_empty_struct());
22734 *iop_a_dst++ = wuffs_base__make_token(
22735 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22736 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22737 if (0 == (v_expect & (((uint32_t)(1)) << 8))) {
22738 if (self->private_impl.f_quirks[12]) {
22739 v_expect = 4162;
22740 } else {
22741 v_expect = 4098;
22742 }
22743 } else {
22744 if (self->private_impl.f_quirks[12]) {
22745 v_expect = 8114;
22746 } else {
22747 v_expect = 7858;
22748 }
22749 }
22750 goto label__outer__continue;
22751 } else if (v_class == 3) {
22752 (iop_a_src += 1, wuffs_base__make_empty_struct());
22753 *iop_a_dst++ = wuffs_base__make_token(
22754 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22755 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22756 v_expect = 7858;
22757 goto label__outer__continue;
22758 } else if (v_class == 4) {
22759 while (true) {
22760 if (a_src) {
22761 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22762 }
22763 v_number_length = wuffs_json__decoder__decode_number(self, a_src);
22764 if (a_src) {
22765 iop_a_src = a_src->data.ptr + a_src->meta.ri;
22766 }
22767 v_number_status = (v_number_length >> 8);
22768 v_vminor = 10486787;
22769 if ((v_number_length & 128) != 0) {
22770 v_vminor = 10486785;
22771 }
22772 v_number_length = (v_number_length & 127);
22773 if (v_number_status == 0) {
22774 *iop_a_dst++ = wuffs_base__make_token(
22775 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22776 (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22777 goto label__3__break;
22778 }
22779 while (v_number_length > 0) {
22780 v_number_length -= 1;
22781 if (iop_a_src > io1_a_src) {
22782 (iop_a_src--, wuffs_base__make_empty_struct());
22783 } else {
22784 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
22785 goto exit;
22786 }
22787 }
22788 if (v_number_status == 1) {
22789 if (self->private_impl.f_quirks[13]) {
22790 if (a_dst) {
22791 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
22792 }
22793 if (a_src) {
22794 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22795 }
22796 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
22797 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
22798 if (a_dst) {
22799 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
22800 }
22801 if (a_src) {
22802 iop_a_src = a_src->data.ptr + a_src->meta.ri;
22803 }
22804 if (status.repr) {
22805 goto suspend;
22806 }
22807 goto label__3__break;
22808 }
22809 status = wuffs_base__make_status(wuffs_json__error__bad_input);
22810 goto exit;
22811 } else if (v_number_status == 2) {
22812 status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length);
22813 goto exit;
22814 } else {
22815 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22816 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17);
22817 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
22818 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
22819 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18);
22820 }
22821 }
22822 }
22823 label__3__break:;
22824 goto label__goto_parsed_a_leaf_value__break;
22825 } else if (v_class == 5) {
22826 v_vminor = 2113553;
22827 if (v_depth == 0) {
22828 } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
22829 v_vminor = 2113601;
22830 } else {
22831 v_vminor = 2113569;
22832 }
22833 if (v_depth >= 1024) {
22834 status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
22835 goto exit;
22836 }
22837 v_stack_byte = (v_depth / 32);
22838 v_stack_bit = (v_depth & 31);
22839 self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1)) << v_stack_bit);
22840 v_depth += 1;
22841 (iop_a_src += 1, wuffs_base__make_empty_struct());
22842 *iop_a_dst++ = wuffs_base__make_token(
22843 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22844 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22845 v_expect = 4162;
22846 v_expect_after_value = 4164;
22847 goto label__outer__continue;
22848 } else if (v_class == 6) {
22849 (iop_a_src += 1, wuffs_base__make_empty_struct());
22850 if (v_depth <= 1) {
22851 *iop_a_dst++ = wuffs_base__make_token(
22852 (((uint64_t)(2101314)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22853 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22854 goto label__outer__break;
22855 }
22856 v_depth -= 1;
22857 v_stack_byte = ((v_depth - 1) / 32);
22858 v_stack_bit = ((v_depth - 1) & 31);
22859 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
22860 *iop_a_dst++ = wuffs_base__make_token(
22861 (((uint64_t)(2105410)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22862 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22863 v_expect = 4356;
22864 v_expect_after_value = 4356;
22865 } else {
22866 *iop_a_dst++ = wuffs_base__make_token(
22867 (((uint64_t)(2113602)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22868 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22869 v_expect = 4164;
22870 v_expect_after_value = 4164;
22871 }
22872 goto label__outer__continue;
22873 } else if (v_class == 7) {
22874 v_vminor = 2105361;
22875 if (v_depth == 0) {
22876 } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
22877 v_vminor = 2105409;
22878 } else {
22879 v_vminor = 2105377;
22880 }
22881 if (v_depth >= 1024) {
22882 status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
22883 goto exit;
22884 }
22885 v_stack_byte = (v_depth / 32);
22886 v_stack_bit = (v_depth & 31);
22887 self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(1)) << v_stack_bit));
22888 v_depth += 1;
22889 (iop_a_src += 1, wuffs_base__make_empty_struct());
22890 *iop_a_dst++ = wuffs_base__make_token(
22891 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22892 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22893 v_expect = 8114;
22894 v_expect_after_value = 4356;
22895 goto label__outer__continue;
22896 } else if (v_class == 8) {
22897 (iop_a_src += 1, wuffs_base__make_empty_struct());
22898 if (v_depth <= 1) {
22899 *iop_a_dst++ = wuffs_base__make_token(
22900 (((uint64_t)(2101282)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22901 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22902 goto label__outer__break;
22903 }
22904 v_depth -= 1;
22905 v_stack_byte = ((v_depth - 1) / 32);
22906 v_stack_bit = ((v_depth - 1) & 31);
22907 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
22908 *iop_a_dst++ = wuffs_base__make_token(
22909 (((uint64_t)(2105378)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22910 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22911 v_expect = 4356;
22912 v_expect_after_value = 4356;
22913 } else {
22914 *iop_a_dst++ = wuffs_base__make_token(
22915 (((uint64_t)(2113570)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22916 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22917 v_expect = 4164;
22918 v_expect_after_value = 4164;
22919 }
22920 goto label__outer__continue;
22921 } else if (v_class == 9) {
22922 v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,111546413966853);
22923 if (v_match == 0) {
22924 *iop_a_dst++ = wuffs_base__make_token(
22925 (((uint64_t)(8388612)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22926 (((uint64_t)(5)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22927 if (((uint64_t)(io2_a_src - iop_a_src)) < 5) {
22928 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
22929 goto exit;
22930 }
22931 (iop_a_src += 5, wuffs_base__make_empty_struct());
22932 goto label__goto_parsed_a_leaf_value__break;
22933 } else if (v_match == 1) {
22934 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22935 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19);
22936 goto label__outer__continue;
22937 }
22938 } else if (v_class == 10) {
22939 v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,435762131972);
22940 if (v_match == 0) {
22941 *iop_a_dst++ = wuffs_base__make_token(
22942 (((uint64_t)(8388616)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22943 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22944 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
22945 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
22946 goto exit;
22947 }
22948 (iop_a_src += 4, wuffs_base__make_empty_struct());
22949 goto label__goto_parsed_a_leaf_value__break;
22950 } else if (v_match == 1) {
22951 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22952 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20);
22953 goto label__outer__continue;
22954 }
22955 } else if (v_class == 11) {
22956 v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,465676103172);
22957 if (v_match == 0) {
22958 *iop_a_dst++ = wuffs_base__make_token(
22959 (((uint64_t)(8388610)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
22960 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
22961 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
22962 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
22963 goto exit;
22964 }
22965 (iop_a_src += 4, wuffs_base__make_empty_struct());
22966 goto label__goto_parsed_a_leaf_value__break;
22967 } else if (v_match == 1) {
22968 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22969 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
22970 goto label__outer__continue;
22971 }
22972 if (self->private_impl.f_quirks[13]) {
22973 if (a_dst) {
22974 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
22975 }
22976 if (a_src) {
22977 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22978 }
22979 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
22980 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
22981 if (a_dst) {
22982 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
22983 }
22984 if (a_src) {
22985 iop_a_src = a_src->data.ptr + a_src->meta.ri;
22986 }
22987 if (status.repr) {
22988 goto suspend;
22989 }
22990 goto label__goto_parsed_a_leaf_value__break;
22991 }
22992 } else if (v_class == 12) {
22993 if (self->private_impl.f_quirks[10] || self->private_impl.f_quirks[11]) {
22994 if (a_dst) {
22995 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
22996 }
22997 if (a_src) {
22998 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
22999 }
23000 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
23001 status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
23002 if (a_dst) {
23003 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
23004 }
23005 if (a_src) {
23006 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23007 }
23008 if (status.repr) {
23009 goto suspend;
23010 }
23011 goto label__outer__continue;
23012 }
23013 }
23014 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23015 goto exit;
23016 }
23017 label__goto_parsed_a_leaf_value__break:;
23018 if (v_depth == 0) {
23019 goto label__outer__break;
23020 }
23021 v_expect = v_expect_after_value;
23022 }
23023 label__outer__break:;
23024 if (self->private_impl.f_quirks[16]) {
23025 if (a_dst) {
23026 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
23027 }
23028 if (a_src) {
23029 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23030 }
23031 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
23032 status = wuffs_json__decoder__decode_trailing_new_line(self, a_dst, a_src);
23033 if (a_dst) {
23034 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
23035 }
23036 if (a_src) {
23037 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23038 }
23039 if (status.repr) {
23040 goto suspend;
23041 }
23042 }
23043 self->private_impl.f_end_of_data = true;
23044
23045 goto ok;
23046 ok:
23047 self->private_impl.p_decode_tokens[0] = 0;
23048 goto exit;
23049 }
23050
23051 goto suspend;
23052 suspend:
23053 self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23054 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
23055 self->private_data.s_decode_tokens[0].v_depth = v_depth;
23056 self->private_data.s_decode_tokens[0].v_expect = v_expect;
23057 self->private_data.s_decode_tokens[0].v_expect_after_value = v_expect_after_value;
23058
23059 goto exit;
23060 exit:
23061 if (a_dst) {
23062 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
23063 }
23064 if (a_src) {
23065 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23066 }
23067
23068 if (wuffs_base__status__is_error(&status)) {
23069 self->private_impl.magic = WUFFS_BASE__DISABLED;
23070 }
23071 return status;
23072}
23073
23074// -------- func json.decoder.decode_number
23075
23076static uint32_t
23077wuffs_json__decoder__decode_number(
23078 wuffs_json__decoder* self,
23079 wuffs_base__io_buffer* a_src) {
23080 uint8_t v_c = 0;
23081 uint32_t v_n = 0;
23082 uint32_t v_floating_point = 0;
23083
23084 const uint8_t* iop_a_src = NULL;
23085 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23086 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23087 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23088 if (a_src) {
23089 io0_a_src = a_src->data.ptr;
23090 io1_a_src = io0_a_src + a_src->meta.ri;
23091 iop_a_src = io1_a_src;
23092 io2_a_src = io0_a_src + a_src->meta.wi;
23093 }
23094
23095 while (true) {
23096 v_n = 0;
23097 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23098 if ( ! (a_src && a_src->meta.closed)) {
23099 v_n |= 768;
23100 }
23101 goto label__goto_done__break;
23102 }
23103 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23104 if (v_c != 45) {
23105 } else {
23106 v_n += 1;
23107 (iop_a_src += 1, wuffs_base__make_empty_struct());
23108 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23109 if ( ! (a_src && a_src->meta.closed)) {
23110 v_n |= 768;
23111 }
23112 v_n |= 256;
23113 goto label__goto_done__break;
23114 }
23115 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23116 }
23117 if (v_c == 48) {
23118 v_n += 1;
23119 (iop_a_src += 1, wuffs_base__make_empty_struct());
23120 } else {
23121 if (a_src) {
23122 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23123 }
23124 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
23125 if (a_src) {
23126 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23127 }
23128 if (v_n > 99) {
23129 goto label__goto_done__break;
23130 }
23131 }
23132 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23133 if ( ! (a_src && a_src->meta.closed)) {
23134 v_n |= 768;
23135 }
23136 goto label__goto_done__break;
23137 }
23138 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23139 if (v_c != 46) {
23140 } else {
23141 if (v_n >= 99) {
23142 v_n |= 512;
23143 goto label__goto_done__break;
23144 }
23145 v_n += 1;
23146 (iop_a_src += 1, wuffs_base__make_empty_struct());
23147 v_floating_point = 128;
23148 if (a_src) {
23149 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23150 }
23151 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
23152 if (a_src) {
23153 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23154 }
23155 if (v_n > 99) {
23156 goto label__goto_done__break;
23157 }
23158 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23159 if ( ! (a_src && a_src->meta.closed)) {
23160 v_n |= 768;
23161 }
23162 goto label__goto_done__break;
23163 }
23164 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23165 }
23166 if ((v_c != 69) && (v_c != 101)) {
23167 goto label__goto_done__break;
23168 }
23169 if (v_n >= 99) {
23170 v_n |= 512;
23171 goto label__goto_done__break;
23172 }
23173 v_n += 1;
23174 (iop_a_src += 1, wuffs_base__make_empty_struct());
23175 v_floating_point = 128;
23176 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23177 if ( ! (a_src && a_src->meta.closed)) {
23178 v_n |= 768;
23179 }
23180 v_n |= 256;
23181 goto label__goto_done__break;
23182 }
23183 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23184 if ((v_c != 43) && (v_c != 45)) {
23185 } else {
23186 if (v_n >= 99) {
23187 v_n |= 512;
23188 goto label__goto_done__break;
23189 }
23190 v_n += 1;
23191 (iop_a_src += 1, wuffs_base__make_empty_struct());
23192 }
23193 if (a_src) {
23194 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23195 }
23196 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
23197 if (a_src) {
23198 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23199 }
23200 goto label__goto_done__break;
23201 }
23202 label__goto_done__break:;
23203 if (a_src) {
23204 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23205 }
23206 return (v_n | v_floating_point);
23207}
23208
23209// -------- func json.decoder.decode_digits
23210
23211static uint32_t
23212wuffs_json__decoder__decode_digits(
23213 wuffs_json__decoder* self,
23214 wuffs_base__io_buffer* a_src,
23215 uint32_t a_n) {
23216 uint8_t v_c = 0;
23217 uint32_t v_n = 0;
23218
23219 const uint8_t* iop_a_src = NULL;
23220 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23221 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23222 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23223 if (a_src) {
23224 io0_a_src = a_src->data.ptr;
23225 io1_a_src = io0_a_src + a_src->meta.ri;
23226 iop_a_src = io1_a_src;
23227 io2_a_src = io0_a_src + a_src->meta.wi;
23228 }
23229
23230 v_n = a_n;
23231 while (true) {
23232 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23233 if ( ! (a_src && a_src->meta.closed)) {
23234 v_n |= 768;
23235 }
23236 goto label__0__break;
23237 }
23238 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23239 if (0 == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c]) {
23240 goto label__0__break;
23241 }
23242 if (v_n >= 99) {
23243 v_n |= 512;
23244 goto label__0__break;
23245 }
23246 v_n += 1;
23247 (iop_a_src += 1, wuffs_base__make_empty_struct());
23248 }
23249 label__0__break:;
23250 if (v_n == a_n) {
23251 v_n |= 256;
23252 }
23253 if (a_src) {
23254 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23255 }
23256 return v_n;
23257}
23258
23259// -------- func json.decoder.decode_leading
23260
23261static wuffs_base__status
23262wuffs_json__decoder__decode_leading(
23263 wuffs_json__decoder* self,
23264 wuffs_base__token_buffer* a_dst,
23265 wuffs_base__io_buffer* a_src) {
23266 wuffs_base__status status = wuffs_base__make_status(NULL);
23267
23268 uint8_t v_c = 0;
23269 uint32_t v_u = 0;
23270
23271 wuffs_base__token* iop_a_dst = NULL;
23272 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23273 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23274 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23275 if (a_dst) {
23276 io0_a_dst = a_dst->data.ptr;
23277 io1_a_dst = io0_a_dst + a_dst->meta.wi;
23278 iop_a_dst = io1_a_dst;
23279 io2_a_dst = io0_a_dst + a_dst->data.len;
23280 if (a_dst->meta.closed) {
23281 io2_a_dst = iop_a_dst;
23282 }
23283 }
23284 const uint8_t* iop_a_src = NULL;
23285 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23286 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23287 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23288 if (a_src) {
23289 io0_a_src = a_src->data.ptr;
23290 io1_a_src = io0_a_src + a_src->meta.ri;
23291 iop_a_src = io1_a_src;
23292 io2_a_src = io0_a_src + a_src->meta.wi;
23293 }
23294
23295 uint32_t coro_susp_point = self->private_impl.p_decode_leading[0];
23296 switch (coro_susp_point) {
23297 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23298
23299 self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[14];
23300 self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[15];
23301 label__0__continue:;
23302 while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) {
23303 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
23304 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
23305 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
23306 goto label__0__continue;
23307 }
23308 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23309 if (a_src && a_src->meta.closed) {
23310 goto label__0__break;
23311 }
23312 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23313 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
23314 goto label__0__continue;
23315 }
23316 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23317 if ((v_c == 30) && self->private_impl.f_allow_leading_ars) {
23318 self->private_impl.f_allow_leading_ars = false;
23319 (iop_a_src += 1, wuffs_base__make_empty_struct());
23320 *iop_a_dst++ = wuffs_base__make_token(
23321 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23322 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23323 goto label__0__continue;
23324 } else if ((v_c == 239) && self->private_impl.f_allow_leading_ubom) {
23325 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
23326 if (a_src && a_src->meta.closed) {
23327 goto label__0__break;
23328 }
23329 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23330 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
23331 goto label__0__continue;
23332 }
23333 v_u = ((uint32_t)(wuffs_base__load_u24le__no_bounds_check(iop_a_src)));
23334 if (v_u == 12565487) {
23335 self->private_impl.f_allow_leading_ubom = false;
23336 (iop_a_src += 3, wuffs_base__make_empty_struct());
23337 *iop_a_dst++ = wuffs_base__make_token(
23338 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23339 (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23340 goto label__0__continue;
23341 }
23342 }
23343 goto label__0__break;
23344 }
23345 label__0__break:;
23346
23347 goto ok;
23348 ok:
23349 self->private_impl.p_decode_leading[0] = 0;
23350 goto exit;
23351 }
23352
23353 goto suspend;
23354 suspend:
23355 self->private_impl.p_decode_leading[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23356
23357 goto exit;
23358 exit:
23359 if (a_dst) {
23360 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
23361 }
23362 if (a_src) {
23363 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23364 }
23365
23366 return status;
23367}
23368
23369// -------- func json.decoder.decode_comment
23370
23371static wuffs_base__status
23372wuffs_json__decoder__decode_comment(
23373 wuffs_json__decoder* self,
23374 wuffs_base__token_buffer* a_dst,
23375 wuffs_base__io_buffer* a_src) {
23376 wuffs_base__status status = wuffs_base__make_status(NULL);
23377
23378 uint8_t v_c = 0;
23379 uint16_t v_c2 = 0;
23380 uint32_t v_length = 0;
23381
23382 wuffs_base__token* iop_a_dst = NULL;
23383 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23384 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23385 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23386 if (a_dst) {
23387 io0_a_dst = a_dst->data.ptr;
23388 io1_a_dst = io0_a_dst + a_dst->meta.wi;
23389 iop_a_dst = io1_a_dst;
23390 io2_a_dst = io0_a_dst + a_dst->data.len;
23391 if (a_dst->meta.closed) {
23392 io2_a_dst = iop_a_dst;
23393 }
23394 }
23395 const uint8_t* iop_a_src = NULL;
23396 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23397 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23398 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23399 if (a_src) {
23400 io0_a_src = a_src->data.ptr;
23401 io1_a_src = io0_a_src + a_src->meta.ri;
23402 iop_a_src = io1_a_src;
23403 io2_a_src = io0_a_src + a_src->meta.wi;
23404 }
23405
23406 uint32_t coro_susp_point = self->private_impl.p_decode_comment[0];
23407 switch (coro_susp_point) {
23408 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23409
23410 label__0__continue:;
23411 while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1)) {
23412 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
23413 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
23414 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
23415 goto label__0__continue;
23416 }
23417 if (a_src && a_src->meta.closed) {
23418 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23419 goto exit;
23420 }
23421 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23422 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
23423 }
23424 v_c2 = wuffs_base__load_u16le__no_bounds_check(iop_a_src);
23425 if ((v_c2 == 10799) && self->private_impl.f_quirks[10]) {
23426 (iop_a_src += 2, wuffs_base__make_empty_struct());
23427 v_length = 2;
23428 label__comment_block__continue:;
23429 while (true) {
23430 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
23431 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
23432 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
23433 v_length = 0;
23434 goto label__comment_block__continue;
23435 }
23436 while (true) {
23437 if (((uint64_t)(io2_a_src - iop_a_src)) <= 1) {
23438 if (v_length > 0) {
23439 *iop_a_dst++ = wuffs_base__make_token(
23440 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23441 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
23442 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23443 }
23444 if (a_src && a_src->meta.closed) {
23445 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23446 goto exit;
23447 }
23448 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23449 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
23450 v_length = 0;
23451 goto label__comment_block__continue;
23452 }
23453 v_c2 = wuffs_base__load_u16le__no_bounds_check(iop_a_src);
23454 if (v_c2 == 12074) {
23455 (iop_a_src += 2, wuffs_base__make_empty_struct());
23456 *iop_a_dst++ = wuffs_base__make_token(
23457 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23458 (((uint64_t)((v_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23459 status = wuffs_base__make_status(NULL);
23460 goto ok;
23461 }
23462 (iop_a_src += 1, wuffs_base__make_empty_struct());
23463 if (v_length >= 65533) {
23464 *iop_a_dst++ = wuffs_base__make_token(
23465 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23466 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
23467 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23468 v_length = 0;
23469 goto label__comment_block__continue;
23470 }
23471 v_length += 1;
23472 }
23473 }
23474 } else if ((v_c2 == 12079) && self->private_impl.f_quirks[11]) {
23475 (iop_a_src += 2, wuffs_base__make_empty_struct());
23476 v_length = 2;
23477 label__comment_line__continue:;
23478 while (true) {
23479 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
23480 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
23481 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
23482 v_length = 0;
23483 goto label__comment_line__continue;
23484 }
23485 while (true) {
23486 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23487 if (v_length > 0) {
23488 *iop_a_dst++ = wuffs_base__make_token(
23489 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23490 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
23491 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23492 }
23493 if (a_src && a_src->meta.closed) {
23494 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23495 goto exit;
23496 }
23497 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23498 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
23499 v_length = 0;
23500 goto label__comment_line__continue;
23501 }
23502 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23503 if (v_c == 10) {
23504 (iop_a_src += 1, wuffs_base__make_empty_struct());
23505 *iop_a_dst++ = wuffs_base__make_token(
23506 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23507 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23508 status = wuffs_base__make_status(NULL);
23509 goto ok;
23510 }
23511 (iop_a_src += 1, wuffs_base__make_empty_struct());
23512 if (v_length >= 65533) {
23513 *iop_a_dst++ = wuffs_base__make_token(
23514 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23515 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
23516 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23517 v_length = 0;
23518 goto label__comment_line__continue;
23519 }
23520 v_length += 1;
23521 }
23522 }
23523 }
23524 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23525 goto exit;
23526
23527 goto ok;
23528 ok:
23529 self->private_impl.p_decode_comment[0] = 0;
23530 goto exit;
23531 }
23532
23533 goto suspend;
23534 suspend:
23535 self->private_impl.p_decode_comment[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23536
23537 goto exit;
23538 exit:
23539 if (a_dst) {
23540 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
23541 }
23542 if (a_src) {
23543 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23544 }
23545
23546 return status;
23547}
23548
23549// -------- func json.decoder.decode_inf_nan
23550
23551static wuffs_base__status
23552wuffs_json__decoder__decode_inf_nan(
23553 wuffs_json__decoder* self,
23554 wuffs_base__token_buffer* a_dst,
23555 wuffs_base__io_buffer* a_src) {
23556 wuffs_base__status status = wuffs_base__make_status(NULL);
23557
23558 uint32_t v_c4 = 0;
23559 uint32_t v_neg = 0;
23560
23561 wuffs_base__token* iop_a_dst = NULL;
23562 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23563 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23564 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23565 if (a_dst) {
23566 io0_a_dst = a_dst->data.ptr;
23567 io1_a_dst = io0_a_dst + a_dst->meta.wi;
23568 iop_a_dst = io1_a_dst;
23569 io2_a_dst = io0_a_dst + a_dst->data.len;
23570 if (a_dst->meta.closed) {
23571 io2_a_dst = iop_a_dst;
23572 }
23573 }
23574 const uint8_t* iop_a_src = NULL;
23575 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23576 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23577 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23578 if (a_src) {
23579 io0_a_src = a_src->data.ptr;
23580 io1_a_src = io0_a_src + a_src->meta.ri;
23581 iop_a_src = io1_a_src;
23582 io2_a_src = io0_a_src + a_src->meta.wi;
23583 }
23584
23585 uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan[0];
23586 if (coro_susp_point) {
23587 v_neg = self->private_data.s_decode_inf_nan[0].v_neg;
23588 }
23589 switch (coro_susp_point) {
23590 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23591
23592 label__0__continue:;
23593 while (true) {
23594 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
23595 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
23596 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
23597 goto label__0__continue;
23598 }
23599 if (((uint64_t)(io2_a_src - iop_a_src)) <= 2) {
23600 if (a_src && a_src->meta.closed) {
23601 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23602 goto exit;
23603 }
23604 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23605 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
23606 goto label__0__continue;
23607 }
23608 v_c4 = ((uint32_t)(wuffs_base__load_u24le__no_bounds_check(iop_a_src)));
23609 if ((v_c4 | 2105376) == 6712937) {
23610 if (((uint64_t)(io2_a_src - iop_a_src)) > 7) {
23611 if ((wuffs_base__load_u64le__no_bounds_check(iop_a_src) | 2314885530818453536) == 8751735898823356009) {
23612 *iop_a_dst++ = wuffs_base__make_token(
23613 (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23614 (((uint64_t)(8)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23615 (iop_a_src += 8, wuffs_base__make_empty_struct());
23616 status = wuffs_base__make_status(NULL);
23617 goto ok;
23618 }
23619 } else if ( ! (a_src && a_src->meta.closed)) {
23620 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23621 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
23622 goto label__0__continue;
23623 }
23624 *iop_a_dst++ = wuffs_base__make_token(
23625 (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23626 (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23627 (iop_a_src += 3, wuffs_base__make_empty_struct());
23628 status = wuffs_base__make_status(NULL);
23629 goto ok;
23630 } else if ((v_c4 | 2105376) == 7233902) {
23631 *iop_a_dst++ = wuffs_base__make_token(
23632 (((uint64_t)(10485888)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23633 (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23634 (iop_a_src += 3, wuffs_base__make_empty_struct());
23635 status = wuffs_base__make_status(NULL);
23636 goto ok;
23637 } else if ((v_c4 & 255) == 43) {
23638 v_neg = 0;
23639 } else if ((v_c4 & 255) == 45) {
23640 v_neg = 1;
23641 } else {
23642 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23643 goto exit;
23644 }
23645 if (((uint64_t)(io2_a_src - iop_a_src)) <= 3) {
23646 if (a_src && a_src->meta.closed) {
23647 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23648 goto exit;
23649 }
23650 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23651 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
23652 goto label__0__continue;
23653 }
23654 v_c4 = (wuffs_base__load_u32le__no_bounds_check(iop_a_src) >> 8);
23655 if ((v_c4 | 2105376) == 6712937) {
23656 if (((uint64_t)(io2_a_src - iop_a_src)) > 8) {
23657 if ((wuffs_base__load_u64le__no_bounds_check(iop_a_src + 1) | 2314885530818453536) == 8751735898823356009) {
23658 *iop_a_dst++ = wuffs_base__make_token(
23659 (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23660 (((uint64_t)(9)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23661 (iop_a_src += 9, wuffs_base__make_empty_struct());
23662 status = wuffs_base__make_status(NULL);
23663 goto ok;
23664 }
23665 } else if ( ! (a_src && a_src->meta.closed)) {
23666 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23667 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
23668 goto label__0__continue;
23669 }
23670 *iop_a_dst++ = wuffs_base__make_token(
23671 (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23672 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23673 (iop_a_src += 4, wuffs_base__make_empty_struct());
23674 status = wuffs_base__make_status(NULL);
23675 goto ok;
23676 } else if ((v_c4 | 2105376) == 7233902) {
23677 *iop_a_dst++ = wuffs_base__make_token(
23678 (((uint64_t)((10485760 | (((uint32_t)(128)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23679 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23680 (iop_a_src += 4, wuffs_base__make_empty_struct());
23681 status = wuffs_base__make_status(NULL);
23682 goto ok;
23683 }
23684 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23685 goto exit;
23686 }
23687
23688 goto ok;
23689 ok:
23690 self->private_impl.p_decode_inf_nan[0] = 0;
23691 goto exit;
23692 }
23693
23694 goto suspend;
23695 suspend:
23696 self->private_impl.p_decode_inf_nan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23697 self->private_data.s_decode_inf_nan[0].v_neg = v_neg;
23698
23699 goto exit;
23700 exit:
23701 if (a_dst) {
23702 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
23703 }
23704 if (a_src) {
23705 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23706 }
23707
23708 return status;
23709}
23710
23711// -------- func json.decoder.decode_trailing_new_line
23712
23713static wuffs_base__status
23714wuffs_json__decoder__decode_trailing_new_line(
23715 wuffs_json__decoder* self,
23716 wuffs_base__token_buffer* a_dst,
23717 wuffs_base__io_buffer* a_src) {
23718 wuffs_base__status status = wuffs_base__make_status(NULL);
23719
23720 uint8_t v_c = 0;
23721 uint32_t v_whitespace_length = 0;
23722
23723 wuffs_base__token* iop_a_dst = NULL;
23724 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23725 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23726 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23727 if (a_dst) {
23728 io0_a_dst = a_dst->data.ptr;
23729 io1_a_dst = io0_a_dst + a_dst->meta.wi;
23730 iop_a_dst = io1_a_dst;
23731 io2_a_dst = io0_a_dst + a_dst->data.len;
23732 if (a_dst->meta.closed) {
23733 io2_a_dst = iop_a_dst;
23734 }
23735 }
23736 const uint8_t* iop_a_src = NULL;
23737 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23738 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23739 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23740 if (a_src) {
23741 io0_a_src = a_src->data.ptr;
23742 io1_a_src = io0_a_src + a_src->meta.ri;
23743 iop_a_src = io1_a_src;
23744 io2_a_src = io0_a_src + a_src->meta.wi;
23745 }
23746
23747 uint32_t coro_susp_point = self->private_impl.p_decode_trailing_new_line[0];
23748 switch (coro_susp_point) {
23749 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23750
23751 label__outer__continue:;
23752 while (true) {
23753 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
23754 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
23755 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
23756 v_whitespace_length = 0;
23757 goto label__outer__continue;
23758 }
23759 while (true) {
23760 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23761 if (v_whitespace_length > 0) {
23762 *iop_a_dst++ = wuffs_base__make_token(
23763 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23764 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23765 v_whitespace_length = 0;
23766 }
23767 if (a_src && a_src->meta.closed) {
23768 goto label__outer__break;
23769 }
23770 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23771 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
23772 v_whitespace_length = 0;
23773 goto label__outer__continue;
23774 }
23775 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
23776 if (WUFFS_JSON__LUT_CLASSES[v_c] != 0) {
23777 if (v_whitespace_length > 0) {
23778 *iop_a_dst++ = wuffs_base__make_token(
23779 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23780 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23781 v_whitespace_length = 0;
23782 }
23783 status = wuffs_base__make_status(wuffs_json__error__bad_input);
23784 goto exit;
23785 }
23786 (iop_a_src += 1, wuffs_base__make_empty_struct());
23787 if ((v_whitespace_length >= 65534) || (v_c == 10)) {
23788 *iop_a_dst++ = wuffs_base__make_token(
23789 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
23790 (((uint64_t)((v_whitespace_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
23791 v_whitespace_length = 0;
23792 if (v_c == 10) {
23793 goto label__outer__break;
23794 }
23795 goto label__outer__continue;
23796 }
23797 v_whitespace_length += 1;
23798 }
23799 }
23800 label__outer__break:;
23801
23802 goto ok;
23803 ok:
23804 self->private_impl.p_decode_trailing_new_line[0] = 0;
23805 goto exit;
23806 }
23807
23808 goto suspend;
23809 suspend:
23810 self->private_impl.p_decode_trailing_new_line[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23811
23812 goto exit;
23813 exit:
23814 if (a_dst) {
23815 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
23816 }
23817 if (a_src) {
23818 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23819 }
23820
23821 return status;
23822}
23823
23824#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
23825
23826#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
23827
23828// ---------------- Status Codes Implementations
23829
23830const char* wuffs_wbmp__error__bad_header = "#wbmp: bad header";
23831
23832// ---------------- Private Consts
23833
23834// ---------------- Private Initializer Prototypes
23835
23836// ---------------- Private Function Prototypes
23837
23838static wuffs_base__status
23839wuffs_wbmp__decoder__skip_frame(
23840 wuffs_wbmp__decoder* self,
23841 wuffs_base__io_buffer* a_src);
23842
23843// ---------------- VTables
23844
23845const wuffs_base__image_decoder__func_ptrs
23846wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
23847 (wuffs_base__status(*)(void*,
23848 wuffs_base__pixel_buffer*,
23849 wuffs_base__io_buffer*,
23850 wuffs_base__pixel_blend,
23851 wuffs_base__slice_u8,
23852 wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame),
23853 (wuffs_base__status(*)(void*,
23854 wuffs_base__frame_config*,
23855 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config),
23856 (wuffs_base__status(*)(void*,
23857 wuffs_base__image_config*,
23858 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config),
23859 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect),
23860 (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops),
23861 (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs),
23862 (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames),
23863 (wuffs_base__status(*)(void*,
23864 uint64_t,
23865 uint64_t))(&wuffs_wbmp__decoder__restart_frame),
23866 (wuffs_base__empty_struct(*)(void*,
23867 uint32_t,
23868 bool))(&wuffs_wbmp__decoder__set_quirk_enabled),
23869 (wuffs_base__empty_struct(*)(void*,
23870 uint32_t,
23871 bool))(&wuffs_wbmp__decoder__set_report_metadata),
23872 (wuffs_base__status(*)(void*,
23873 wuffs_base__io_buffer*,
23874 wuffs_base__more_information*,
23875 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more),
23876 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len),
23877};
23878
23879// ---------------- Initializer Implementations
23880
23881wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
23882wuffs_wbmp__decoder__initialize(
23883 wuffs_wbmp__decoder* self,
23884 size_t sizeof_star_self,
23885 uint64_t wuffs_version,
23886 uint32_t initialize_flags){
23887 if (!self) {
23888 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23889 }
23890 if (sizeof(*self) != sizeof_star_self) {
23891 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
23892 }
23893 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
23894 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
23895 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
23896 }
23897
23898 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
23899 // The whole point of this if-check is to detect an uninitialized *self.
23900 // We disable the warning on GCC. Clang-5.0 does not have this warning.
23901#if !defined(__clang__) && defined(__GNUC__)
23902#pragma GCC diagnostic push
23903#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
23904#endif
23905 if (self->private_impl.magic != 0) {
23906 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
23907 }
23908#if !defined(__clang__) && defined(__GNUC__)
23909#pragma GCC diagnostic pop
23910#endif
23911 } else {
23912 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
23913 memset(self, 0, sizeof(*self));
23914 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
23915 } else {
23916 memset(&(self->private_impl), 0, sizeof(self->private_impl));
23917 }
23918 }
23919
23920 self->private_impl.magic = WUFFS_BASE__MAGIC;
23921 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
23922 wuffs_base__image_decoder__vtable_name;
23923 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
23924 (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
23925 return wuffs_base__make_status(NULL);
23926}
23927
23928wuffs_wbmp__decoder*
23929wuffs_wbmp__decoder__alloc() {
23930 wuffs_wbmp__decoder* x =
23931 (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
23932 if (!x) {
23933 return NULL;
23934 }
23935 if (wuffs_wbmp__decoder__initialize(
23936 x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
23937 free(x);
23938 return NULL;
23939 }
23940 return x;
23941}
23942
23943size_t
23944sizeof__wuffs_wbmp__decoder() {
23945 return sizeof(wuffs_wbmp__decoder);
23946}
23947
23948// ---------------- Function Implementations
23949
23950// -------- func wbmp.decoder.set_quirk_enabled
23951
23952WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
23953wuffs_wbmp__decoder__set_quirk_enabled(
23954 wuffs_wbmp__decoder* self,
23955 uint32_t a_quirk,
23956 bool a_enabled) {
23957 return wuffs_base__make_empty_struct();
23958}
23959
23960// -------- func wbmp.decoder.decode_image_config
23961
23962WUFFS_BASE__MAYBE_STATIC wuffs_base__status
23963wuffs_wbmp__decoder__decode_image_config(
23964 wuffs_wbmp__decoder* self,
23965 wuffs_base__image_config* a_dst,
23966 wuffs_base__io_buffer* a_src) {
23967 if (!self) {
23968 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23969 }
23970 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
23971 return wuffs_base__make_status(
23972 (self->private_impl.magic == WUFFS_BASE__DISABLED)
23973 ? wuffs_base__error__disabled_by_previous_error
23974 : wuffs_base__error__initialize_not_called);
23975 }
23976 if (!a_src) {
23977 self->private_impl.magic = WUFFS_BASE__DISABLED;
23978 return wuffs_base__make_status(wuffs_base__error__bad_argument);
23979 }
23980 if ((self->private_impl.active_coroutine != 0) &&
23981 (self->private_impl.active_coroutine != 1)) {
23982 self->private_impl.magic = WUFFS_BASE__DISABLED;
23983 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
23984 }
23985 self->private_impl.active_coroutine = 0;
23986 wuffs_base__status status = wuffs_base__make_status(NULL);
23987
23988 uint8_t v_c = 0;
23989 uint32_t v_i = 0;
23990 uint32_t v_x32 = 0;
23991 uint64_t v_x64 = 0;
23992
23993 const uint8_t* iop_a_src = NULL;
23994 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23995 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23996 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23997 if (a_src) {
23998 io0_a_src = a_src->data.ptr;
23999 io1_a_src = io0_a_src + a_src->meta.ri;
24000 iop_a_src = io1_a_src;
24001 io2_a_src = io0_a_src + a_src->meta.wi;
24002 }
24003
24004 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
24005 if (coro_susp_point) {
24006 v_i = self->private_data.s_decode_image_config[0].v_i;
24007 v_x32 = self->private_data.s_decode_image_config[0].v_x32;
24008 }
24009 switch (coro_susp_point) {
24010 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24011
24012 if (self->private_impl.f_call_sequence != 0) {
24013 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
24014 goto exit;
24015 }
24016 v_i = 0;
24017 while (v_i < 2) {
24018 {
24019 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
24020 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24021 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24022 goto suspend;
24023 }
24024 uint8_t t_0 = *iop_a_src++;
24025 v_c = t_0;
24026 }
24027 if (v_c != 0) {
24028 status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
24029 goto exit;
24030 }
24031 v_i += 1;
24032 }
24033 v_i = 0;
24034 while (v_i < 2) {
24035 v_x32 = 0;
24036 while (true) {
24037 {
24038 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
24039 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24040 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24041 goto suspend;
24042 }
24043 uint8_t t_1 = *iop_a_src++;
24044 v_c = t_1;
24045 }
24046 v_x32 |= ((uint32_t)((v_c & 127)));
24047 if ((v_c >> 7) == 0) {
24048 goto label__0__break;
24049 }
24050 v_x64 = (((uint64_t)(v_x32)) << 7);
24051 if (v_x64 > 4294967295) {
24052 status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
24053 goto exit;
24054 }
24055 v_x32 = ((uint32_t)(v_x64));
24056 }
24057 label__0__break:;
24058 if (v_i == 0) {
24059 self->private_impl.f_width = v_x32;
24060 } else {
24061 self->private_impl.f_height = v_x32;
24062 }
24063 v_i += 1;
24064 }
24065 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)));
24066 if (a_dst != NULL) {
24067 wuffs_base__image_config__set(
24068 a_dst,
24069 2198077448,
24070 0,
24071 self->private_impl.f_width,
24072 self->private_impl.f_height,
24073 self->private_impl.f_frame_config_io_position,
24074 true);
24075 }
24076 self->private_impl.f_call_sequence = 1;
24077
24078 goto ok;
24079 ok:
24080 self->private_impl.p_decode_image_config[0] = 0;
24081 goto exit;
24082 }
24083
24084 goto suspend;
24085 suspend:
24086 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
24087 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
24088 self->private_data.s_decode_image_config[0].v_i = v_i;
24089 self->private_data.s_decode_image_config[0].v_x32 = v_x32;
24090
24091 goto exit;
24092 exit:
24093 if (a_src) {
24094 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24095 }
24096
24097 if (wuffs_base__status__is_error(&status)) {
24098 self->private_impl.magic = WUFFS_BASE__DISABLED;
24099 }
24100 return status;
24101}
24102
24103// -------- func wbmp.decoder.decode_frame_config
24104
24105WUFFS_BASE__MAYBE_STATIC wuffs_base__status
24106wuffs_wbmp__decoder__decode_frame_config(
24107 wuffs_wbmp__decoder* self,
24108 wuffs_base__frame_config* a_dst,
24109 wuffs_base__io_buffer* a_src) {
24110 if (!self) {
24111 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24112 }
24113 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24114 return wuffs_base__make_status(
24115 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24116 ? wuffs_base__error__disabled_by_previous_error
24117 : wuffs_base__error__initialize_not_called);
24118 }
24119 if (!a_src) {
24120 self->private_impl.magic = WUFFS_BASE__DISABLED;
24121 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24122 }
24123 if ((self->private_impl.active_coroutine != 0) &&
24124 (self->private_impl.active_coroutine != 2)) {
24125 self->private_impl.magic = WUFFS_BASE__DISABLED;
24126 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24127 }
24128 self->private_impl.active_coroutine = 0;
24129 wuffs_base__status status = wuffs_base__make_status(NULL);
24130
24131 const uint8_t* iop_a_src = NULL;
24132 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24133 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24134 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24135 if (a_src) {
24136 io0_a_src = a_src->data.ptr;
24137 io1_a_src = io0_a_src + a_src->meta.ri;
24138 iop_a_src = io1_a_src;
24139 io2_a_src = io0_a_src + a_src->meta.wi;
24140 }
24141
24142 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
24143 switch (coro_susp_point) {
24144 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24145
24146 if (self->private_impl.f_call_sequence < 1) {
24147 if (a_src) {
24148 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24149 }
24150 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
24151 status = wuffs_wbmp__decoder__decode_image_config(self, NULL, a_src);
24152 if (a_src) {
24153 iop_a_src = a_src->data.ptr + a_src->meta.ri;
24154 }
24155 if (status.repr) {
24156 goto suspend;
24157 }
24158 } else if (self->private_impl.f_call_sequence == 1) {
24159 if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add(a_src->meta.pos, ((uint64_t)(iop_a_src - io0_a_src)))) {
24160 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
24161 goto exit;
24162 }
24163 } else if (self->private_impl.f_call_sequence == 2) {
24164 if (a_src) {
24165 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24166 }
24167 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
24168 status = wuffs_wbmp__decoder__skip_frame(self, a_src);
24169 if (a_src) {
24170 iop_a_src = a_src->data.ptr + a_src->meta.ri;
24171 }
24172 if (status.repr) {
24173 goto suspend;
24174 }
24175 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
24176 goto ok;
24177 } else {
24178 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
24179 goto ok;
24180 }
24181 if (a_dst != NULL) {
24182 wuffs_base__frame_config__set(
24183 a_dst,
24184 wuffs_base__utility__make_rect_ie_u32(
24185 0,
24186 0,
24187 self->private_impl.f_width,
24188 self->private_impl.f_height),
24189 ((wuffs_base__flicks)(0)),
24190 0,
24191 self->private_impl.f_frame_config_io_position,
24192 0,
24193 true,
24194 false,
24195 4278190080);
24196 }
24197 self->private_impl.f_call_sequence = 2;
24198
24199 goto ok;
24200 ok:
24201 self->private_impl.p_decode_frame_config[0] = 0;
24202 goto exit;
24203 }
24204
24205 goto suspend;
24206 suspend:
24207 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
24208 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
24209
24210 goto exit;
24211 exit:
24212 if (a_src) {
24213 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24214 }
24215
24216 if (wuffs_base__status__is_error(&status)) {
24217 self->private_impl.magic = WUFFS_BASE__DISABLED;
24218 }
24219 return status;
24220}
24221
24222// -------- func wbmp.decoder.decode_frame
24223
24224WUFFS_BASE__MAYBE_STATIC wuffs_base__status
24225wuffs_wbmp__decoder__decode_frame(
24226 wuffs_wbmp__decoder* self,
24227 wuffs_base__pixel_buffer* a_dst,
24228 wuffs_base__io_buffer* a_src,
24229 wuffs_base__pixel_blend a_blend,
24230 wuffs_base__slice_u8 a_workbuf,
24231 wuffs_base__decode_frame_options* a_opts) {
24232 if (!self) {
24233 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24234 }
24235 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24236 return wuffs_base__make_status(
24237 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24238 ? wuffs_base__error__disabled_by_previous_error
24239 : wuffs_base__error__initialize_not_called);
24240 }
24241 if (!a_dst || !a_src) {
24242 self->private_impl.magic = WUFFS_BASE__DISABLED;
24243 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24244 }
24245 if ((self->private_impl.active_coroutine != 0) &&
24246 (self->private_impl.active_coroutine != 3)) {
24247 self->private_impl.magic = WUFFS_BASE__DISABLED;
24248 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24249 }
24250 self->private_impl.active_coroutine = 0;
24251 wuffs_base__status status = wuffs_base__make_status(NULL);
24252
24253 wuffs_base__status v_status = wuffs_base__make_status(NULL);
24254 wuffs_base__pixel_format v_dst_pixfmt = {0};
24255 uint32_t v_dst_bits_per_pixel = 0;
24256 uint64_t v_dst_bytes_per_pixel = 0;
24257 uint64_t v_dst_x_in_bytes = 0;
24258 uint32_t v_dst_x = 0;
24259 uint32_t v_dst_y = 0;
24260 wuffs_base__table_u8 v_tab = {0};
24261 wuffs_base__slice_u8 v_dst = {0};
24262 uint8_t v_src[1] = {0};
24263 uint8_t v_c = 0;
24264
24265 const uint8_t* iop_a_src = NULL;
24266 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24267 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24268 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24269 if (a_src) {
24270 io0_a_src = a_src->data.ptr;
24271 io1_a_src = io0_a_src + a_src->meta.ri;
24272 iop_a_src = io1_a_src;
24273 io2_a_src = io0_a_src + a_src->meta.wi;
24274 }
24275
24276 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
24277 if (coro_susp_point) {
24278 v_dst_bytes_per_pixel = self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel;
24279 v_dst_x = self->private_data.s_decode_frame[0].v_dst_x;
24280 v_dst_y = self->private_data.s_decode_frame[0].v_dst_y;
24281 memcpy(v_src, self->private_data.s_decode_frame[0].v_src, sizeof(v_src));
24282 v_c = self->private_data.s_decode_frame[0].v_c;
24283 }
24284 switch (coro_susp_point) {
24285 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24286
24287 if (self->private_impl.f_call_sequence < 2) {
24288 if (a_src) {
24289 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24290 }
24291 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
24292 status = wuffs_wbmp__decoder__decode_frame_config(self, NULL, a_src);
24293 if (a_src) {
24294 iop_a_src = a_src->data.ptr + a_src->meta.ri;
24295 }
24296 if (status.repr) {
24297 goto suspend;
24298 }
24299 } else if (self->private_impl.f_call_sequence == 2) {
24300 } else {
24301 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
24302 goto ok;
24303 }
24304 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
24305 wuffs_base__pixel_buffer__pixel_format(a_dst),
24306 wuffs_base__pixel_buffer__palette(a_dst),
24307 wuffs_base__utility__make_pixel_format(536870920),
24308 wuffs_base__utility__empty_slice_u8(),
24309 a_blend);
24310 if ( ! wuffs_base__status__is_ok(&v_status)) {
24311 status = v_status;
24312 if (wuffs_base__status__is_error(&status)) {
24313 goto exit;
24314 } else if (wuffs_base__status__is_suspension(&status)) {
24315 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
24316 goto exit;
24317 }
24318 goto ok;
24319 }
24320 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
24321 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
24322 if ((v_dst_bits_per_pixel & 7) != 0) {
24323 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
24324 goto exit;
24325 }
24326 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
24327 if (self->private_impl.f_width > 0) {
24328 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
24329 while (v_dst_y < self->private_impl.f_height) {
24330 v_dst = wuffs_base__table_u8__row(v_tab, v_dst_y);
24331 v_dst_x = 0;
24332 while (v_dst_x < self->private_impl.f_width) {
24333 if ((v_dst_x & 7) == 0) {
24334 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
24335 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24336 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
24337 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
24338 v_dst = wuffs_base__table_u8__row(v_tab, v_dst_y);
24339 v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
24340 if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) {
24341 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes);
24342 }
24343 }
24344 v_c = wuffs_base__load_u8be__no_bounds_check(iop_a_src);
24345 (iop_a_src += 1, wuffs_base__make_empty_struct());
24346 }
24347 if ((v_c & 128) == 0) {
24348 v_src[0] = 0;
24349 } else {
24350 v_src[0] = 255;
24351 }
24352 v_c = ((uint8_t)(((((uint32_t)(v_c)) << 1) & 255)));
24353 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__utility__empty_slice_u8(), wuffs_base__make_slice_u8(v_src, 1));
24354 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
24355 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
24356 }
24357 v_dst_x += 1;
24358 }
24359 v_dst_y += 1;
24360 }
24361 }
24362 self->private_impl.f_call_sequence = 3;
24363
24364 goto ok;
24365 ok:
24366 self->private_impl.p_decode_frame[0] = 0;
24367 goto exit;
24368 }
24369
24370 goto suspend;
24371 suspend:
24372 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
24373 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
24374 self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
24375 self->private_data.s_decode_frame[0].v_dst_x = v_dst_x;
24376 self->private_data.s_decode_frame[0].v_dst_y = v_dst_y;
24377 memcpy(self->private_data.s_decode_frame[0].v_src, v_src, sizeof(v_src));
24378 self->private_data.s_decode_frame[0].v_c = v_c;
24379
24380 goto exit;
24381 exit:
24382 if (a_src) {
24383 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24384 }
24385
24386 if (wuffs_base__status__is_error(&status)) {
24387 self->private_impl.magic = WUFFS_BASE__DISABLED;
24388 }
24389 return status;
24390}
24391
24392// -------- func wbmp.decoder.skip_frame
24393
24394static wuffs_base__status
24395wuffs_wbmp__decoder__skip_frame(
24396 wuffs_wbmp__decoder* self,
24397 wuffs_base__io_buffer* a_src) {
24398 wuffs_base__status status = wuffs_base__make_status(NULL);
24399
24400 uint64_t v_bytes_per_row = 0;
24401 uint64_t v_total_bytes = 0;
24402
24403 const uint8_t* iop_a_src = NULL;
24404 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24405 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24406 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24407 if (a_src) {
24408 io0_a_src = a_src->data.ptr;
24409 io1_a_src = io0_a_src + a_src->meta.ri;
24410 iop_a_src = io1_a_src;
24411 io2_a_src = io0_a_src + a_src->meta.wi;
24412 }
24413
24414 uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
24415 switch (coro_susp_point) {
24416 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24417
24418 v_bytes_per_row = ((((uint64_t)(self->private_impl.f_width)) + 7) / 8);
24419 v_total_bytes = (v_bytes_per_row * ((uint64_t)(self->private_impl.f_height)));
24420 self->private_data.s_skip_frame[0].scratch = v_total_bytes;
24421 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
24422 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
24423 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
24424 iop_a_src = io2_a_src;
24425 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24426 goto suspend;
24427 }
24428 iop_a_src += self->private_data.s_skip_frame[0].scratch;
24429 self->private_impl.f_call_sequence = 3;
24430
24431 goto ok;
24432 ok:
24433 self->private_impl.p_skip_frame[0] = 0;
24434 goto exit;
24435 }
24436
24437 goto suspend;
24438 suspend:
24439 self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
24440
24441 goto exit;
24442 exit:
24443 if (a_src) {
24444 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24445 }
24446
24447 return status;
24448}
24449
24450// -------- func wbmp.decoder.frame_dirty_rect
24451
24452WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
24453wuffs_wbmp__decoder__frame_dirty_rect(
24454 const wuffs_wbmp__decoder* self) {
24455 if (!self) {
24456 return wuffs_base__utility__empty_rect_ie_u32();
24457 }
24458 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24459 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24460 return wuffs_base__utility__empty_rect_ie_u32();
24461 }
24462
24463 return wuffs_base__utility__make_rect_ie_u32(
24464 0,
24465 0,
24466 self->private_impl.f_width,
24467 self->private_impl.f_height);
24468}
24469
24470// -------- func wbmp.decoder.num_animation_loops
24471
24472WUFFS_BASE__MAYBE_STATIC uint32_t
24473wuffs_wbmp__decoder__num_animation_loops(
24474 const wuffs_wbmp__decoder* self) {
24475 if (!self) {
24476 return 0;
24477 }
24478 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24479 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24480 return 0;
24481 }
24482
24483 return 0;
24484}
24485
24486// -------- func wbmp.decoder.num_decoded_frame_configs
24487
24488WUFFS_BASE__MAYBE_STATIC uint64_t
24489wuffs_wbmp__decoder__num_decoded_frame_configs(
24490 const wuffs_wbmp__decoder* self) {
24491 if (!self) {
24492 return 0;
24493 }
24494 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24495 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24496 return 0;
24497 }
24498
24499 if (self->private_impl.f_call_sequence > 1) {
24500 return 1;
24501 }
24502 return 0;
24503}
24504
24505// -------- func wbmp.decoder.num_decoded_frames
24506
24507WUFFS_BASE__MAYBE_STATIC uint64_t
24508wuffs_wbmp__decoder__num_decoded_frames(
24509 const wuffs_wbmp__decoder* self) {
24510 if (!self) {
24511 return 0;
24512 }
24513 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24514 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24515 return 0;
24516 }
24517
24518 if (self->private_impl.f_call_sequence > 2) {
24519 return 1;
24520 }
24521 return 0;
24522}
24523
24524// -------- func wbmp.decoder.restart_frame
24525
24526WUFFS_BASE__MAYBE_STATIC wuffs_base__status
24527wuffs_wbmp__decoder__restart_frame(
24528 wuffs_wbmp__decoder* self,
24529 uint64_t a_index,
24530 uint64_t a_io_position) {
24531 if (!self) {
24532 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24533 }
24534 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24535 return wuffs_base__make_status(
24536 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24537 ? wuffs_base__error__disabled_by_previous_error
24538 : wuffs_base__error__initialize_not_called);
24539 }
24540
24541 if (self->private_impl.f_call_sequence == 0) {
24542 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
24543 }
24544 if (a_index != 0) {
24545 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24546 }
24547 self->private_impl.f_call_sequence = 1;
24548 self->private_impl.f_frame_config_io_position = a_io_position;
24549 return wuffs_base__make_status(NULL);
24550}
24551
24552// -------- func wbmp.decoder.set_report_metadata
24553
24554WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
24555wuffs_wbmp__decoder__set_report_metadata(
24556 wuffs_wbmp__decoder* self,
24557 uint32_t a_fourcc,
24558 bool a_report) {
24559 return wuffs_base__make_empty_struct();
24560}
24561
24562// -------- func wbmp.decoder.tell_me_more
24563
24564WUFFS_BASE__MAYBE_STATIC wuffs_base__status
24565wuffs_wbmp__decoder__tell_me_more(
24566 wuffs_wbmp__decoder* self,
24567 wuffs_base__io_buffer* a_dst,
24568 wuffs_base__more_information* a_minfo,
24569 wuffs_base__io_buffer* a_src) {
24570 if (!self) {
24571 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24572 }
24573 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24574 return wuffs_base__make_status(
24575 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24576 ? wuffs_base__error__disabled_by_previous_error
24577 : wuffs_base__error__initialize_not_called);
24578 }
24579 if (!a_dst || !a_src) {
24580 self->private_impl.magic = WUFFS_BASE__DISABLED;
24581 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24582 }
24583 if ((self->private_impl.active_coroutine != 0) &&
24584 (self->private_impl.active_coroutine != 4)) {
24585 self->private_impl.magic = WUFFS_BASE__DISABLED;
24586 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24587 }
24588 self->private_impl.active_coroutine = 0;
24589 wuffs_base__status status = wuffs_base__make_status(NULL);
24590
24591 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
24592 goto exit;
24593
24594 goto ok;
24595 ok:
24596 goto exit;
24597 exit:
24598 if (wuffs_base__status__is_error(&status)) {
24599 self->private_impl.magic = WUFFS_BASE__DISABLED;
24600 }
24601 return status;
24602}
24603
24604// -------- func wbmp.decoder.workbuf_len
24605
24606WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
24607wuffs_wbmp__decoder__workbuf_len(
24608 const wuffs_wbmp__decoder* self) {
24609 if (!self) {
24610 return wuffs_base__utility__empty_range_ii_u64();
24611 }
24612 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24613 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24614 return wuffs_base__utility__empty_range_ii_u64();
24615 }
24616
24617 return wuffs_base__utility__make_range_ii_u64(0, 0);
24618}
24619
24620#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
24621
24622#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
24623
24624// ---------------- Status Codes Implementations
24625
24626const char* wuffs_zlib__note__dictionary_required = "@zlib: dictionary required";
24627const char* wuffs_zlib__error__bad_checksum = "#zlib: bad checksum";
24628const char* wuffs_zlib__error__bad_compression_method = "#zlib: bad compression method";
24629const char* wuffs_zlib__error__bad_compression_window_size = "#zlib: bad compression window size";
24630const char* wuffs_zlib__error__bad_parity_check = "#zlib: bad parity check";
24631const char* wuffs_zlib__error__incorrect_dictionary = "#zlib: incorrect dictionary";
24632
24633// ---------------- Private Consts
24634
24635// ---------------- Private Initializer Prototypes
24636
24637// ---------------- Private Function Prototypes
24638
24639// ---------------- VTables
24640
24641const wuffs_base__io_transformer__func_ptrs
24642wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = {
24643 (wuffs_base__empty_struct(*)(void*,
24644 uint32_t,
24645 bool))(&wuffs_zlib__decoder__set_quirk_enabled),
24646 (wuffs_base__status(*)(void*,
24647 wuffs_base__io_buffer*,
24648 wuffs_base__io_buffer*,
24649 wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io),
24650 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len),
24651};
24652
24653// ---------------- Initializer Implementations
24654
24655wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
24656wuffs_zlib__decoder__initialize(
24657 wuffs_zlib__decoder* self,
24658 size_t sizeof_star_self,
24659 uint64_t wuffs_version,
24660 uint32_t initialize_flags){
24661 if (!self) {
24662 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24663 }
24664 if (sizeof(*self) != sizeof_star_self) {
24665 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
24666 }
24667 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
24668 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
24669 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
24670 }
24671
24672 if ((initialize_flags & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
24673 // The whole point of this if-check is to detect an uninitialized *self.
24674 // We disable the warning on GCC. Clang-5.0 does not have this warning.
24675#if !defined(__clang__) && defined(__GNUC__)
24676#pragma GCC diagnostic push
24677#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
24678#endif
24679 if (self->private_impl.magic != 0) {
24680 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
24681 }
24682#if !defined(__clang__) && defined(__GNUC__)
24683#pragma GCC diagnostic pop
24684#endif
24685 } else {
24686 if ((initialize_flags & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
24687 memset(self, 0, sizeof(*self));
24688 initialize_flags |= WUFFS_INITIALIZE__ALREADY_ZEROED;
24689 } else {
24690 memset(&(self->private_impl), 0, sizeof(self->private_impl));
24691 }
24692 }
24693
24694 {
24695 wuffs_base__status z = wuffs_adler32__hasher__initialize(
24696 &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, initialize_flags);
24697 if (z.repr) {
24698 return z;
24699 }
24700 }
24701 {
24702 wuffs_base__status z = wuffs_adler32__hasher__initialize(
24703 &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, initialize_flags);
24704 if (z.repr) {
24705 return z;
24706 }
24707 }
24708 {
24709 wuffs_base__status z = wuffs_deflate__decoder__initialize(
24710 &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, initialize_flags);
24711 if (z.repr) {
24712 return z;
24713 }
24714 }
24715 self->private_impl.magic = WUFFS_BASE__MAGIC;
24716 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
24717 wuffs_base__io_transformer__vtable_name;
24718 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
24719 (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer);
24720 return wuffs_base__make_status(NULL);
24721}
24722
24723wuffs_zlib__decoder*
24724wuffs_zlib__decoder__alloc() {
24725 wuffs_zlib__decoder* x =
24726 (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
24727 if (!x) {
24728 return NULL;
24729 }
24730 if (wuffs_zlib__decoder__initialize(
24731 x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
24732 free(x);
24733 return NULL;
24734 }
24735 return x;
24736}
24737
24738size_t
24739sizeof__wuffs_zlib__decoder() {
24740 return sizeof(wuffs_zlib__decoder);
24741}
24742
24743// ---------------- Function Implementations
24744
24745// -------- func zlib.decoder.dictionary_id
24746
24747WUFFS_BASE__MAYBE_STATIC uint32_t
24748wuffs_zlib__decoder__dictionary_id(
24749 const wuffs_zlib__decoder* self) {
24750 if (!self) {
24751 return 0;
24752 }
24753 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24754 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24755 return 0;
24756 }
24757
24758 return self->private_impl.f_dict_id_want;
24759}
24760
24761// -------- func zlib.decoder.add_dictionary
24762
24763WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
24764wuffs_zlib__decoder__add_dictionary(
24765 wuffs_zlib__decoder* self,
24766 wuffs_base__slice_u8 a_dict) {
24767 if (!self) {
24768 return wuffs_base__make_empty_struct();
24769 }
24770 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24771 return wuffs_base__make_empty_struct();
24772 }
24773
24774 if (self->private_impl.f_header_complete) {
24775 self->private_impl.f_bad_call_sequence = true;
24776 } else {
24777 self->private_impl.f_dict_id_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict);
24778 wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict);
24779 }
24780 self->private_impl.f_got_dictionary = true;
24781 return wuffs_base__make_empty_struct();
24782}
24783
24784// -------- func zlib.decoder.set_ignore_checksum
24785
24786WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
24787wuffs_zlib__decoder__set_ignore_checksum(
24788 wuffs_zlib__decoder* self,
24789 bool a_ic) {
24790 if (!self) {
24791 return wuffs_base__make_empty_struct();
24792 }
24793 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24794 return wuffs_base__make_empty_struct();
24795 }
24796
24797 self->private_impl.f_ignore_checksum = a_ic;
24798 return wuffs_base__make_empty_struct();
24799}
24800
24801// -------- func zlib.decoder.set_quirk_enabled
24802
24803WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
24804wuffs_zlib__decoder__set_quirk_enabled(
24805 wuffs_zlib__decoder* self,
24806 uint32_t a_quirk,
24807 bool a_enabled) {
24808 return wuffs_base__make_empty_struct();
24809}
24810
24811// -------- func zlib.decoder.workbuf_len
24812
24813WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
24814wuffs_zlib__decoder__workbuf_len(
24815 const wuffs_zlib__decoder* self) {
24816 if (!self) {
24817 return wuffs_base__utility__empty_range_ii_u64();
24818 }
24819 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24820 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24821 return wuffs_base__utility__empty_range_ii_u64();
24822 }
24823
24824 return wuffs_base__utility__make_range_ii_u64(1, 1);
24825}
24826
24827// -------- func zlib.decoder.transform_io
24828
24829WUFFS_BASE__MAYBE_STATIC wuffs_base__status
24830wuffs_zlib__decoder__transform_io(
24831 wuffs_zlib__decoder* self,
24832 wuffs_base__io_buffer* a_dst,
24833 wuffs_base__io_buffer* a_src,
24834 wuffs_base__slice_u8 a_workbuf) {
24835 if (!self) {
24836 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24837 }
24838 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24839 return wuffs_base__make_status(
24840 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24841 ? wuffs_base__error__disabled_by_previous_error
24842 : wuffs_base__error__initialize_not_called);
24843 }
24844 if (!a_dst || !a_src) {
24845 self->private_impl.magic = WUFFS_BASE__DISABLED;
24846 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24847 }
24848 if ((self->private_impl.active_coroutine != 0) &&
24849 (self->private_impl.active_coroutine != 1)) {
24850 self->private_impl.magic = WUFFS_BASE__DISABLED;
24851 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24852 }
24853 self->private_impl.active_coroutine = 0;
24854 wuffs_base__status status = wuffs_base__make_status(NULL);
24855
24856 uint16_t v_x = 0;
24857 uint32_t v_checksum_got = 0;
24858 wuffs_base__status v_status = wuffs_base__make_status(NULL);
24859 uint32_t v_checksum_want = 0;
24860 uint64_t v_mark = 0;
24861
24862 uint8_t* iop_a_dst = NULL;
24863 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24864 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24865 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24866 if (a_dst) {
24867 io0_a_dst = a_dst->data.ptr;
24868 io1_a_dst = io0_a_dst + a_dst->meta.wi;
24869 iop_a_dst = io1_a_dst;
24870 io2_a_dst = io0_a_dst + a_dst->data.len;
24871 if (a_dst->meta.closed) {
24872 io2_a_dst = iop_a_dst;
24873 }
24874 }
24875 const uint8_t* iop_a_src = NULL;
24876 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24877 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24878 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24879 if (a_src) {
24880 io0_a_src = a_src->data.ptr;
24881 io1_a_src = io0_a_src + a_src->meta.ri;
24882 iop_a_src = io1_a_src;
24883 io2_a_src = io0_a_src + a_src->meta.wi;
24884 }
24885
24886 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
24887 if (coro_susp_point) {
24888 v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
24889 }
24890 switch (coro_susp_point) {
24891 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24892
24893 if (self->private_impl.f_bad_call_sequence) {
24894 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
24895 goto exit;
24896 } else if ( ! self->private_impl.f_want_dictionary) {
24897 {
24898 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
24899 uint16_t t_0;
24900 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
24901 t_0 = wuffs_base__load_u16be__no_bounds_check(iop_a_src);
24902 iop_a_src += 2;
24903 } else {
24904 self->private_data.s_transform_io[0].scratch = 0;
24905 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
24906 while (true) {
24907 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24908 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24909 goto suspend;
24910 }
24911 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
24912 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
24913 *scratch >>= 8;
24914 *scratch <<= 8;
24915 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
24916 if (num_bits_0 == 8) {
24917 t_0 = ((uint16_t)(*scratch >> 48));
24918 break;
24919 }
24920 num_bits_0 += 8;
24921 *scratch |= ((uint64_t)(num_bits_0));
24922 }
24923 }
24924 v_x = t_0;
24925 }
24926 if (((v_x >> 8) & 15) != 8) {
24927 status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method);
24928 goto exit;
24929 }
24930 if ((v_x >> 12) > 7) {
24931 status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size);
24932 goto exit;
24933 }
24934 if ((v_x % 31) != 0) {
24935 status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check);
24936 goto exit;
24937 }
24938 self->private_impl.f_want_dictionary = ((v_x & 32) != 0);
24939 if (self->private_impl.f_want_dictionary) {
24940 self->private_impl.f_dict_id_got = 1;
24941 {
24942 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
24943 uint32_t t_1;
24944 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
24945 t_1 = wuffs_base__load_u32be__no_bounds_check(iop_a_src);
24946 iop_a_src += 4;
24947 } else {
24948 self->private_data.s_transform_io[0].scratch = 0;
24949 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
24950 while (true) {
24951 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24952 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24953 goto suspend;
24954 }
24955 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
24956 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
24957 *scratch >>= 8;
24958 *scratch <<= 8;
24959 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
24960 if (num_bits_1 == 24) {
24961 t_1 = ((uint32_t)(*scratch >> 32));
24962 break;
24963 }
24964 num_bits_1 += 8;
24965 *scratch |= ((uint64_t)(num_bits_1));
24966 }
24967 }
24968 self->private_impl.f_dict_id_want = t_1;
24969 }
24970 status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
24971 goto ok;
24972 } else if (self->private_impl.f_got_dictionary) {
24973 status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
24974 goto exit;
24975 }
24976 } else if (self->private_impl.f_dict_id_got != self->private_impl.f_dict_id_want) {
24977 if (self->private_impl.f_got_dictionary) {
24978 status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
24979 goto exit;
24980 }
24981 status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
24982 goto ok;
24983 }
24984 self->private_impl.f_header_complete = true;
24985 while (true) {
24986 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
24987 {
24988 if (a_dst) {
24989 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
24990 }
24991 if (a_src) {
24992 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24993 }
24994 wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
24995 if (a_dst) {
24996 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
24997 }
24998 if (a_src) {
24999 iop_a_src = a_src->data.ptr + a_src->meta.ri;
25000 }
25001 v_status = t_2;
25002 }
25003 if ( ! self->private_impl.f_ignore_checksum) {
25004 v_checksum_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
25005 }
25006 if (wuffs_base__status__is_ok(&v_status)) {
25007 goto label__0__break;
25008 }
25009 status = v_status;
25010 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
25011 }
25012 label__0__break:;
25013 {
25014 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
25015 uint32_t t_3;
25016 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
25017 t_3 = wuffs_base__load_u32be__no_bounds_check(iop_a_src);
25018 iop_a_src += 4;
25019 } else {
25020 self->private_data.s_transform_io[0].scratch = 0;
25021 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
25022 while (true) {
25023 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
25024 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
25025 goto suspend;
25026 }
25027 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
25028 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
25029 *scratch >>= 8;
25030 *scratch <<= 8;
25031 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
25032 if (num_bits_3 == 24) {
25033 t_3 = ((uint32_t)(*scratch >> 32));
25034 break;
25035 }
25036 num_bits_3 += 8;
25037 *scratch |= ((uint64_t)(num_bits_3));
25038 }
25039 }
25040 v_checksum_want = t_3;
25041 }
25042 if ( ! self->private_impl.f_ignore_checksum && (v_checksum_got != v_checksum_want)) {
25043 status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum);
25044 goto exit;
25045 }
25046
25047 goto ok;
25048 ok:
25049 self->private_impl.p_transform_io[0] = 0;
25050 goto exit;
25051 }
25052
25053 goto suspend;
25054 suspend:
25055 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
25056 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
25057 self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
25058
25059 goto exit;
25060 exit:
25061 if (a_dst) {
25062 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
25063 }
25064 if (a_src) {
25065 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
25066 }
25067
25068 if (wuffs_base__status__is_error(&status)) {
25069 self->private_impl.magic = WUFFS_BASE__DISABLED;
25070 }
25071 return status;
25072}
25073
25074#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
25075
25076#endif // WUFFS_IMPLEMENTATION
25077
25078#ifdef __clang__
25079#pragma clang diagnostic pop
25080#endif
25081
25082#endif // WUFFS_INCLUDE_GUARD
25083