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