1 #ifndef WUFFS_INCLUDE_GUARD
2 #define WUFFS_INCLUDE_GUARD
3
4 // Wuffs ships as a "single file C library" or "header file library" as per
5 // https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
6 //
7 // To use that single file as a "foo.c"-like implementation, instead of a
8 // "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
9 // compiling it.
10
11 // Wuffs' C code is generated automatically, not hand-written. These warnings'
12 // costs outweigh the benefits.
13 //
14 // The "elif defined(__clang__)" isn't redundant. While vanilla clang defines
15 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
16 #if defined(__GNUC__)
17 #pragma GCC diagnostic push
18 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
19 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
20 #pragma GCC diagnostic ignored "-Wunreachable-code"
21 #pragma GCC diagnostic ignored "-Wunused-function"
22 #pragma GCC diagnostic ignored "-Wunused-parameter"
23 #if defined(__cplusplus)
24 #pragma GCC diagnostic ignored "-Wold-style-cast"
25 #endif
26 #elif defined(__clang__)
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
29 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
30 #pragma clang diagnostic ignored "-Wunreachable-code"
31 #pragma clang diagnostic ignored "-Wunused-function"
32 #pragma clang diagnostic ignored "-Wunused-parameter"
33 #if defined(__cplusplus)
34 #pragma clang diagnostic ignored "-Wold-style-cast"
35 #endif
36 #endif
37
38 // Copyright 2017 The Wuffs Authors.
39 //
40 // Licensed under the Apache License, Version 2.0 (the "License");
41 // you may not use this file except in compliance with the License.
42 // You may obtain a copy of the License at
43 //
44 // https://www.apache.org/licenses/LICENSE-2.0
45 //
46 // Unless required by applicable law or agreed to in writing, software
47 // distributed under the License is distributed on an "AS IS" BASIS,
48 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49 // See the License for the specific language governing permissions and
50 // limitations under the License.
51
52 #include <stdbool.h>
53 #include <stdint.h>
54 #include <stdlib.h>
55 #include <string.h>
56
57 #ifdef __cplusplus
58 #if (__cplusplus >= 201103L) || defined(_MSC_VER)
59 #include <memory>
60 #define WUFFS_BASE__HAVE_EQ_DELETE
61 #define WUFFS_BASE__HAVE_UNIQUE_PTR
62 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
63 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
64 #elif defined(__GNUC__) || defined(__clang__)
65 #warning "Wuffs' C++ code expects -std=c++11 or later"
66 #endif
67
68 extern "C" {
69 #endif
70
71 // ---------------- Version
72
73 // WUFFS_VERSION is the major.minor.patch version, as per https://semver.org/,
74 // as a uint64_t. The major number is the high 32 bits. The minor number is the
75 // middle 16 bits. The patch number is the low 16 bits. The pre-release label
76 // and build metadata are part of the string representation (such as
77 // "1.2.3-beta+456.20181231") but not the uint64_t representation.
78 //
79 // WUFFS_VERSION_PRE_RELEASE_LABEL (such as "", "beta" or "rc.1") being
80 // non-empty denotes a developer preview, not a release version, and has no
81 // backwards or forwards compatibility guarantees.
82 //
83 // WUFFS_VERSION_BUILD_METADATA_XXX, if non-zero, are the number of commits and
84 // the last commit date in the repository used to build this library. Within
85 // each major.minor branch, the commit count should increase monotonically.
86 //
87 // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision
88 // adfd2965cc104f3de6cccaed5095721d042c1251 committed on 2022-01-18.
89 #define WUFFS_VERSION 0x000030000
90 #define WUFFS_VERSION_MAJOR 0
91 #define WUFFS_VERSION_MINOR 3
92 #define WUFFS_VERSION_PATCH 0
93 #define WUFFS_VERSION_PRE_RELEASE_LABEL "beta.14"
94 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3273
95 #define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20220118
96 #define WUFFS_VERSION_STRING "0.3.0-beta.14+3273.20220118"
97
98 // ---------------- Configuration
99
100 // Define WUFFS_CONFIG__AVOID_CPU_ARCH to avoid any code tied to a specific CPU
101 // architecture, such as SSE SIMD for the x86 CPU family.
102 #if defined(WUFFS_CONFIG__AVOID_CPU_ARCH) // (#if-chain ref AVOID_CPU_ARCH_0)
103 // No-op.
104 #else // (#if-chain ref AVOID_CPU_ARCH_0)
105
106 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
107 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
108 #if defined(__GNUC__) || defined(__clang__)
109 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg) __attribute__((target(arg)))
110 #else
111 #define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg)
112 #endif // defined(__GNUC__) || defined(__clang__)
113
114 #if defined(__GNUC__) // (#if-chain ref AVOID_CPU_ARCH_1)
115
116 // To simplify Wuffs code, "cpu_arch >= arm_xxx" requires xxx but also
117 // unaligned little-endian load/stores.
118 #if defined(__ARM_FEATURE_UNALIGNED) && !defined(__native_client__) && \
119 defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
120 // Not all gcc versions define __ARM_ACLE, even if they support crc32
121 // intrinsics. Look for __ARM_FEATURE_CRC32 instead.
122 #if defined(__ARM_FEATURE_CRC32)
123 #include <arm_acle.h>
124 #define WUFFS_BASE__CPU_ARCH__ARM_CRC32
125 #endif // defined(__ARM_FEATURE_CRC32)
126 #if defined(__ARM_NEON)
127 #include <arm_neon.h>
128 #define WUFFS_BASE__CPU_ARCH__ARM_NEON
129 #endif // defined(__ARM_NEON)
130 #endif // defined(__ARM_FEATURE_UNALIGNED) etc
131
132 // Similarly, "cpu_arch >= x86_sse42" requires SSE4.2 but also PCLMUL and
133 // POPCNT. This is checked at runtime via cpuid, not at compile time.
134 //
135 // Likewise, "cpu_arch >= x86_avx2" also requires PCLMUL, POPCNT and SSE4.2.
136 #if defined(__i386__) || defined(__x86_64__)
137 #if !defined(__native_client__)
138 #include <cpuid.h>
139 #include <x86intrin.h>
140 // X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
141 #define WUFFS_BASE__CPU_ARCH__X86_FAMILY
142 #endif // !defined(__native_client__)
143 #endif // defined(__i386__) || defined(__x86_64__)
144
145 #elif defined(_MSC_VER) // (#if-chain ref AVOID_CPU_ARCH_1)
146
147 #if defined(_M_IX86) || defined(_M_X64)
148 #if defined(__AVX__) || defined(__clang__)
149
150 // We need <intrin.h> for the __cpuid function.
151 #include <intrin.h>
152 // That's not enough for X64 SIMD, with clang-cl, if we want to use
153 // "__attribute__((target(arg)))" without e.g. "/arch:AVX".
154 //
155 // Some web pages suggest that <immintrin.h> is all you need, as it pulls in
156 // the earlier SIMD families like SSE4.2, but that doesn't seem to work in
157 // practice, possibly for the same reason that just <intrin.h> doesn't work.
158 #include <immintrin.h> // AVX, AVX2, FMA, POPCNT
159 #include <nmmintrin.h> // SSE4.2
160 #include <wmmintrin.h> // AES, PCLMUL
161 // X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
162 #define WUFFS_BASE__CPU_ARCH__X86_FAMILY
163
164 #else // defined(__AVX__) || defined(__clang__)
165
166 // clang-cl (which defines both __clang__ and _MSC_VER) supports
167 // "__attribute__((target(arg)))".
168 //
169 // For MSVC's cl.exe (unlike clang or gcc), SIMD capability is a compile-time
170 // property of the source file (e.g. a /arch:AVX or -mavx compiler flag), not
171 // of individual functions (that can be conditionally selected at runtime).
172 #pragma message("Wuffs with MSVC+IX86/X64 needs /arch:AVX for best performance")
173
174 #endif // defined(__AVX__) || defined(__clang__)
175 #endif // defined(_M_IX86) || defined(_M_X64)
176
177 #endif // (#if-chain ref AVOID_CPU_ARCH_1)
178 #endif // (#if-chain ref AVOID_CPU_ARCH_0)
179
180 // --------
181
182 // Define WUFFS_CONFIG__STATIC_FUNCTIONS (combined with WUFFS_IMPLEMENTATION)
183 // to make all of Wuffs' functions have static storage.
184 //
185 // This can help the compiler ignore or discard unused code, which can produce
186 // faster compiles and smaller binaries. Other motivations are discussed in the
187 // "ALLOW STATIC IMPLEMENTATION" section of
188 // https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
189 #if defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
190 #define WUFFS_BASE__MAYBE_STATIC static
191 #else
192 #define WUFFS_BASE__MAYBE_STATIC
193 #endif // defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
194
195 // ---------------- CPU Architecture
196
197 static inline bool //
wuffs_base__cpu_arch__have_arm_crc32()198 wuffs_base__cpu_arch__have_arm_crc32() {
199 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
200 return true;
201 #else
202 return false;
203 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
204 }
205
206 static inline bool //
wuffs_base__cpu_arch__have_arm_neon()207 wuffs_base__cpu_arch__have_arm_neon() {
208 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
209 return true;
210 #else
211 return false;
212 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
213 }
214
215 static inline bool //
wuffs_base__cpu_arch__have_x86_avx2()216 wuffs_base__cpu_arch__have_x86_avx2() {
217 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
218 // GCC defines these macros but MSVC does not.
219 // - bit_AVX2 = (1 << 5)
220 const unsigned int avx2_ebx7 = 0x00000020;
221 // GCC defines these macros but MSVC does not.
222 // - bit_PCLMUL = (1 << 1)
223 // - bit_POPCNT = (1 << 23)
224 // - bit_SSE4_2 = (1 << 20)
225 const unsigned int avx2_ecx1 = 0x00900002;
226
227 // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
228 #if defined(__GNUC__)
229 unsigned int eax7 = 0;
230 unsigned int ebx7 = 0;
231 unsigned int ecx7 = 0;
232 unsigned int edx7 = 0;
233 if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
234 ((ebx7 & avx2_ebx7) == avx2_ebx7)) {
235 unsigned int eax1 = 0;
236 unsigned int ebx1 = 0;
237 unsigned int ecx1 = 0;
238 unsigned int edx1 = 0;
239 if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
240 ((ecx1 & avx2_ecx1) == avx2_ecx1)) {
241 return true;
242 }
243 }
244 #elif defined(_MSC_VER) // defined(__GNUC__)
245 int x7[4];
246 __cpuidex(x7, 7, 0);
247 if ((((unsigned int)(x7[1])) & avx2_ebx7) == avx2_ebx7) {
248 int x1[4];
249 __cpuid(x1, 1);
250 if ((((unsigned int)(x1[2])) & avx2_ecx1) == avx2_ecx1) {
251 return true;
252 }
253 }
254 #else
255 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
256 #endif // defined(__GNUC__); defined(_MSC_VER)
257 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
258 return false;
259 }
260
261 static inline bool //
wuffs_base__cpu_arch__have_x86_bmi2()262 wuffs_base__cpu_arch__have_x86_bmi2() {
263 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
264 // GCC defines these macros but MSVC does not.
265 // - bit_BMI2 = (1 << 8)
266 const unsigned int bmi2_ebx7 = 0x00000100;
267
268 // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
269 #if defined(__GNUC__)
270 unsigned int eax7 = 0;
271 unsigned int ebx7 = 0;
272 unsigned int ecx7 = 0;
273 unsigned int edx7 = 0;
274 if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
275 ((ebx7 & bmi2_ebx7) == bmi2_ebx7)) {
276 return true;
277 }
278 #elif defined(_MSC_VER) // defined(__GNUC__)
279 int x7[4];
280 __cpuidex(x7, 7, 0);
281 if ((((unsigned int)(x7[1])) & bmi2_ebx7) == bmi2_ebx7) {
282 return true;
283 }
284 #else
285 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
286 #endif // defined(__GNUC__); defined(_MSC_VER)
287 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
288 return false;
289 }
290
291 static inline bool //
wuffs_base__cpu_arch__have_x86_sse42()292 wuffs_base__cpu_arch__have_x86_sse42() {
293 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
294 // GCC defines these macros but MSVC does not.
295 // - bit_PCLMUL = (1 << 1)
296 // - bit_POPCNT = (1 << 23)
297 // - bit_SSE4_2 = (1 << 20)
298 const unsigned int sse42_ecx1 = 0x00900002;
299
300 // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
301 #if defined(__GNUC__)
302 unsigned int eax1 = 0;
303 unsigned int ebx1 = 0;
304 unsigned int ecx1 = 0;
305 unsigned int edx1 = 0;
306 if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
307 ((ecx1 & sse42_ecx1) == sse42_ecx1)) {
308 return true;
309 }
310 #elif defined(_MSC_VER) // defined(__GNUC__)
311 int x1[4];
312 __cpuid(x1, 1);
313 if ((((unsigned int)(x1[2])) & sse42_ecx1) == sse42_ecx1) {
314 return true;
315 }
316 #else
317 #error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
318 #endif // defined(__GNUC__); defined(_MSC_VER)
319 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
320 return false;
321 }
322
323 // ---------------- Fundamentals
324
325 // Wuffs assumes that:
326 // - converting a uint32_t to a size_t will never overflow.
327 // - converting a size_t to a uint64_t will never overflow.
328 #if defined(__WORDSIZE)
329 #if (__WORDSIZE != 32) && (__WORDSIZE != 64)
330 #error "Wuffs requires a word size of either 32 or 64 bits"
331 #endif
332 #endif
333
334 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
335 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
336 #if defined(__GNUC__) || defined(__clang__)
337 #define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused))
338 #define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result))
339 #else
340 #define WUFFS_BASE__POTENTIALLY_UNUSED
341 #define WUFFS_BASE__WARN_UNUSED_RESULT
342 #endif
343
344 // --------
345
346 // Options (bitwise or'ed together) for wuffs_foo__bar__initialize functions.
347
348 #define WUFFS_INITIALIZE__DEFAULT_OPTIONS ((uint32_t)0x00000000)
349
350 // WUFFS_INITIALIZE__ALREADY_ZEROED means that the "self" receiver struct value
351 // has already been set to all zeroes.
352 #define WUFFS_INITIALIZE__ALREADY_ZEROED ((uint32_t)0x00000001)
353
354 // WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED means that, absent
355 // WUFFS_INITIALIZE__ALREADY_ZEROED, only some of the "self" receiver struct
356 // value will be set to all zeroes. Internal buffers, which tend to be a large
357 // proportion of the struct's size, will be left uninitialized. Internal means
358 // that the buffer is contained by the receiver struct, as opposed to being
359 // passed as a separately allocated "work buffer".
360 //
361 // For more detail, see:
362 // https://github.com/google/wuffs/blob/main/doc/note/initialization.md
363 #define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \
364 ((uint32_t)0x00000002)
365
366 // --------
367
368 // wuffs_base__empty_struct is used when a Wuffs function returns an empty
369 // struct. In C, if a function f returns void, you can't say "x = f()", but in
370 // Wuffs, if a function g returns empty, you can say "y = g()".
371 typedef struct wuffs_base__empty_struct__struct {
372 // private_impl is a placeholder field. It isn't explicitly used, except that
373 // without it, the sizeof a struct with no fields can differ across C/C++
374 // compilers, and it is undefined behavior in C99. For example, gcc says that
375 // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
376 // ABI incompatibility if a Wuffs .c file is processed by one compiler and
377 // its .h file with another compiler.
378 //
379 // Instead, we explicitly insert an otherwise unused field, so that the
380 // sizeof this struct is always 1.
381 uint8_t private_impl;
382 } wuffs_base__empty_struct;
383
384 static inline wuffs_base__empty_struct //
wuffs_base__make_empty_struct()385 wuffs_base__make_empty_struct() {
386 wuffs_base__empty_struct ret;
387 ret.private_impl = 0;
388 return ret;
389 }
390
391 // wuffs_base__utility is a placeholder receiver type. It enables what Java
392 // calls static methods, as opposed to regular methods.
393 typedef struct wuffs_base__utility__struct {
394 // private_impl is a placeholder field. It isn't explicitly used, except that
395 // without it, the sizeof a struct with no fields can differ across C/C++
396 // compilers, and it is undefined behavior in C99. For example, gcc says that
397 // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to
398 // ABI incompatibility if a Wuffs .c file is processed by one compiler and
399 // its .h file with another compiler.
400 //
401 // Instead, we explicitly insert an otherwise unused field, so that the
402 // sizeof this struct is always 1.
403 uint8_t private_impl;
404 } wuffs_base__utility;
405
406 typedef struct wuffs_base__vtable__struct {
407 const char* vtable_name;
408 const void* function_pointers;
409 } wuffs_base__vtable;
410
411 // --------
412
413 // See https://github.com/google/wuffs/blob/main/doc/note/statuses.md
414 typedef struct wuffs_base__status__struct {
415 const char* repr;
416
417 #ifdef __cplusplus
418 inline bool is_complete() const;
419 inline bool is_error() const;
420 inline bool is_note() const;
421 inline bool is_ok() const;
422 inline bool is_suspension() const;
423 inline const char* message() const;
424 #endif // __cplusplus
425
426 } wuffs_base__status;
427
428 extern const char wuffs_base__note__i_o_redirect[];
429 extern const char wuffs_base__note__end_of_data[];
430 extern const char wuffs_base__note__metadata_reported[];
431 extern const char wuffs_base__suspension__even_more_information[];
432 extern const char wuffs_base__suspension__mispositioned_read[];
433 extern const char wuffs_base__suspension__mispositioned_write[];
434 extern const char wuffs_base__suspension__short_read[];
435 extern const char wuffs_base__suspension__short_write[];
436 extern const char wuffs_base__error__bad_i_o_position[];
437 extern const char wuffs_base__error__bad_argument_length_too_short[];
438 extern const char wuffs_base__error__bad_argument[];
439 extern const char wuffs_base__error__bad_call_sequence[];
440 extern const char wuffs_base__error__bad_data[];
441 extern const char wuffs_base__error__bad_receiver[];
442 extern const char wuffs_base__error__bad_restart[];
443 extern const char wuffs_base__error__bad_sizeof_receiver[];
444 extern const char wuffs_base__error__bad_vtable[];
445 extern const char wuffs_base__error__bad_workbuf_length[];
446 extern const char wuffs_base__error__bad_wuffs_version[];
447 extern const char wuffs_base__error__cannot_return_a_suspension[];
448 extern const char wuffs_base__error__disabled_by_previous_error[];
449 extern const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[];
450 extern const char wuffs_base__error__initialize_not_called[];
451 extern const char wuffs_base__error__interleaved_coroutine_calls[];
452 extern const char wuffs_base__error__no_more_information[];
453 extern const char wuffs_base__error__not_enough_data[];
454 extern const char wuffs_base__error__out_of_bounds[];
455 extern const char wuffs_base__error__unsupported_method[];
456 extern const char wuffs_base__error__unsupported_option[];
457 extern const char wuffs_base__error__unsupported_pixel_swizzler_option[];
458 extern const char wuffs_base__error__too_much_data[];
459
460 static inline wuffs_base__status //
wuffs_base__make_status(const char * repr)461 wuffs_base__make_status(const char* repr) {
462 wuffs_base__status z;
463 z.repr = repr;
464 return z;
465 }
466
467 static inline bool //
wuffs_base__status__is_complete(const wuffs_base__status * z)468 wuffs_base__status__is_complete(const wuffs_base__status* z) {
469 return (z->repr == NULL) || ((*z->repr != '$') && (*z->repr != '#'));
470 }
471
472 static inline bool //
wuffs_base__status__is_error(const wuffs_base__status * z)473 wuffs_base__status__is_error(const wuffs_base__status* z) {
474 return z->repr && (*z->repr == '#');
475 }
476
477 static inline bool //
wuffs_base__status__is_note(const wuffs_base__status * z)478 wuffs_base__status__is_note(const wuffs_base__status* z) {
479 return z->repr && (*z->repr != '$') && (*z->repr != '#');
480 }
481
482 static inline bool //
wuffs_base__status__is_ok(const wuffs_base__status * z)483 wuffs_base__status__is_ok(const wuffs_base__status* z) {
484 return z->repr == NULL;
485 }
486
487 static inline bool //
wuffs_base__status__is_suspension(const wuffs_base__status * z)488 wuffs_base__status__is_suspension(const wuffs_base__status* z) {
489 return z->repr && (*z->repr == '$');
490 }
491
492 // wuffs_base__status__message strips the leading '$', '#' or '@'.
493 static inline const char* //
wuffs_base__status__message(const wuffs_base__status * z)494 wuffs_base__status__message(const wuffs_base__status* z) {
495 if (z->repr) {
496 if ((*z->repr == '$') || (*z->repr == '#') || (*z->repr == '@')) {
497 return z->repr + 1;
498 }
499 }
500 return z->repr;
501 }
502
503 #ifdef __cplusplus
504
505 inline bool //
is_complete()506 wuffs_base__status::is_complete() const {
507 return wuffs_base__status__is_complete(this);
508 }
509
510 inline bool //
is_error()511 wuffs_base__status::is_error() const {
512 return wuffs_base__status__is_error(this);
513 }
514
515 inline bool //
is_note()516 wuffs_base__status::is_note() const {
517 return wuffs_base__status__is_note(this);
518 }
519
520 inline bool //
is_ok()521 wuffs_base__status::is_ok() const {
522 return wuffs_base__status__is_ok(this);
523 }
524
525 inline bool //
is_suspension()526 wuffs_base__status::is_suspension() const {
527 return wuffs_base__status__is_suspension(this);
528 }
529
530 inline const char* //
message()531 wuffs_base__status::message() const {
532 return wuffs_base__status__message(this);
533 }
534
535 #endif // __cplusplus
536
537 // --------
538
539 // WUFFS_BASE__RESULT is a result type: either a status (an error) or a value.
540 //
541 // A result with all fields NULL or zero is as valid as a zero-valued T.
542 #define WUFFS_BASE__RESULT(T) \
543 struct { \
544 wuffs_base__status status; \
545 T value; \
546 }
547
548 typedef WUFFS_BASE__RESULT(double) wuffs_base__result_f64;
549 typedef WUFFS_BASE__RESULT(int64_t) wuffs_base__result_i64;
550 typedef WUFFS_BASE__RESULT(uint64_t) wuffs_base__result_u64;
551
552 // --------
553
554 // wuffs_base__transform__output is the result of transforming from a src slice
555 // to a dst slice.
556 typedef struct wuffs_base__transform__output__struct {
557 wuffs_base__status status;
558 size_t num_dst;
559 size_t num_src;
560 } wuffs_base__transform__output;
561
562 // --------
563
564 // FourCC constants. Four Character Codes are literally four ASCII characters
565 // (sometimes padded with ' ' spaces) that pack neatly into a signed or
566 // unsigned 32-bit integer. ASCII letters are conventionally upper case.
567 //
568 // They are often used to identify video codecs (e.g. "H265") and pixel formats
569 // (e.g. "YV12"). Wuffs uses them for that but also generally for naming
570 // various things: compression formats (e.g. "BZ2 "), image metadata (e.g.
571 // "EXIF"), file formats (e.g. "HTML"), etc.
572 //
573 // Wuffs' u32 values are big-endian ("JPEG" is 0x4A504547 not 0x4745504A) to
574 // preserve ordering: "JPEG" < "MP3 " and 0x4A504547 < 0x4D503320.
575
576 // Background Color.
577 #define WUFFS_BASE__FOURCC__BGCL 0x4247434C
578
579 // Bitmap.
580 #define WUFFS_BASE__FOURCC__BMP 0x424D5020
581
582 // Brotli.
583 #define WUFFS_BASE__FOURCC__BRTL 0x4252544C
584
585 // Bzip2.
586 #define WUFFS_BASE__FOURCC__BZ2 0x425A3220
587
588 // Concise Binary Object Representation.
589 #define WUFFS_BASE__FOURCC__CBOR 0x43424F52
590
591 // Primary Chromaticities and White Point.
592 #define WUFFS_BASE__FOURCC__CHRM 0x4348524D
593
594 // Cascading Style Sheets.
595 #define WUFFS_BASE__FOURCC__CSS 0x43535320
596
597 // Encapsulated PostScript.
598 #define WUFFS_BASE__FOURCC__EPS 0x45505320
599
600 // Exchangeable Image File Format.
601 #define WUFFS_BASE__FOURCC__EXIF 0x45584946
602
603 // Free Lossless Audio Codec.
604 #define WUFFS_BASE__FOURCC__FLAC 0x464C4143
605
606 // Gamma Correction.
607 #define WUFFS_BASE__FOURCC__GAMA 0x47414D41
608
609 // Graphics Interchange Format.
610 #define WUFFS_BASE__FOURCC__GIF 0x47494620
611
612 // GNU Zip.
613 #define WUFFS_BASE__FOURCC__GZ 0x475A2020
614
615 // High Efficiency Image File.
616 #define WUFFS_BASE__FOURCC__HEIF 0x48454946
617
618 // Hypertext Markup Language.
619 #define WUFFS_BASE__FOURCC__HTML 0x48544D4C
620
621 // International Color Consortium Profile.
622 #define WUFFS_BASE__FOURCC__ICCP 0x49434350
623
624 // Icon.
625 #define WUFFS_BASE__FOURCC__ICO 0x49434F20
626
627 // Icon Vector Graphics.
628 #define WUFFS_BASE__FOURCC__ICVG 0x49435647
629
630 // Initialization.
631 #define WUFFS_BASE__FOURCC__INI 0x494E4920
632
633 // Joint Photographic Experts Group.
634 #define WUFFS_BASE__FOURCC__JPEG 0x4A504547
635
636 // JavaScript.
637 #define WUFFS_BASE__FOURCC__JS 0x4A532020
638
639 // JavaScript Object Notation.
640 #define WUFFS_BASE__FOURCC__JSON 0x4A534F4E
641
642 // JSON With Commas and Comments.
643 #define WUFFS_BASE__FOURCC__JWCC 0x4A574343
644
645 // Key-Value Pair.
646 #define WUFFS_BASE__FOURCC__KVP 0x4B565020
647
648 // Key-Value Pair (Key).
649 #define WUFFS_BASE__FOURCC__KVPK 0x4B56504B
650
651 // Key-Value Pair (Value).
652 #define WUFFS_BASE__FOURCC__KVPV 0x4B565056
653
654 // Lempel–Ziv 4.
655 #define WUFFS_BASE__FOURCC__LZ4 0x4C5A3420
656
657 // Markdown.
658 #define WUFFS_BASE__FOURCC__MD 0x4D442020
659
660 // Modification Time.
661 #define WUFFS_BASE__FOURCC__MTIM 0x4D54494D
662
663 // MPEG-1 Audio Layer III.
664 #define WUFFS_BASE__FOURCC__MP3 0x4D503320
665
666 // Naive Image.
667 #define WUFFS_BASE__FOURCC__NIE 0x4E494520
668
669 // Offset (2-Dimensional).
670 #define WUFFS_BASE__FOURCC__OFS2 0x4F465332
671
672 // Open Type Format.
673 #define WUFFS_BASE__FOURCC__OTF 0x4F544620
674
675 // Portable Document Format.
676 #define WUFFS_BASE__FOURCC__PDF 0x50444620
677
678 // Physical Dimensions.
679 #define WUFFS_BASE__FOURCC__PHYD 0x50485944
680
681 // Portable Network Graphics.
682 #define WUFFS_BASE__FOURCC__PNG 0x504E4720
683
684 // Portable Anymap.
685 #define WUFFS_BASE__FOURCC__PNM 0x504E4D20
686
687 // PostScript.
688 #define WUFFS_BASE__FOURCC__PS 0x50532020
689
690 // Quite OK Image.
691 #define WUFFS_BASE__FOURCC__QOI 0x514F4920
692
693 // Random Access Compression.
694 #define WUFFS_BASE__FOURCC__RAC 0x52414320
695
696 // Raw.
697 #define WUFFS_BASE__FOURCC__RAW 0x52415720
698
699 // Resource Interchange File Format.
700 #define WUFFS_BASE__FOURCC__RIFF 0x52494646
701
702 // Riegeli Records.
703 #define WUFFS_BASE__FOURCC__RIGL 0x5249474C
704
705 // Snappy.
706 #define WUFFS_BASE__FOURCC__SNPY 0x534E5059
707
708 // Standard Red Green Blue (Rendering Intent).
709 #define WUFFS_BASE__FOURCC__SRGB 0x53524742
710
711 // Scalable Vector Graphics.
712 #define WUFFS_BASE__FOURCC__SVG 0x53564720
713
714 // Tape Archive.
715 #define WUFFS_BASE__FOURCC__TAR 0x54415220
716
717 // Text.
718 #define WUFFS_BASE__FOURCC__TEXT 0x54455854
719
720 // Truevision Advanced Raster Graphics Adapter.
721 #define WUFFS_BASE__FOURCC__TGA 0x54474120
722
723 // Tagged Image File Format.
724 #define WUFFS_BASE__FOURCC__TIFF 0x54494646
725
726 // Tom's Obvious Minimal Language.
727 #define WUFFS_BASE__FOURCC__TOML 0x544F4D4C
728
729 // Waveform.
730 #define WUFFS_BASE__FOURCC__WAVE 0x57415645
731
732 // Wireless Bitmap.
733 #define WUFFS_BASE__FOURCC__WBMP 0x57424D50
734
735 // Web Picture.
736 #define WUFFS_BASE__FOURCC__WEBP 0x57454250
737
738 // Web Open Font Format.
739 #define WUFFS_BASE__FOURCC__WOFF 0x574F4646
740
741 // Extensible Markup Language.
742 #define WUFFS_BASE__FOURCC__XML 0x584D4C20
743
744 // Extensible Metadata Platform.
745 #define WUFFS_BASE__FOURCC__XMP 0x584D5020
746
747 // Xz.
748 #define WUFFS_BASE__FOURCC__XZ 0x585A2020
749
750 // Zip.
751 #define WUFFS_BASE__FOURCC__ZIP 0x5A495020
752
753 // Zlib.
754 #define WUFFS_BASE__FOURCC__ZLIB 0x5A4C4942
755
756 // Zstandard.
757 #define WUFFS_BASE__FOURCC__ZSTD 0x5A535444
758
759 // --------
760
761 // Quirks.
762
763 #define WUFFS_BASE__QUIRK_IGNORE_CHECKSUM 1
764
765 // --------
766
767 // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a
768 // second. See https://github.com/OculusVR/Flicks
769 typedef int64_t wuffs_base__flicks;
770
771 #define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000)
772 #define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600)
773
774 // ---------------- Numeric Types
775
776 // The helpers below are functions, instead of macros, because their arguments
777 // can be an expression that we shouldn't evaluate more than once.
778 //
779 // They are static, so that linking multiple wuffs .o files won't complain about
780 // duplicate function definitions.
781 //
782 // They are explicitly marked inline, even if modern compilers don't use the
783 // inline attribute to guide optimizations such as inlining, to avoid the
784 // -Wunused-function warning, and we like to compile with -Wall -Werror.
785
786 static inline int8_t //
wuffs_base__i8__min(int8_t x,int8_t y)787 wuffs_base__i8__min(int8_t x, int8_t y) {
788 return x < y ? x : y;
789 }
790
791 static inline int8_t //
wuffs_base__i8__max(int8_t x,int8_t y)792 wuffs_base__i8__max(int8_t x, int8_t y) {
793 return x > y ? x : y;
794 }
795
796 static inline int16_t //
wuffs_base__i16__min(int16_t x,int16_t y)797 wuffs_base__i16__min(int16_t x, int16_t y) {
798 return x < y ? x : y;
799 }
800
801 static inline int16_t //
wuffs_base__i16__max(int16_t x,int16_t y)802 wuffs_base__i16__max(int16_t x, int16_t y) {
803 return x > y ? x : y;
804 }
805
806 static inline int32_t //
wuffs_base__i32__min(int32_t x,int32_t y)807 wuffs_base__i32__min(int32_t x, int32_t y) {
808 return x < y ? x : y;
809 }
810
811 static inline int32_t //
wuffs_base__i32__max(int32_t x,int32_t y)812 wuffs_base__i32__max(int32_t x, int32_t y) {
813 return x > y ? x : y;
814 }
815
816 static inline int64_t //
wuffs_base__i64__min(int64_t x,int64_t y)817 wuffs_base__i64__min(int64_t x, int64_t y) {
818 return x < y ? x : y;
819 }
820
821 static inline int64_t //
wuffs_base__i64__max(int64_t x,int64_t y)822 wuffs_base__i64__max(int64_t x, int64_t y) {
823 return x > y ? x : y;
824 }
825
826 static inline uint8_t //
wuffs_base__u8__min(uint8_t x,uint8_t y)827 wuffs_base__u8__min(uint8_t x, uint8_t y) {
828 return x < y ? x : y;
829 }
830
831 static inline uint8_t //
wuffs_base__u8__max(uint8_t x,uint8_t y)832 wuffs_base__u8__max(uint8_t x, uint8_t y) {
833 return x > y ? x : y;
834 }
835
836 static inline uint16_t //
wuffs_base__u16__min(uint16_t x,uint16_t y)837 wuffs_base__u16__min(uint16_t x, uint16_t y) {
838 return x < y ? x : y;
839 }
840
841 static inline uint16_t //
wuffs_base__u16__max(uint16_t x,uint16_t y)842 wuffs_base__u16__max(uint16_t x, uint16_t y) {
843 return x > y ? x : y;
844 }
845
846 static inline uint32_t //
wuffs_base__u32__min(uint32_t x,uint32_t y)847 wuffs_base__u32__min(uint32_t x, uint32_t y) {
848 return x < y ? x : y;
849 }
850
851 static inline uint32_t //
wuffs_base__u32__max(uint32_t x,uint32_t y)852 wuffs_base__u32__max(uint32_t x, uint32_t y) {
853 return x > y ? x : y;
854 }
855
856 static inline uint64_t //
wuffs_base__u64__min(uint64_t x,uint64_t y)857 wuffs_base__u64__min(uint64_t x, uint64_t y) {
858 return x < y ? x : y;
859 }
860
861 static inline uint64_t //
wuffs_base__u64__max(uint64_t x,uint64_t y)862 wuffs_base__u64__max(uint64_t x, uint64_t y) {
863 return x > y ? x : y;
864 }
865
866 // --------
867
868 static inline uint8_t //
wuffs_base__u8__rotate_left(uint8_t x,uint32_t n)869 wuffs_base__u8__rotate_left(uint8_t x, uint32_t n) {
870 n &= 7;
871 return ((uint8_t)(x << n)) | ((uint8_t)(x >> (8 - n)));
872 }
873
874 static inline uint8_t //
wuffs_base__u8__rotate_right(uint8_t x,uint32_t n)875 wuffs_base__u8__rotate_right(uint8_t x, uint32_t n) {
876 n &= 7;
877 return ((uint8_t)(x >> n)) | ((uint8_t)(x << (8 - n)));
878 }
879
880 static inline uint16_t //
wuffs_base__u16__rotate_left(uint16_t x,uint32_t n)881 wuffs_base__u16__rotate_left(uint16_t x, uint32_t n) {
882 n &= 15;
883 return ((uint16_t)(x << n)) | ((uint16_t)(x >> (16 - n)));
884 }
885
886 static inline uint16_t //
wuffs_base__u16__rotate_right(uint16_t x,uint32_t n)887 wuffs_base__u16__rotate_right(uint16_t x, uint32_t n) {
888 n &= 15;
889 return ((uint16_t)(x >> n)) | ((uint16_t)(x << (16 - n)));
890 }
891
892 static inline uint32_t //
wuffs_base__u32__rotate_left(uint32_t x,uint32_t n)893 wuffs_base__u32__rotate_left(uint32_t x, uint32_t n) {
894 n &= 31;
895 return ((uint32_t)(x << n)) | ((uint32_t)(x >> (32 - n)));
896 }
897
898 static inline uint32_t //
wuffs_base__u32__rotate_right(uint32_t x,uint32_t n)899 wuffs_base__u32__rotate_right(uint32_t x, uint32_t n) {
900 n &= 31;
901 return ((uint32_t)(x >> n)) | ((uint32_t)(x << (32 - n)));
902 }
903
904 static inline uint64_t //
wuffs_base__u64__rotate_left(uint64_t x,uint32_t n)905 wuffs_base__u64__rotate_left(uint64_t x, uint32_t n) {
906 n &= 63;
907 return ((uint64_t)(x << n)) | ((uint64_t)(x >> (64 - n)));
908 }
909
910 static inline uint64_t //
wuffs_base__u64__rotate_right(uint64_t x,uint32_t n)911 wuffs_base__u64__rotate_right(uint64_t x, uint32_t n) {
912 n &= 63;
913 return ((uint64_t)(x >> n)) | ((uint64_t)(x << (64 - n)));
914 }
915
916 // --------
917
918 // Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms
919 // are per https://locklessinc.com/articles/sat_arithmetic/
920 //
921 // It is important that the underlying types are unsigned integers, as signed
922 // integer arithmetic overflow is undefined behavior in C.
923
924 static inline uint8_t //
wuffs_base__u8__sat_add(uint8_t x,uint8_t y)925 wuffs_base__u8__sat_add(uint8_t x, uint8_t y) {
926 uint8_t res = (uint8_t)(x + y);
927 res |= (uint8_t)(-(res < x));
928 return res;
929 }
930
931 static inline uint8_t //
wuffs_base__u8__sat_sub(uint8_t x,uint8_t y)932 wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) {
933 uint8_t res = (uint8_t)(x - y);
934 res &= (uint8_t)(-(res <= x));
935 return res;
936 }
937
938 static inline uint16_t //
wuffs_base__u16__sat_add(uint16_t x,uint16_t y)939 wuffs_base__u16__sat_add(uint16_t x, uint16_t y) {
940 uint16_t res = (uint16_t)(x + y);
941 res |= (uint16_t)(-(res < x));
942 return res;
943 }
944
945 static inline uint16_t //
wuffs_base__u16__sat_sub(uint16_t x,uint16_t y)946 wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) {
947 uint16_t res = (uint16_t)(x - y);
948 res &= (uint16_t)(-(res <= x));
949 return res;
950 }
951
952 static inline uint32_t //
wuffs_base__u32__sat_add(uint32_t x,uint32_t y)953 wuffs_base__u32__sat_add(uint32_t x, uint32_t y) {
954 uint32_t res = (uint32_t)(x + y);
955 res |= (uint32_t)(-(res < x));
956 return res;
957 }
958
959 static inline uint32_t //
wuffs_base__u32__sat_sub(uint32_t x,uint32_t y)960 wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) {
961 uint32_t res = (uint32_t)(x - y);
962 res &= (uint32_t)(-(res <= x));
963 return res;
964 }
965
966 static inline uint64_t //
wuffs_base__u64__sat_add(uint64_t x,uint64_t y)967 wuffs_base__u64__sat_add(uint64_t x, uint64_t y) {
968 uint64_t res = (uint64_t)(x + y);
969 res |= (uint64_t)(-(res < x));
970 return res;
971 }
972
973 static inline uint64_t //
wuffs_base__u64__sat_sub(uint64_t x,uint64_t y)974 wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) {
975 uint64_t res = (uint64_t)(x - y);
976 res &= (uint64_t)(-(res <= x));
977 return res;
978 }
979
980 // --------
981
982 typedef struct wuffs_base__multiply_u64__output__struct {
983 uint64_t lo;
984 uint64_t hi;
985 } wuffs_base__multiply_u64__output;
986
987 // wuffs_base__multiply_u64 returns x*y as a 128-bit value.
988 //
989 // The maximum inclusive output hi_lo is 0xFFFFFFFFFFFFFFFE_0000000000000001.
990 static inline wuffs_base__multiply_u64__output //
wuffs_base__multiply_u64(uint64_t x,uint64_t y)991 wuffs_base__multiply_u64(uint64_t x, uint64_t y) {
992 #if defined(__SIZEOF_INT128__)
993 __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y);
994 wuffs_base__multiply_u64__output o;
995 o.lo = ((uint64_t)(z));
996 o.hi = ((uint64_t)(z >> 64));
997 return o;
998 #else
999 // TODO: consider using the _mul128 intrinsic if defined(_MSC_VER).
1000 uint64_t x0 = x & 0xFFFFFFFF;
1001 uint64_t x1 = x >> 32;
1002 uint64_t y0 = y & 0xFFFFFFFF;
1003 uint64_t y1 = y >> 32;
1004 uint64_t w0 = x0 * y0;
1005 uint64_t t = (x1 * y0) + (w0 >> 32);
1006 uint64_t w1 = t & 0xFFFFFFFF;
1007 uint64_t w2 = t >> 32;
1008 w1 += x0 * y1;
1009 wuffs_base__multiply_u64__output o;
1010 o.lo = x * y;
1011 o.hi = (x1 * y1) + w2 + (w1 >> 32);
1012 return o;
1013 #endif
1014 }
1015
1016 // --------
1017
1018 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
1019 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
1020 #if (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1021
1022 static inline uint32_t //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1023 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1024 return u ? ((uint32_t)(__builtin_clzl(u))) : 64u;
1025 }
1026
1027 #else
1028 // TODO: consider using the _BitScanReverse intrinsic if defined(_MSC_VER).
1029
1030 static inline uint32_t //
wuffs_base__count_leading_zeroes_u64(uint64_t u)1031 wuffs_base__count_leading_zeroes_u64(uint64_t u) {
1032 if (u == 0) {
1033 return 64;
1034 }
1035
1036 uint32_t n = 0;
1037 if ((u >> 32) == 0) {
1038 n |= 32;
1039 u <<= 32;
1040 }
1041 if ((u >> 48) == 0) {
1042 n |= 16;
1043 u <<= 16;
1044 }
1045 if ((u >> 56) == 0) {
1046 n |= 8;
1047 u <<= 8;
1048 }
1049 if ((u >> 60) == 0) {
1050 n |= 4;
1051 u <<= 4;
1052 }
1053 if ((u >> 62) == 0) {
1054 n |= 2;
1055 u <<= 2;
1056 }
1057 if ((u >> 63) == 0) {
1058 n |= 1;
1059 u <<= 1;
1060 }
1061 return n;
1062 }
1063
1064 #endif // (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
1065
1066 // --------
1067
1068 #define wuffs_base__peek_u8be__no_bounds_check \
1069 wuffs_base__peek_u8__no_bounds_check
1070 #define wuffs_base__peek_u8le__no_bounds_check \
1071 wuffs_base__peek_u8__no_bounds_check
1072
1073 static inline uint8_t //
wuffs_base__peek_u8__no_bounds_check(const uint8_t * p)1074 wuffs_base__peek_u8__no_bounds_check(const uint8_t* p) {
1075 return p[0];
1076 }
1077
1078 static inline uint16_t //
wuffs_base__peek_u16be__no_bounds_check(const uint8_t * p)1079 wuffs_base__peek_u16be__no_bounds_check(const uint8_t* p) {
1080 return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
1081 }
1082
1083 static inline uint16_t //
wuffs_base__peek_u16le__no_bounds_check(const uint8_t * p)1084 wuffs_base__peek_u16le__no_bounds_check(const uint8_t* p) {
1085 return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
1086 }
1087
1088 static inline uint32_t //
wuffs_base__peek_u24be__no_bounds_check(const uint8_t * p)1089 wuffs_base__peek_u24be__no_bounds_check(const uint8_t* p) {
1090 return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
1091 ((uint32_t)(p[2]) << 0);
1092 }
1093
1094 static inline uint32_t //
wuffs_base__peek_u24le__no_bounds_check(const uint8_t * p)1095 wuffs_base__peek_u24le__no_bounds_check(const uint8_t* p) {
1096 return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1097 ((uint32_t)(p[2]) << 16);
1098 }
1099
1100 static inline uint32_t //
wuffs_base__peek_u32be__no_bounds_check(const uint8_t * p)1101 wuffs_base__peek_u32be__no_bounds_check(const uint8_t* p) {
1102 return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
1103 ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
1104 }
1105
1106 static inline uint32_t //
wuffs_base__peek_u32le__no_bounds_check(const uint8_t * p)1107 wuffs_base__peek_u32le__no_bounds_check(const uint8_t* p) {
1108 return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
1109 ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
1110 }
1111
1112 static inline uint64_t //
wuffs_base__peek_u40be__no_bounds_check(const uint8_t * p)1113 wuffs_base__peek_u40be__no_bounds_check(const uint8_t* p) {
1114 return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
1115 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
1116 ((uint64_t)(p[4]) << 0);
1117 }
1118
1119 static inline uint64_t //
wuffs_base__peek_u40le__no_bounds_check(const uint8_t * p)1120 wuffs_base__peek_u40le__no_bounds_check(const uint8_t* p) {
1121 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1122 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1123 ((uint64_t)(p[4]) << 32);
1124 }
1125
1126 static inline uint64_t //
wuffs_base__peek_u48be__no_bounds_check(const uint8_t * p)1127 wuffs_base__peek_u48be__no_bounds_check(const uint8_t* p) {
1128 return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
1129 ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
1130 ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
1131 }
1132
1133 static inline uint64_t //
wuffs_base__peek_u48le__no_bounds_check(const uint8_t * p)1134 wuffs_base__peek_u48le__no_bounds_check(const uint8_t* p) {
1135 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1136 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1137 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
1138 }
1139
1140 static inline uint64_t //
wuffs_base__peek_u56be__no_bounds_check(const uint8_t * p)1141 wuffs_base__peek_u56be__no_bounds_check(const uint8_t* p) {
1142 return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
1143 ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
1144 ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
1145 ((uint64_t)(p[6]) << 0);
1146 }
1147
1148 static inline uint64_t //
wuffs_base__peek_u56le__no_bounds_check(const uint8_t * p)1149 wuffs_base__peek_u56le__no_bounds_check(const uint8_t* p) {
1150 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1151 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1152 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1153 ((uint64_t)(p[6]) << 48);
1154 }
1155
1156 static inline uint64_t //
wuffs_base__peek_u64be__no_bounds_check(const uint8_t * p)1157 wuffs_base__peek_u64be__no_bounds_check(const uint8_t* p) {
1158 return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
1159 ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
1160 ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
1161 ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
1162 }
1163
1164 static inline uint64_t //
wuffs_base__peek_u64le__no_bounds_check(const uint8_t * p)1165 wuffs_base__peek_u64le__no_bounds_check(const uint8_t* p) {
1166 return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
1167 ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
1168 ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
1169 ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
1170 }
1171
1172 // --------
1173
1174 #define wuffs_base__poke_u8be__no_bounds_check \
1175 wuffs_base__poke_u8__no_bounds_check
1176 #define wuffs_base__poke_u8le__no_bounds_check \
1177 wuffs_base__poke_u8__no_bounds_check
1178
1179 static inline void //
wuffs_base__poke_u8__no_bounds_check(uint8_t * p,uint8_t x)1180 wuffs_base__poke_u8__no_bounds_check(uint8_t* p, uint8_t x) {
1181 p[0] = x;
1182 }
1183
1184 static inline void //
wuffs_base__poke_u16be__no_bounds_check(uint8_t * p,uint16_t x)1185 wuffs_base__poke_u16be__no_bounds_check(uint8_t* p, uint16_t x) {
1186 p[0] = (uint8_t)(x >> 8);
1187 p[1] = (uint8_t)(x >> 0);
1188 }
1189
1190 static inline void //
wuffs_base__poke_u16le__no_bounds_check(uint8_t * p,uint16_t x)1191 wuffs_base__poke_u16le__no_bounds_check(uint8_t* p, uint16_t x) {
1192 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1193 // This seems to perform better on gcc 10 (but not clang 9). Clang also
1194 // defines "__GNUC__".
1195 memcpy(p, &x, 2);
1196 #else
1197 p[0] = (uint8_t)(x >> 0);
1198 p[1] = (uint8_t)(x >> 8);
1199 #endif
1200 }
1201
1202 static inline void //
wuffs_base__poke_u24be__no_bounds_check(uint8_t * p,uint32_t x)1203 wuffs_base__poke_u24be__no_bounds_check(uint8_t* p, uint32_t x) {
1204 p[0] = (uint8_t)(x >> 16);
1205 p[1] = (uint8_t)(x >> 8);
1206 p[2] = (uint8_t)(x >> 0);
1207 }
1208
1209 static inline void //
wuffs_base__poke_u24le__no_bounds_check(uint8_t * p,uint32_t x)1210 wuffs_base__poke_u24le__no_bounds_check(uint8_t* p, uint32_t x) {
1211 p[0] = (uint8_t)(x >> 0);
1212 p[1] = (uint8_t)(x >> 8);
1213 p[2] = (uint8_t)(x >> 16);
1214 }
1215
1216 static inline void //
wuffs_base__poke_u32be__no_bounds_check(uint8_t * p,uint32_t x)1217 wuffs_base__poke_u32be__no_bounds_check(uint8_t* p, uint32_t x) {
1218 p[0] = (uint8_t)(x >> 24);
1219 p[1] = (uint8_t)(x >> 16);
1220 p[2] = (uint8_t)(x >> 8);
1221 p[3] = (uint8_t)(x >> 0);
1222 }
1223
1224 static inline void //
wuffs_base__poke_u32le__no_bounds_check(uint8_t * p,uint32_t x)1225 wuffs_base__poke_u32le__no_bounds_check(uint8_t* p, uint32_t x) {
1226 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1227 // This seems to perform better on gcc 10 (but not clang 9). Clang also
1228 // defines "__GNUC__".
1229 memcpy(p, &x, 4);
1230 #else
1231 p[0] = (uint8_t)(x >> 0);
1232 p[1] = (uint8_t)(x >> 8);
1233 p[2] = (uint8_t)(x >> 16);
1234 p[3] = (uint8_t)(x >> 24);
1235 #endif
1236 }
1237
1238 static inline void //
wuffs_base__poke_u40be__no_bounds_check(uint8_t * p,uint64_t x)1239 wuffs_base__poke_u40be__no_bounds_check(uint8_t* p, uint64_t x) {
1240 p[0] = (uint8_t)(x >> 32);
1241 p[1] = (uint8_t)(x >> 24);
1242 p[2] = (uint8_t)(x >> 16);
1243 p[3] = (uint8_t)(x >> 8);
1244 p[4] = (uint8_t)(x >> 0);
1245 }
1246
1247 static inline void //
wuffs_base__poke_u40le__no_bounds_check(uint8_t * p,uint64_t x)1248 wuffs_base__poke_u40le__no_bounds_check(uint8_t* p, uint64_t x) {
1249 p[0] = (uint8_t)(x >> 0);
1250 p[1] = (uint8_t)(x >> 8);
1251 p[2] = (uint8_t)(x >> 16);
1252 p[3] = (uint8_t)(x >> 24);
1253 p[4] = (uint8_t)(x >> 32);
1254 }
1255
1256 static inline void //
wuffs_base__poke_u48be__no_bounds_check(uint8_t * p,uint64_t x)1257 wuffs_base__poke_u48be__no_bounds_check(uint8_t* p, uint64_t x) {
1258 p[0] = (uint8_t)(x >> 40);
1259 p[1] = (uint8_t)(x >> 32);
1260 p[2] = (uint8_t)(x >> 24);
1261 p[3] = (uint8_t)(x >> 16);
1262 p[4] = (uint8_t)(x >> 8);
1263 p[5] = (uint8_t)(x >> 0);
1264 }
1265
1266 static inline void //
wuffs_base__poke_u48le__no_bounds_check(uint8_t * p,uint64_t x)1267 wuffs_base__poke_u48le__no_bounds_check(uint8_t* p, uint64_t x) {
1268 p[0] = (uint8_t)(x >> 0);
1269 p[1] = (uint8_t)(x >> 8);
1270 p[2] = (uint8_t)(x >> 16);
1271 p[3] = (uint8_t)(x >> 24);
1272 p[4] = (uint8_t)(x >> 32);
1273 p[5] = (uint8_t)(x >> 40);
1274 }
1275
1276 static inline void //
wuffs_base__poke_u56be__no_bounds_check(uint8_t * p,uint64_t x)1277 wuffs_base__poke_u56be__no_bounds_check(uint8_t* p, uint64_t x) {
1278 p[0] = (uint8_t)(x >> 48);
1279 p[1] = (uint8_t)(x >> 40);
1280 p[2] = (uint8_t)(x >> 32);
1281 p[3] = (uint8_t)(x >> 24);
1282 p[4] = (uint8_t)(x >> 16);
1283 p[5] = (uint8_t)(x >> 8);
1284 p[6] = (uint8_t)(x >> 0);
1285 }
1286
1287 static inline void //
wuffs_base__poke_u56le__no_bounds_check(uint8_t * p,uint64_t x)1288 wuffs_base__poke_u56le__no_bounds_check(uint8_t* p, uint64_t x) {
1289 p[0] = (uint8_t)(x >> 0);
1290 p[1] = (uint8_t)(x >> 8);
1291 p[2] = (uint8_t)(x >> 16);
1292 p[3] = (uint8_t)(x >> 24);
1293 p[4] = (uint8_t)(x >> 32);
1294 p[5] = (uint8_t)(x >> 40);
1295 p[6] = (uint8_t)(x >> 48);
1296 }
1297
1298 static inline void //
wuffs_base__poke_u64be__no_bounds_check(uint8_t * p,uint64_t x)1299 wuffs_base__poke_u64be__no_bounds_check(uint8_t* p, uint64_t x) {
1300 p[0] = (uint8_t)(x >> 56);
1301 p[1] = (uint8_t)(x >> 48);
1302 p[2] = (uint8_t)(x >> 40);
1303 p[3] = (uint8_t)(x >> 32);
1304 p[4] = (uint8_t)(x >> 24);
1305 p[5] = (uint8_t)(x >> 16);
1306 p[6] = (uint8_t)(x >> 8);
1307 p[7] = (uint8_t)(x >> 0);
1308 }
1309
1310 static inline void //
wuffs_base__poke_u64le__no_bounds_check(uint8_t * p,uint64_t x)1311 wuffs_base__poke_u64le__no_bounds_check(uint8_t* p, uint64_t x) {
1312 #if defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__)
1313 // This seems to perform better on gcc 10 (but not clang 9). Clang also
1314 // defines "__GNUC__".
1315 memcpy(p, &x, 8);
1316 #else
1317 p[0] = (uint8_t)(x >> 0);
1318 p[1] = (uint8_t)(x >> 8);
1319 p[2] = (uint8_t)(x >> 16);
1320 p[3] = (uint8_t)(x >> 24);
1321 p[4] = (uint8_t)(x >> 32);
1322 p[5] = (uint8_t)(x >> 40);
1323 p[6] = (uint8_t)(x >> 48);
1324 p[7] = (uint8_t)(x >> 56);
1325 #endif
1326 }
1327
1328 // --------
1329
1330 // Load and Store functions are deprecated. Use Peek and Poke instead.
1331
1332 #define wuffs_base__load_u8__no_bounds_check \
1333 wuffs_base__peek_u8__no_bounds_check
1334 #define wuffs_base__load_u16be__no_bounds_check \
1335 wuffs_base__peek_u16be__no_bounds_check
1336 #define wuffs_base__load_u16le__no_bounds_check \
1337 wuffs_base__peek_u16le__no_bounds_check
1338 #define wuffs_base__load_u24be__no_bounds_check \
1339 wuffs_base__peek_u24be__no_bounds_check
1340 #define wuffs_base__load_u24le__no_bounds_check \
1341 wuffs_base__peek_u24le__no_bounds_check
1342 #define wuffs_base__load_u32be__no_bounds_check \
1343 wuffs_base__peek_u32be__no_bounds_check
1344 #define wuffs_base__load_u32le__no_bounds_check \
1345 wuffs_base__peek_u32le__no_bounds_check
1346 #define wuffs_base__load_u40be__no_bounds_check \
1347 wuffs_base__peek_u40be__no_bounds_check
1348 #define wuffs_base__load_u40le__no_bounds_check \
1349 wuffs_base__peek_u40le__no_bounds_check
1350 #define wuffs_base__load_u48be__no_bounds_check \
1351 wuffs_base__peek_u48be__no_bounds_check
1352 #define wuffs_base__load_u48le__no_bounds_check \
1353 wuffs_base__peek_u48le__no_bounds_check
1354 #define wuffs_base__load_u56be__no_bounds_check \
1355 wuffs_base__peek_u56be__no_bounds_check
1356 #define wuffs_base__load_u56le__no_bounds_check \
1357 wuffs_base__peek_u56le__no_bounds_check
1358 #define wuffs_base__load_u64be__no_bounds_check \
1359 wuffs_base__peek_u64be__no_bounds_check
1360 #define wuffs_base__load_u64le__no_bounds_check \
1361 wuffs_base__peek_u64le__no_bounds_check
1362
1363 #define wuffs_base__store_u8__no_bounds_check \
1364 wuffs_base__poke_u8__no_bounds_check
1365 #define wuffs_base__store_u16be__no_bounds_check \
1366 wuffs_base__poke_u16be__no_bounds_check
1367 #define wuffs_base__store_u16le__no_bounds_check \
1368 wuffs_base__poke_u16le__no_bounds_check
1369 #define wuffs_base__store_u24be__no_bounds_check \
1370 wuffs_base__poke_u24be__no_bounds_check
1371 #define wuffs_base__store_u24le__no_bounds_check \
1372 wuffs_base__poke_u24le__no_bounds_check
1373 #define wuffs_base__store_u32be__no_bounds_check \
1374 wuffs_base__poke_u32be__no_bounds_check
1375 #define wuffs_base__store_u32le__no_bounds_check \
1376 wuffs_base__poke_u32le__no_bounds_check
1377 #define wuffs_base__store_u40be__no_bounds_check \
1378 wuffs_base__poke_u40be__no_bounds_check
1379 #define wuffs_base__store_u40le__no_bounds_check \
1380 wuffs_base__poke_u40le__no_bounds_check
1381 #define wuffs_base__store_u48be__no_bounds_check \
1382 wuffs_base__poke_u48be__no_bounds_check
1383 #define wuffs_base__store_u48le__no_bounds_check \
1384 wuffs_base__poke_u48le__no_bounds_check
1385 #define wuffs_base__store_u56be__no_bounds_check \
1386 wuffs_base__poke_u56be__no_bounds_check
1387 #define wuffs_base__store_u56le__no_bounds_check \
1388 wuffs_base__poke_u56le__no_bounds_check
1389 #define wuffs_base__store_u64be__no_bounds_check \
1390 wuffs_base__poke_u64be__no_bounds_check
1391 #define wuffs_base__store_u64le__no_bounds_check \
1392 wuffs_base__poke_u64le__no_bounds_check
1393
1394 // ---------------- Slices and Tables
1395
1396 // WUFFS_BASE__SLICE is a 1-dimensional buffer.
1397 //
1398 // len measures a number of elements, not necessarily a size in bytes.
1399 //
1400 // A value with all fields NULL or zero is a valid, empty slice.
1401 #define WUFFS_BASE__SLICE(T) \
1402 struct { \
1403 T* ptr; \
1404 size_t len; \
1405 }
1406
1407 // WUFFS_BASE__TABLE is a 2-dimensional buffer.
1408 //
1409 // width, height and stride measure a number of elements, not necessarily a
1410 // size in bytes.
1411 //
1412 // A value with all fields NULL or zero is a valid, empty table.
1413 #define WUFFS_BASE__TABLE(T) \
1414 struct { \
1415 T* ptr; \
1416 size_t width; \
1417 size_t height; \
1418 size_t stride; \
1419 }
1420
1421 typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8;
1422 typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16;
1423 typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32;
1424 typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64;
1425
1426 typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8;
1427 typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16;
1428 typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32;
1429 typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64;
1430
1431 static inline wuffs_base__slice_u8 //
wuffs_base__make_slice_u8(uint8_t * ptr,size_t len)1432 wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) {
1433 wuffs_base__slice_u8 ret;
1434 ret.ptr = ptr;
1435 ret.len = len;
1436 return ret;
1437 }
1438
1439 static inline wuffs_base__slice_u16 //
wuffs_base__make_slice_u16(uint16_t * ptr,size_t len)1440 wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) {
1441 wuffs_base__slice_u16 ret;
1442 ret.ptr = ptr;
1443 ret.len = len;
1444 return ret;
1445 }
1446
1447 static inline wuffs_base__slice_u32 //
wuffs_base__make_slice_u32(uint32_t * ptr,size_t len)1448 wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) {
1449 wuffs_base__slice_u32 ret;
1450 ret.ptr = ptr;
1451 ret.len = len;
1452 return ret;
1453 }
1454
1455 static inline wuffs_base__slice_u64 //
wuffs_base__make_slice_u64(uint64_t * ptr,size_t len)1456 wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) {
1457 wuffs_base__slice_u64 ret;
1458 ret.ptr = ptr;
1459 ret.len = len;
1460 return ret;
1461 }
1462
1463 static inline wuffs_base__slice_u8 //
wuffs_base__empty_slice_u8()1464 wuffs_base__empty_slice_u8() {
1465 wuffs_base__slice_u8 ret;
1466 ret.ptr = NULL;
1467 ret.len = 0;
1468 return ret;
1469 }
1470
1471 static inline wuffs_base__slice_u16 //
wuffs_base__empty_slice_u16()1472 wuffs_base__empty_slice_u16() {
1473 wuffs_base__slice_u16 ret;
1474 ret.ptr = NULL;
1475 ret.len = 0;
1476 return ret;
1477 }
1478
1479 static inline wuffs_base__slice_u32 //
wuffs_base__empty_slice_u32()1480 wuffs_base__empty_slice_u32() {
1481 wuffs_base__slice_u32 ret;
1482 ret.ptr = NULL;
1483 ret.len = 0;
1484 return ret;
1485 }
1486
1487 static inline wuffs_base__slice_u64 //
wuffs_base__empty_slice_u64()1488 wuffs_base__empty_slice_u64() {
1489 wuffs_base__slice_u64 ret;
1490 ret.ptr = NULL;
1491 ret.len = 0;
1492 return ret;
1493 }
1494
1495 static inline wuffs_base__table_u8 //
wuffs_base__make_table_u8(uint8_t * ptr,size_t width,size_t height,size_t stride)1496 wuffs_base__make_table_u8(uint8_t* ptr,
1497 size_t width,
1498 size_t height,
1499 size_t stride) {
1500 wuffs_base__table_u8 ret;
1501 ret.ptr = ptr;
1502 ret.width = width;
1503 ret.height = height;
1504 ret.stride = stride;
1505 return ret;
1506 }
1507
1508 static inline wuffs_base__table_u16 //
wuffs_base__make_table_u16(uint16_t * ptr,size_t width,size_t height,size_t stride)1509 wuffs_base__make_table_u16(uint16_t* ptr,
1510 size_t width,
1511 size_t height,
1512 size_t stride) {
1513 wuffs_base__table_u16 ret;
1514 ret.ptr = ptr;
1515 ret.width = width;
1516 ret.height = height;
1517 ret.stride = stride;
1518 return ret;
1519 }
1520
1521 static inline wuffs_base__table_u32 //
wuffs_base__make_table_u32(uint32_t * ptr,size_t width,size_t height,size_t stride)1522 wuffs_base__make_table_u32(uint32_t* ptr,
1523 size_t width,
1524 size_t height,
1525 size_t stride) {
1526 wuffs_base__table_u32 ret;
1527 ret.ptr = ptr;
1528 ret.width = width;
1529 ret.height = height;
1530 ret.stride = stride;
1531 return ret;
1532 }
1533
1534 static inline wuffs_base__table_u64 //
wuffs_base__make_table_u64(uint64_t * ptr,size_t width,size_t height,size_t stride)1535 wuffs_base__make_table_u64(uint64_t* ptr,
1536 size_t width,
1537 size_t height,
1538 size_t stride) {
1539 wuffs_base__table_u64 ret;
1540 ret.ptr = ptr;
1541 ret.width = width;
1542 ret.height = height;
1543 ret.stride = stride;
1544 return ret;
1545 }
1546
1547 static inline wuffs_base__table_u8 //
wuffs_base__empty_table_u8()1548 wuffs_base__empty_table_u8() {
1549 wuffs_base__table_u8 ret;
1550 ret.ptr = NULL;
1551 ret.width = 0;
1552 ret.height = 0;
1553 ret.stride = 0;
1554 return ret;
1555 }
1556
1557 static inline wuffs_base__table_u16 //
wuffs_base__empty_table_u16()1558 wuffs_base__empty_table_u16() {
1559 wuffs_base__table_u16 ret;
1560 ret.ptr = NULL;
1561 ret.width = 0;
1562 ret.height = 0;
1563 ret.stride = 0;
1564 return ret;
1565 }
1566
1567 static inline wuffs_base__table_u32 //
wuffs_base__empty_table_u32()1568 wuffs_base__empty_table_u32() {
1569 wuffs_base__table_u32 ret;
1570 ret.ptr = NULL;
1571 ret.width = 0;
1572 ret.height = 0;
1573 ret.stride = 0;
1574 return ret;
1575 }
1576
1577 static inline wuffs_base__table_u64 //
wuffs_base__empty_table_u64()1578 wuffs_base__empty_table_u64() {
1579 wuffs_base__table_u64 ret;
1580 ret.ptr = NULL;
1581 ret.width = 0;
1582 ret.height = 0;
1583 ret.stride = 0;
1584 return ret;
1585 }
1586
1587 static inline bool //
wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s,wuffs_base__slice_u8 t)1588 wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {
1589 return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||
1590 ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));
1591 }
1592
1593 // wuffs_base__slice_u8__subslice_i returns s[i:].
1594 //
1595 // It returns an empty slice if i is out of bounds.
1596 static inline wuffs_base__slice_u8 //
wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s,uint64_t i)1597 wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) {
1598 if ((i <= SIZE_MAX) && (i <= s.len)) {
1599 return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i)));
1600 }
1601 return wuffs_base__make_slice_u8(NULL, 0);
1602 }
1603
1604 // wuffs_base__slice_u8__subslice_j returns s[:j].
1605 //
1606 // It returns an empty slice if j is out of bounds.
1607 static inline wuffs_base__slice_u8 //
wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s,uint64_t j)1608 wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) {
1609 if ((j <= SIZE_MAX) && (j <= s.len)) {
1610 return wuffs_base__make_slice_u8(s.ptr, ((size_t)j));
1611 }
1612 return wuffs_base__make_slice_u8(NULL, 0);
1613 }
1614
1615 // wuffs_base__slice_u8__subslice_ij returns s[i:j].
1616 //
1617 // It returns an empty slice if i or j is out of bounds.
1618 static inline wuffs_base__slice_u8 //
wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,uint64_t i,uint64_t j)1619 wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s,
1620 uint64_t i,
1621 uint64_t j) {
1622 if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) {
1623 return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i)));
1624 }
1625 return wuffs_base__make_slice_u8(NULL, 0);
1626 }
1627
1628 // wuffs_base__table_u8__subtable_ij returns t[ix:jx, iy:jy].
1629 //
1630 // It returns an empty table if i or j is out of bounds.
1631 static inline wuffs_base__table_u8 //
wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,uint64_t ix,uint64_t iy,uint64_t jx,uint64_t jy)1632 wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,
1633 uint64_t ix,
1634 uint64_t iy,
1635 uint64_t jx,
1636 uint64_t jy) {
1637 if ((ix <= jx) && (jx <= SIZE_MAX) && (jx <= t.width) && //
1638 (iy <= jy) && (jy <= SIZE_MAX) && (jy <= t.height)) {
1639 return wuffs_base__make_table_u8(t.ptr + ix + (iy * t.stride), //
1640 ((size_t)(jx - ix)), //
1641 ((size_t)(jy - iy)), //
1642 t.stride); //
1643 }
1644 return wuffs_base__make_table_u8(NULL, 0, 0, 0);
1645 }
1646
1647 // wuffs_base__table__flattened_length returns the number of elements covered
1648 // by the 1-dimensional span that backs a 2-dimensional table. This counts the
1649 // elements inside the table and, when width != stride, the elements outside
1650 // the table but between its rows.
1651 //
1652 // For example, consider a width 10, height 4, stride 10 table. Mark its first
1653 // and last (inclusive) elements with 'a' and 'z'. This function returns 40.
1654 //
1655 // a123456789
1656 // 0123456789
1657 // 0123456789
1658 // 012345678z
1659 //
1660 // Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
1661 //
1662 // a123456789
1663 // 01iiiiiioo
1664 // ooiiiiiioo
1665 // ooiiiiii8z
1666 //
1667 // This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
1668 // inside elements plus 8 'o' outside elements. Note that 26 is less than a
1669 // naive (height * stride = 30) computation. Indeed, advancing 29 elements from
1670 // the first 'i' would venture past 'z', out of bounds of the original table.
1671 //
1672 // It does not check for overflow, but if the arguments come from a table that
1673 // exists in memory and each element occupies a positive number of bytes then
1674 // the result should be bounded by the amount of allocatable memory (which
1675 // shouldn't overflow SIZE_MAX).
1676 static inline size_t //
wuffs_base__table__flattened_length(size_t width,size_t height,size_t stride)1677 wuffs_base__table__flattened_length(size_t width,
1678 size_t height,
1679 size_t stride) {
1680 if (height == 0) {
1681 return 0;
1682 }
1683 return ((height - 1) * stride) + width;
1684 }
1685
1686 // ---------------- Magic Numbers
1687
1688 // wuffs_base__magic_number_guess_fourcc guesses the file format of some data,
1689 // given its starting bytes (the prefix_data argument) and whether or not there
1690 // may be further bytes (the prefix_closed argument; true means that
1691 // prefix_data is the entire data).
1692 //
1693 // It returns a positive FourCC value on success.
1694 //
1695 // It returns zero if nothing matches its hard-coded list of 'magic numbers'.
1696 //
1697 // It returns a negative value if prefix_closed is false and a longer prefix is
1698 // required for a conclusive result. For example, a single 'B' byte (without
1699 // further data) is not enough to discriminate the BMP and BPG image file
1700 // formats. Similarly, a single '\xFF' byte might be the start of JPEG data or
1701 // it might be the start of some other binary data.
1702 //
1703 // It does not do a full validity check. Like any guess made from a short
1704 // prefix of the data, it may return false positives. Data that starts with 99
1705 // bytes of valid JPEG followed by corruption or truncation is an invalid JPEG
1706 // image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.
1707 //
1708 // Another source of false positives is that some 'magic numbers' are valid
1709 // ASCII data. A file starting with "GIF87a and GIF89a are the two versions of
1710 // GIF" will match GIF's 'magic number' even if it's plain text, not an image.
1711 //
1712 // For modular builds that divide the base module into sub-modules, using this
1713 // function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just
1714 // WUFFS_CONFIG__MODULE__BASE__CORE.
1715 WUFFS_BASE__MAYBE_STATIC int32_t //
1716 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
1717 bool prefix_closed);
1718
1719 // ---------------- Ranges and Rects
1720
1721 // See https://github.com/google/wuffs/blob/main/doc/note/ranges-and-rects.md
1722
1723 typedef struct wuffs_base__range_ii_u32__struct {
1724 uint32_t min_incl;
1725 uint32_t max_incl;
1726
1727 #ifdef __cplusplus
1728 inline bool is_empty() const;
1729 inline bool equals(wuffs_base__range_ii_u32__struct s) const;
1730 inline wuffs_base__range_ii_u32__struct intersect(
1731 wuffs_base__range_ii_u32__struct s) const;
1732 inline wuffs_base__range_ii_u32__struct unite(
1733 wuffs_base__range_ii_u32__struct s) const;
1734 inline bool contains(uint32_t x) const;
1735 inline bool contains_range(wuffs_base__range_ii_u32__struct s) const;
1736 #endif // __cplusplus
1737
1738 } wuffs_base__range_ii_u32;
1739
1740 static inline wuffs_base__range_ii_u32 //
wuffs_base__empty_range_ii_u32()1741 wuffs_base__empty_range_ii_u32() {
1742 wuffs_base__range_ii_u32 ret;
1743 ret.min_incl = 0;
1744 ret.max_incl = 0;
1745 return ret;
1746 }
1747
1748 static inline wuffs_base__range_ii_u32 //
wuffs_base__make_range_ii_u32(uint32_t min_incl,uint32_t max_incl)1749 wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) {
1750 wuffs_base__range_ii_u32 ret;
1751 ret.min_incl = min_incl;
1752 ret.max_incl = max_incl;
1753 return ret;
1754 }
1755
1756 static inline bool //
wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32 * r)1757 wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) {
1758 return r->min_incl > r->max_incl;
1759 }
1760
1761 static inline bool //
wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1762 wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r,
1763 wuffs_base__range_ii_u32 s) {
1764 return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
1765 (wuffs_base__range_ii_u32__is_empty(r) &&
1766 wuffs_base__range_ii_u32__is_empty(&s));
1767 }
1768
1769 static inline wuffs_base__range_ii_u32 //
wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1770 wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r,
1771 wuffs_base__range_ii_u32 s) {
1772 wuffs_base__range_ii_u32 t;
1773 t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1774 t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl);
1775 return t;
1776 }
1777
1778 static inline wuffs_base__range_ii_u32 //
wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1779 wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r,
1780 wuffs_base__range_ii_u32 s) {
1781 if (wuffs_base__range_ii_u32__is_empty(r)) {
1782 return s;
1783 }
1784 if (wuffs_base__range_ii_u32__is_empty(&s)) {
1785 return *r;
1786 }
1787 wuffs_base__range_ii_u32 t;
1788 t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1789 t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl);
1790 return t;
1791 }
1792
1793 static inline bool //
wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32 * r,uint32_t x)1794 wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r,
1795 uint32_t x) {
1796 return (r->min_incl <= x) && (x <= r->max_incl);
1797 }
1798
1799 static inline bool //
wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32 * r,wuffs_base__range_ii_u32 s)1800 wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r,
1801 wuffs_base__range_ii_u32 s) {
1802 return wuffs_base__range_ii_u32__equals(
1803 &s, wuffs_base__range_ii_u32__intersect(r, s));
1804 }
1805
1806 #ifdef __cplusplus
1807
1808 inline bool //
is_empty()1809 wuffs_base__range_ii_u32::is_empty() const {
1810 return wuffs_base__range_ii_u32__is_empty(this);
1811 }
1812
1813 inline bool //
equals(wuffs_base__range_ii_u32 s)1814 wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const {
1815 return wuffs_base__range_ii_u32__equals(this, s);
1816 }
1817
1818 inline wuffs_base__range_ii_u32 //
intersect(wuffs_base__range_ii_u32 s)1819 wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const {
1820 return wuffs_base__range_ii_u32__intersect(this, s);
1821 }
1822
1823 inline wuffs_base__range_ii_u32 //
unite(wuffs_base__range_ii_u32 s)1824 wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const {
1825 return wuffs_base__range_ii_u32__unite(this, s);
1826 }
1827
1828 inline bool //
contains(uint32_t x)1829 wuffs_base__range_ii_u32::contains(uint32_t x) const {
1830 return wuffs_base__range_ii_u32__contains(this, x);
1831 }
1832
1833 inline bool //
contains_range(wuffs_base__range_ii_u32 s)1834 wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const {
1835 return wuffs_base__range_ii_u32__contains_range(this, s);
1836 }
1837
1838 #endif // __cplusplus
1839
1840 // --------
1841
1842 typedef struct wuffs_base__range_ie_u32__struct {
1843 uint32_t min_incl;
1844 uint32_t max_excl;
1845
1846 #ifdef __cplusplus
1847 inline bool is_empty() const;
1848 inline bool equals(wuffs_base__range_ie_u32__struct s) const;
1849 inline wuffs_base__range_ie_u32__struct intersect(
1850 wuffs_base__range_ie_u32__struct s) const;
1851 inline wuffs_base__range_ie_u32__struct unite(
1852 wuffs_base__range_ie_u32__struct s) const;
1853 inline bool contains(uint32_t x) const;
1854 inline bool contains_range(wuffs_base__range_ie_u32__struct s) const;
1855 inline uint32_t length() const;
1856 #endif // __cplusplus
1857
1858 } wuffs_base__range_ie_u32;
1859
1860 static inline wuffs_base__range_ie_u32 //
wuffs_base__empty_range_ie_u32()1861 wuffs_base__empty_range_ie_u32() {
1862 wuffs_base__range_ie_u32 ret;
1863 ret.min_incl = 0;
1864 ret.max_excl = 0;
1865 return ret;
1866 }
1867
1868 static inline wuffs_base__range_ie_u32 //
wuffs_base__make_range_ie_u32(uint32_t min_incl,uint32_t max_excl)1869 wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) {
1870 wuffs_base__range_ie_u32 ret;
1871 ret.min_incl = min_incl;
1872 ret.max_excl = max_excl;
1873 return ret;
1874 }
1875
1876 static inline bool //
wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32 * r)1877 wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) {
1878 return r->min_incl >= r->max_excl;
1879 }
1880
1881 static inline bool //
wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1882 wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r,
1883 wuffs_base__range_ie_u32 s) {
1884 return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
1885 (wuffs_base__range_ie_u32__is_empty(r) &&
1886 wuffs_base__range_ie_u32__is_empty(&s));
1887 }
1888
1889 static inline wuffs_base__range_ie_u32 //
wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1890 wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r,
1891 wuffs_base__range_ie_u32 s) {
1892 wuffs_base__range_ie_u32 t;
1893 t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl);
1894 t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl);
1895 return t;
1896 }
1897
1898 static inline wuffs_base__range_ie_u32 //
wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1899 wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r,
1900 wuffs_base__range_ie_u32 s) {
1901 if (wuffs_base__range_ie_u32__is_empty(r)) {
1902 return s;
1903 }
1904 if (wuffs_base__range_ie_u32__is_empty(&s)) {
1905 return *r;
1906 }
1907 wuffs_base__range_ie_u32 t;
1908 t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl);
1909 t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl);
1910 return t;
1911 }
1912
1913 static inline bool //
wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32 * r,uint32_t x)1914 wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r,
1915 uint32_t x) {
1916 return (r->min_incl <= x) && (x < r->max_excl);
1917 }
1918
1919 static inline bool //
wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32 * r,wuffs_base__range_ie_u32 s)1920 wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r,
1921 wuffs_base__range_ie_u32 s) {
1922 return wuffs_base__range_ie_u32__equals(
1923 &s, wuffs_base__range_ie_u32__intersect(r, s));
1924 }
1925
1926 static inline uint32_t //
wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32 * r)1927 wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) {
1928 return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl);
1929 }
1930
1931 #ifdef __cplusplus
1932
1933 inline bool //
is_empty()1934 wuffs_base__range_ie_u32::is_empty() const {
1935 return wuffs_base__range_ie_u32__is_empty(this);
1936 }
1937
1938 inline bool //
equals(wuffs_base__range_ie_u32 s)1939 wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const {
1940 return wuffs_base__range_ie_u32__equals(this, s);
1941 }
1942
1943 inline wuffs_base__range_ie_u32 //
intersect(wuffs_base__range_ie_u32 s)1944 wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const {
1945 return wuffs_base__range_ie_u32__intersect(this, s);
1946 }
1947
1948 inline wuffs_base__range_ie_u32 //
unite(wuffs_base__range_ie_u32 s)1949 wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const {
1950 return wuffs_base__range_ie_u32__unite(this, s);
1951 }
1952
1953 inline bool //
contains(uint32_t x)1954 wuffs_base__range_ie_u32::contains(uint32_t x) const {
1955 return wuffs_base__range_ie_u32__contains(this, x);
1956 }
1957
1958 inline bool //
contains_range(wuffs_base__range_ie_u32 s)1959 wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const {
1960 return wuffs_base__range_ie_u32__contains_range(this, s);
1961 }
1962
1963 inline uint32_t //
length()1964 wuffs_base__range_ie_u32::length() const {
1965 return wuffs_base__range_ie_u32__length(this);
1966 }
1967
1968 #endif // __cplusplus
1969
1970 // --------
1971
1972 typedef struct wuffs_base__range_ii_u64__struct {
1973 uint64_t min_incl;
1974 uint64_t max_incl;
1975
1976 #ifdef __cplusplus
1977 inline bool is_empty() const;
1978 inline bool equals(wuffs_base__range_ii_u64__struct s) const;
1979 inline wuffs_base__range_ii_u64__struct intersect(
1980 wuffs_base__range_ii_u64__struct s) const;
1981 inline wuffs_base__range_ii_u64__struct unite(
1982 wuffs_base__range_ii_u64__struct s) const;
1983 inline bool contains(uint64_t x) const;
1984 inline bool contains_range(wuffs_base__range_ii_u64__struct s) const;
1985 #endif // __cplusplus
1986
1987 } wuffs_base__range_ii_u64;
1988
1989 static inline wuffs_base__range_ii_u64 //
wuffs_base__empty_range_ii_u64()1990 wuffs_base__empty_range_ii_u64() {
1991 wuffs_base__range_ii_u64 ret;
1992 ret.min_incl = 0;
1993 ret.max_incl = 0;
1994 return ret;
1995 }
1996
1997 static inline wuffs_base__range_ii_u64 //
wuffs_base__make_range_ii_u64(uint64_t min_incl,uint64_t max_incl)1998 wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) {
1999 wuffs_base__range_ii_u64 ret;
2000 ret.min_incl = min_incl;
2001 ret.max_incl = max_incl;
2002 return ret;
2003 }
2004
2005 static inline bool //
wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64 * r)2006 wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) {
2007 return r->min_incl > r->max_incl;
2008 }
2009
2010 static inline bool //
wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2011 wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r,
2012 wuffs_base__range_ii_u64 s) {
2013 return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) ||
2014 (wuffs_base__range_ii_u64__is_empty(r) &&
2015 wuffs_base__range_ii_u64__is_empty(&s));
2016 }
2017
2018 static inline wuffs_base__range_ii_u64 //
wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2019 wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r,
2020 wuffs_base__range_ii_u64 s) {
2021 wuffs_base__range_ii_u64 t;
2022 t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2023 t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl);
2024 return t;
2025 }
2026
2027 static inline wuffs_base__range_ii_u64 //
wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2028 wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r,
2029 wuffs_base__range_ii_u64 s) {
2030 if (wuffs_base__range_ii_u64__is_empty(r)) {
2031 return s;
2032 }
2033 if (wuffs_base__range_ii_u64__is_empty(&s)) {
2034 return *r;
2035 }
2036 wuffs_base__range_ii_u64 t;
2037 t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2038 t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl);
2039 return t;
2040 }
2041
2042 static inline bool //
wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64 * r,uint64_t x)2043 wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r,
2044 uint64_t x) {
2045 return (r->min_incl <= x) && (x <= r->max_incl);
2046 }
2047
2048 static inline bool //
wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64 * r,wuffs_base__range_ii_u64 s)2049 wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r,
2050 wuffs_base__range_ii_u64 s) {
2051 return wuffs_base__range_ii_u64__equals(
2052 &s, wuffs_base__range_ii_u64__intersect(r, s));
2053 }
2054
2055 #ifdef __cplusplus
2056
2057 inline bool //
is_empty()2058 wuffs_base__range_ii_u64::is_empty() const {
2059 return wuffs_base__range_ii_u64__is_empty(this);
2060 }
2061
2062 inline bool //
equals(wuffs_base__range_ii_u64 s)2063 wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const {
2064 return wuffs_base__range_ii_u64__equals(this, s);
2065 }
2066
2067 inline wuffs_base__range_ii_u64 //
intersect(wuffs_base__range_ii_u64 s)2068 wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const {
2069 return wuffs_base__range_ii_u64__intersect(this, s);
2070 }
2071
2072 inline wuffs_base__range_ii_u64 //
unite(wuffs_base__range_ii_u64 s)2073 wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const {
2074 return wuffs_base__range_ii_u64__unite(this, s);
2075 }
2076
2077 inline bool //
contains(uint64_t x)2078 wuffs_base__range_ii_u64::contains(uint64_t x) const {
2079 return wuffs_base__range_ii_u64__contains(this, x);
2080 }
2081
2082 inline bool //
contains_range(wuffs_base__range_ii_u64 s)2083 wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const {
2084 return wuffs_base__range_ii_u64__contains_range(this, s);
2085 }
2086
2087 #endif // __cplusplus
2088
2089 // --------
2090
2091 typedef struct wuffs_base__range_ie_u64__struct {
2092 uint64_t min_incl;
2093 uint64_t max_excl;
2094
2095 #ifdef __cplusplus
2096 inline bool is_empty() const;
2097 inline bool equals(wuffs_base__range_ie_u64__struct s) const;
2098 inline wuffs_base__range_ie_u64__struct intersect(
2099 wuffs_base__range_ie_u64__struct s) const;
2100 inline wuffs_base__range_ie_u64__struct unite(
2101 wuffs_base__range_ie_u64__struct s) const;
2102 inline bool contains(uint64_t x) const;
2103 inline bool contains_range(wuffs_base__range_ie_u64__struct s) const;
2104 inline uint64_t length() const;
2105 #endif // __cplusplus
2106
2107 } wuffs_base__range_ie_u64;
2108
2109 static inline wuffs_base__range_ie_u64 //
wuffs_base__empty_range_ie_u64()2110 wuffs_base__empty_range_ie_u64() {
2111 wuffs_base__range_ie_u64 ret;
2112 ret.min_incl = 0;
2113 ret.max_excl = 0;
2114 return ret;
2115 }
2116
2117 static inline wuffs_base__range_ie_u64 //
wuffs_base__make_range_ie_u64(uint64_t min_incl,uint64_t max_excl)2118 wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) {
2119 wuffs_base__range_ie_u64 ret;
2120 ret.min_incl = min_incl;
2121 ret.max_excl = max_excl;
2122 return ret;
2123 }
2124
2125 static inline bool //
wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64 * r)2126 wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) {
2127 return r->min_incl >= r->max_excl;
2128 }
2129
2130 static inline bool //
wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2131 wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r,
2132 wuffs_base__range_ie_u64 s) {
2133 return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) ||
2134 (wuffs_base__range_ie_u64__is_empty(r) &&
2135 wuffs_base__range_ie_u64__is_empty(&s));
2136 }
2137
2138 static inline wuffs_base__range_ie_u64 //
wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2139 wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r,
2140 wuffs_base__range_ie_u64 s) {
2141 wuffs_base__range_ie_u64 t;
2142 t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl);
2143 t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl);
2144 return t;
2145 }
2146
2147 static inline wuffs_base__range_ie_u64 //
wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2148 wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r,
2149 wuffs_base__range_ie_u64 s) {
2150 if (wuffs_base__range_ie_u64__is_empty(r)) {
2151 return s;
2152 }
2153 if (wuffs_base__range_ie_u64__is_empty(&s)) {
2154 return *r;
2155 }
2156 wuffs_base__range_ie_u64 t;
2157 t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl);
2158 t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl);
2159 return t;
2160 }
2161
2162 static inline bool //
wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64 * r,uint64_t x)2163 wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r,
2164 uint64_t x) {
2165 return (r->min_incl <= x) && (x < r->max_excl);
2166 }
2167
2168 static inline bool //
wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64 * r,wuffs_base__range_ie_u64 s)2169 wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r,
2170 wuffs_base__range_ie_u64 s) {
2171 return wuffs_base__range_ie_u64__equals(
2172 &s, wuffs_base__range_ie_u64__intersect(r, s));
2173 }
2174
2175 static inline uint64_t //
wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64 * r)2176 wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) {
2177 return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl);
2178 }
2179
2180 #ifdef __cplusplus
2181
2182 inline bool //
is_empty()2183 wuffs_base__range_ie_u64::is_empty() const {
2184 return wuffs_base__range_ie_u64__is_empty(this);
2185 }
2186
2187 inline bool //
equals(wuffs_base__range_ie_u64 s)2188 wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const {
2189 return wuffs_base__range_ie_u64__equals(this, s);
2190 }
2191
2192 inline wuffs_base__range_ie_u64 //
intersect(wuffs_base__range_ie_u64 s)2193 wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const {
2194 return wuffs_base__range_ie_u64__intersect(this, s);
2195 }
2196
2197 inline wuffs_base__range_ie_u64 //
unite(wuffs_base__range_ie_u64 s)2198 wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const {
2199 return wuffs_base__range_ie_u64__unite(this, s);
2200 }
2201
2202 inline bool //
contains(uint64_t x)2203 wuffs_base__range_ie_u64::contains(uint64_t x) const {
2204 return wuffs_base__range_ie_u64__contains(this, x);
2205 }
2206
2207 inline bool //
contains_range(wuffs_base__range_ie_u64 s)2208 wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const {
2209 return wuffs_base__range_ie_u64__contains_range(this, s);
2210 }
2211
2212 inline uint64_t //
length()2213 wuffs_base__range_ie_u64::length() const {
2214 return wuffs_base__range_ie_u64__length(this);
2215 }
2216
2217 #endif // __cplusplus
2218
2219 // --------
2220
2221 typedef struct wuffs_base__rect_ii_u32__struct {
2222 uint32_t min_incl_x;
2223 uint32_t min_incl_y;
2224 uint32_t max_incl_x;
2225 uint32_t max_incl_y;
2226
2227 #ifdef __cplusplus
2228 inline bool is_empty() const;
2229 inline bool equals(wuffs_base__rect_ii_u32__struct s) const;
2230 inline wuffs_base__rect_ii_u32__struct intersect(
2231 wuffs_base__rect_ii_u32__struct s) const;
2232 inline wuffs_base__rect_ii_u32__struct unite(
2233 wuffs_base__rect_ii_u32__struct s) const;
2234 inline bool contains(uint32_t x, uint32_t y) const;
2235 inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const;
2236 #endif // __cplusplus
2237
2238 } wuffs_base__rect_ii_u32;
2239
2240 static inline wuffs_base__rect_ii_u32 //
wuffs_base__empty_rect_ii_u32()2241 wuffs_base__empty_rect_ii_u32() {
2242 wuffs_base__rect_ii_u32 ret;
2243 ret.min_incl_x = 0;
2244 ret.min_incl_y = 0;
2245 ret.max_incl_x = 0;
2246 ret.max_incl_y = 0;
2247 return ret;
2248 }
2249
2250 static inline wuffs_base__rect_ii_u32 //
wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,uint32_t min_incl_y,uint32_t max_incl_x,uint32_t max_incl_y)2251 wuffs_base__make_rect_ii_u32(uint32_t min_incl_x,
2252 uint32_t min_incl_y,
2253 uint32_t max_incl_x,
2254 uint32_t max_incl_y) {
2255 wuffs_base__rect_ii_u32 ret;
2256 ret.min_incl_x = min_incl_x;
2257 ret.min_incl_y = min_incl_y;
2258 ret.max_incl_x = max_incl_x;
2259 ret.max_incl_y = max_incl_y;
2260 return ret;
2261 }
2262
2263 static inline bool //
wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32 * r)2264 wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) {
2265 return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y);
2266 }
2267
2268 static inline bool //
wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2269 wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r,
2270 wuffs_base__rect_ii_u32 s) {
2271 return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2272 r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) ||
2273 (wuffs_base__rect_ii_u32__is_empty(r) &&
2274 wuffs_base__rect_ii_u32__is_empty(&s));
2275 }
2276
2277 static inline wuffs_base__rect_ii_u32 //
wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2278 wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r,
2279 wuffs_base__rect_ii_u32 s) {
2280 wuffs_base__rect_ii_u32 t;
2281 t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2282 t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2283 t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x);
2284 t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y);
2285 return t;
2286 }
2287
2288 static inline wuffs_base__rect_ii_u32 //
wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2289 wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r,
2290 wuffs_base__rect_ii_u32 s) {
2291 if (wuffs_base__rect_ii_u32__is_empty(r)) {
2292 return s;
2293 }
2294 if (wuffs_base__rect_ii_u32__is_empty(&s)) {
2295 return *r;
2296 }
2297 wuffs_base__rect_ii_u32 t;
2298 t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2299 t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2300 t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x);
2301 t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y);
2302 return t;
2303 }
2304
2305 static inline bool //
wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32 * r,uint32_t x,uint32_t y)2306 wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r,
2307 uint32_t x,
2308 uint32_t y) {
2309 return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) &&
2310 (y <= r->max_incl_y);
2311 }
2312
2313 static inline bool //
wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32 * r,wuffs_base__rect_ii_u32 s)2314 wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r,
2315 wuffs_base__rect_ii_u32 s) {
2316 return wuffs_base__rect_ii_u32__equals(
2317 &s, wuffs_base__rect_ii_u32__intersect(r, s));
2318 }
2319
2320 #ifdef __cplusplus
2321
2322 inline bool //
is_empty()2323 wuffs_base__rect_ii_u32::is_empty() const {
2324 return wuffs_base__rect_ii_u32__is_empty(this);
2325 }
2326
2327 inline bool //
equals(wuffs_base__rect_ii_u32 s)2328 wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const {
2329 return wuffs_base__rect_ii_u32__equals(this, s);
2330 }
2331
2332 inline wuffs_base__rect_ii_u32 //
intersect(wuffs_base__rect_ii_u32 s)2333 wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const {
2334 return wuffs_base__rect_ii_u32__intersect(this, s);
2335 }
2336
2337 inline wuffs_base__rect_ii_u32 //
unite(wuffs_base__rect_ii_u32 s)2338 wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const {
2339 return wuffs_base__rect_ii_u32__unite(this, s);
2340 }
2341
2342 inline bool //
contains(uint32_t x,uint32_t y)2343 wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const {
2344 return wuffs_base__rect_ii_u32__contains(this, x, y);
2345 }
2346
2347 inline bool //
contains_rect(wuffs_base__rect_ii_u32 s)2348 wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const {
2349 return wuffs_base__rect_ii_u32__contains_rect(this, s);
2350 }
2351
2352 #endif // __cplusplus
2353
2354 // --------
2355
2356 typedef struct wuffs_base__rect_ie_u32__struct {
2357 uint32_t min_incl_x;
2358 uint32_t min_incl_y;
2359 uint32_t max_excl_x;
2360 uint32_t max_excl_y;
2361
2362 #ifdef __cplusplus
2363 inline bool is_empty() const;
2364 inline bool equals(wuffs_base__rect_ie_u32__struct s) const;
2365 inline wuffs_base__rect_ie_u32__struct intersect(
2366 wuffs_base__rect_ie_u32__struct s) const;
2367 inline wuffs_base__rect_ie_u32__struct unite(
2368 wuffs_base__rect_ie_u32__struct s) const;
2369 inline bool contains(uint32_t x, uint32_t y) const;
2370 inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const;
2371 inline uint32_t width() const;
2372 inline uint32_t height() const;
2373 #endif // __cplusplus
2374
2375 } wuffs_base__rect_ie_u32;
2376
2377 static inline wuffs_base__rect_ie_u32 //
wuffs_base__empty_rect_ie_u32()2378 wuffs_base__empty_rect_ie_u32() {
2379 wuffs_base__rect_ie_u32 ret;
2380 ret.min_incl_x = 0;
2381 ret.min_incl_y = 0;
2382 ret.max_excl_x = 0;
2383 ret.max_excl_y = 0;
2384 return ret;
2385 }
2386
2387 static inline wuffs_base__rect_ie_u32 //
wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,uint32_t min_incl_y,uint32_t max_excl_x,uint32_t max_excl_y)2388 wuffs_base__make_rect_ie_u32(uint32_t min_incl_x,
2389 uint32_t min_incl_y,
2390 uint32_t max_excl_x,
2391 uint32_t max_excl_y) {
2392 wuffs_base__rect_ie_u32 ret;
2393 ret.min_incl_x = min_incl_x;
2394 ret.min_incl_y = min_incl_y;
2395 ret.max_excl_x = max_excl_x;
2396 ret.max_excl_y = max_excl_y;
2397 return ret;
2398 }
2399
2400 static inline bool //
wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32 * r)2401 wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) {
2402 return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y);
2403 }
2404
2405 static inline bool //
wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2406 wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r,
2407 wuffs_base__rect_ie_u32 s) {
2408 return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y &&
2409 r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) ||
2410 (wuffs_base__rect_ie_u32__is_empty(r) &&
2411 wuffs_base__rect_ie_u32__is_empty(&s));
2412 }
2413
2414 static inline wuffs_base__rect_ie_u32 //
wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2415 wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r,
2416 wuffs_base__rect_ie_u32 s) {
2417 wuffs_base__rect_ie_u32 t;
2418 t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x);
2419 t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y);
2420 t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x);
2421 t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y);
2422 return t;
2423 }
2424
2425 static inline wuffs_base__rect_ie_u32 //
wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2426 wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r,
2427 wuffs_base__rect_ie_u32 s) {
2428 if (wuffs_base__rect_ie_u32__is_empty(r)) {
2429 return s;
2430 }
2431 if (wuffs_base__rect_ie_u32__is_empty(&s)) {
2432 return *r;
2433 }
2434 wuffs_base__rect_ie_u32 t;
2435 t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x);
2436 t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y);
2437 t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x);
2438 t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y);
2439 return t;
2440 }
2441
2442 static inline bool //
wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32 * r,uint32_t x,uint32_t y)2443 wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r,
2444 uint32_t x,
2445 uint32_t y) {
2446 return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) &&
2447 (y < r->max_excl_y);
2448 }
2449
2450 static inline bool //
wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32 * r,wuffs_base__rect_ie_u32 s)2451 wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r,
2452 wuffs_base__rect_ie_u32 s) {
2453 return wuffs_base__rect_ie_u32__equals(
2454 &s, wuffs_base__rect_ie_u32__intersect(r, s));
2455 }
2456
2457 static inline uint32_t //
wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32 * r)2458 wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) {
2459 return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x);
2460 }
2461
2462 static inline uint32_t //
wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32 * r)2463 wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) {
2464 return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y);
2465 }
2466
2467 #ifdef __cplusplus
2468
2469 inline bool //
is_empty()2470 wuffs_base__rect_ie_u32::is_empty() const {
2471 return wuffs_base__rect_ie_u32__is_empty(this);
2472 }
2473
2474 inline bool //
equals(wuffs_base__rect_ie_u32 s)2475 wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const {
2476 return wuffs_base__rect_ie_u32__equals(this, s);
2477 }
2478
2479 inline wuffs_base__rect_ie_u32 //
intersect(wuffs_base__rect_ie_u32 s)2480 wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const {
2481 return wuffs_base__rect_ie_u32__intersect(this, s);
2482 }
2483
2484 inline wuffs_base__rect_ie_u32 //
unite(wuffs_base__rect_ie_u32 s)2485 wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const {
2486 return wuffs_base__rect_ie_u32__unite(this, s);
2487 }
2488
2489 inline bool //
contains(uint32_t x,uint32_t y)2490 wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const {
2491 return wuffs_base__rect_ie_u32__contains(this, x, y);
2492 }
2493
2494 inline bool //
contains_rect(wuffs_base__rect_ie_u32 s)2495 wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const {
2496 return wuffs_base__rect_ie_u32__contains_rect(this, s);
2497 }
2498
2499 inline uint32_t //
width()2500 wuffs_base__rect_ie_u32::width() const {
2501 return wuffs_base__rect_ie_u32__width(this);
2502 }
2503
2504 inline uint32_t //
height()2505 wuffs_base__rect_ie_u32::height() const {
2506 return wuffs_base__rect_ie_u32__height(this);
2507 }
2508
2509 #endif // __cplusplus
2510
2511 // ---------------- More Information
2512
2513 // wuffs_base__more_information holds additional fields, typically when a Wuffs
2514 // method returns a [note status](/doc/note/statuses.md).
2515 //
2516 // The flavor field follows the base38 namespace
2517 // convention](/doc/note/base38-and-fourcc.md). The other fields' semantics
2518 // depends on the flavor.
2519 typedef struct wuffs_base__more_information__struct {
2520 uint32_t flavor;
2521 uint32_t w;
2522 uint64_t x;
2523 uint64_t y;
2524 uint64_t z;
2525
2526 #ifdef __cplusplus
2527 inline void set(uint32_t flavor_arg,
2528 uint32_t w_arg,
2529 uint64_t x_arg,
2530 uint64_t y_arg,
2531 uint64_t z_arg);
2532 inline uint32_t io_redirect__fourcc() const;
2533 inline wuffs_base__range_ie_u64 io_redirect__range() const;
2534 inline uint64_t io_seek__position() const;
2535 inline uint32_t metadata__fourcc() const;
2536 // Deprecated: use metadata_raw_passthrough__range.
2537 inline wuffs_base__range_ie_u64 metadata__range() const;
2538 inline wuffs_base__range_ie_u64 metadata_raw_passthrough__range() const;
2539 inline int32_t metadata_parsed__chrm(uint32_t component) const;
2540 inline uint32_t metadata_parsed__gama() const;
2541 inline uint32_t metadata_parsed__srgb() const;
2542 #endif // __cplusplus
2543
2544 } wuffs_base__more_information;
2545
2546 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT 1
2547 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK 2
2548 // Deprecated: use
2549 // WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH.
2550 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA 3
2551 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH 3
2552 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM 4
2553 #define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED 5
2554
2555 static inline wuffs_base__more_information //
wuffs_base__empty_more_information()2556 wuffs_base__empty_more_information() {
2557 wuffs_base__more_information ret;
2558 ret.flavor = 0;
2559 ret.w = 0;
2560 ret.x = 0;
2561 ret.y = 0;
2562 ret.z = 0;
2563 return ret;
2564 }
2565
2566 static inline void //
wuffs_base__more_information__set(wuffs_base__more_information * m,uint32_t flavor,uint32_t w,uint64_t x,uint64_t y,uint64_t z)2567 wuffs_base__more_information__set(wuffs_base__more_information* m,
2568 uint32_t flavor,
2569 uint32_t w,
2570 uint64_t x,
2571 uint64_t y,
2572 uint64_t z) {
2573 if (!m) {
2574 return;
2575 }
2576 m->flavor = flavor;
2577 m->w = w;
2578 m->x = x;
2579 m->y = y;
2580 m->z = z;
2581 }
2582
2583 static inline uint32_t //
wuffs_base__more_information__io_redirect__fourcc(const wuffs_base__more_information * m)2584 wuffs_base__more_information__io_redirect__fourcc(
2585 const wuffs_base__more_information* m) {
2586 return m->w;
2587 }
2588
2589 static inline wuffs_base__range_ie_u64 //
wuffs_base__more_information__io_redirect__range(const wuffs_base__more_information * m)2590 wuffs_base__more_information__io_redirect__range(
2591 const wuffs_base__more_information* m) {
2592 wuffs_base__range_ie_u64 ret;
2593 ret.min_incl = m->y;
2594 ret.max_excl = m->z;
2595 return ret;
2596 }
2597
2598 static inline uint64_t //
wuffs_base__more_information__io_seek__position(const wuffs_base__more_information * m)2599 wuffs_base__more_information__io_seek__position(
2600 const wuffs_base__more_information* m) {
2601 return m->x;
2602 }
2603
2604 static inline uint32_t //
wuffs_base__more_information__metadata__fourcc(const wuffs_base__more_information * m)2605 wuffs_base__more_information__metadata__fourcc(
2606 const wuffs_base__more_information* m) {
2607 return m->w;
2608 }
2609
2610 // Deprecated: use
2611 // wuffs_base__more_information__metadata_raw_passthrough__range.
2612 static inline wuffs_base__range_ie_u64 //
wuffs_base__more_information__metadata__range(const wuffs_base__more_information * m)2613 wuffs_base__more_information__metadata__range(
2614 const wuffs_base__more_information* m) {
2615 wuffs_base__range_ie_u64 ret;
2616 ret.min_incl = m->y;
2617 ret.max_excl = m->z;
2618 return ret;
2619 }
2620
2621 static inline wuffs_base__range_ie_u64 //
wuffs_base__more_information__metadata_raw_passthrough__range(const wuffs_base__more_information * m)2622 wuffs_base__more_information__metadata_raw_passthrough__range(
2623 const wuffs_base__more_information* m) {
2624 wuffs_base__range_ie_u64 ret;
2625 ret.min_incl = m->y;
2626 ret.max_excl = m->z;
2627 return ret;
2628 }
2629
2630 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_X 0
2631 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_Y 1
2632 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_X 2
2633 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_Y 3
2634 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_X 4
2635 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_Y 5
2636 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_X 6
2637 #define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_Y 7
2638
2639 // wuffs_base__more_information__metadata_parsed__chrm returns chromaticity
2640 // values (scaled by 100000) like the PNG "cHRM" chunk. For example, the sRGB
2641 // color space corresponds to:
2642 // - ETC__CHRM__WHITE_X 31270
2643 // - ETC__CHRM__WHITE_Y 32900
2644 // - ETC__CHRM__RED_X 64000
2645 // - ETC__CHRM__RED_Y 33000
2646 // - ETC__CHRM__GREEN_X 30000
2647 // - ETC__CHRM__GREEN_Y 60000
2648 // - ETC__CHRM__BLUE_X 15000
2649 // - ETC__CHRM__BLUE_Y 6000
2650 //
2651 // See
2652 // https://ciechanow.ski/color-spaces/#chromaticity-and-white-point-coordinates
2653 static inline int32_t //
wuffs_base__more_information__metadata_parsed__chrm(const wuffs_base__more_information * m,uint32_t component)2654 wuffs_base__more_information__metadata_parsed__chrm(
2655 const wuffs_base__more_information* m,
2656 uint32_t component) {
2657 // After the flavor and the w field (holding a FourCC), a
2658 // wuffs_base__more_information holds 24 bytes of data in three uint64_t
2659 // typed fields (x, y and z). We pack the eight chromaticity values (wx, wy,
2660 // rx, ..., by), basically int24_t values, into 24 bytes like this:
2661 // - LSB MSB
2662 // - x: wx wx wx wy wy wy rx rx
2663 // - y: rx ry ry ry gx gx gx gy
2664 // - z: gy gy bx bx bx by by by
2665 uint32_t u = 0;
2666 switch (component & 7) {
2667 case 0:
2668 u = ((uint32_t)(m->x >> 0));
2669 break;
2670 case 1:
2671 u = ((uint32_t)(m->x >> 24));
2672 break;
2673 case 2:
2674 u = ((uint32_t)((m->x >> 48) | (m->y << 16)));
2675 break;
2676 case 3:
2677 u = ((uint32_t)(m->y >> 8));
2678 break;
2679 case 4:
2680 u = ((uint32_t)(m->y >> 32));
2681 break;
2682 case 5:
2683 u = ((uint32_t)((m->y >> 56) | (m->z << 8)));
2684 break;
2685 case 6:
2686 u = ((uint32_t)(m->z >> 16));
2687 break;
2688 case 7:
2689 u = ((uint32_t)(m->z >> 40));
2690 break;
2691 }
2692 // The left-right shifts sign-extend from 24-bit to 32-bit integers.
2693 return ((int32_t)(u << 8)) >> 8;
2694 }
2695
2696 // wuffs_base__more_information__metadata_parsed__gama returns inverse gamma
2697 // correction values (scaled by 100000) like the PNG "gAMA" chunk. For example,
2698 // for gamma = 2.2, this returns 45455 (approximating 100000 / 2.2).
2699 static inline uint32_t //
wuffs_base__more_information__metadata_parsed__gama(const wuffs_base__more_information * m)2700 wuffs_base__more_information__metadata_parsed__gama(
2701 const wuffs_base__more_information* m) {
2702 return ((uint32_t)(m->x));
2703 }
2704
2705 #define WUFFS_BASE__SRGB_RENDERING_INTENT__PERCEPTUAL 0
2706 #define WUFFS_BASE__SRGB_RENDERING_INTENT__RELATIVE_COLORIMETRIC 1
2707 #define WUFFS_BASE__SRGB_RENDERING_INTENT__SATURATION 2
2708 #define WUFFS_BASE__SRGB_RENDERING_INTENT__ABSOLUTE_COLORIMETRIC 3
2709
2710 // wuffs_base__more_information__metadata_parsed__srgb returns the sRGB
2711 // rendering intent like the PNG "sRGB" chunk.
2712 static inline uint32_t //
wuffs_base__more_information__metadata_parsed__srgb(const wuffs_base__more_information * m)2713 wuffs_base__more_information__metadata_parsed__srgb(
2714 const wuffs_base__more_information* m) {
2715 return m->x & 3;
2716 }
2717
2718 #ifdef __cplusplus
2719
2720 inline void //
set(uint32_t flavor_arg,uint32_t w_arg,uint64_t x_arg,uint64_t y_arg,uint64_t z_arg)2721 wuffs_base__more_information::set(uint32_t flavor_arg,
2722 uint32_t w_arg,
2723 uint64_t x_arg,
2724 uint64_t y_arg,
2725 uint64_t z_arg) {
2726 wuffs_base__more_information__set(this, flavor_arg, w_arg, x_arg, y_arg,
2727 z_arg);
2728 }
2729
2730 inline uint32_t //
io_redirect__fourcc()2731 wuffs_base__more_information::io_redirect__fourcc() const {
2732 return wuffs_base__more_information__io_redirect__fourcc(this);
2733 }
2734
2735 inline wuffs_base__range_ie_u64 //
io_redirect__range()2736 wuffs_base__more_information::io_redirect__range() const {
2737 return wuffs_base__more_information__io_redirect__range(this);
2738 }
2739
2740 inline uint64_t //
io_seek__position()2741 wuffs_base__more_information::io_seek__position() const {
2742 return wuffs_base__more_information__io_seek__position(this);
2743 }
2744
2745 inline uint32_t //
metadata__fourcc()2746 wuffs_base__more_information::metadata__fourcc() const {
2747 return wuffs_base__more_information__metadata__fourcc(this);
2748 }
2749
2750 inline wuffs_base__range_ie_u64 //
metadata__range()2751 wuffs_base__more_information::metadata__range() const {
2752 return wuffs_base__more_information__metadata__range(this);
2753 }
2754
2755 inline wuffs_base__range_ie_u64 //
metadata_raw_passthrough__range()2756 wuffs_base__more_information::metadata_raw_passthrough__range() const {
2757 return wuffs_base__more_information__metadata_raw_passthrough__range(this);
2758 }
2759
2760 inline int32_t //
metadata_parsed__chrm(uint32_t component)2761 wuffs_base__more_information::metadata_parsed__chrm(uint32_t component) const {
2762 return wuffs_base__more_information__metadata_parsed__chrm(this, component);
2763 }
2764
2765 inline uint32_t //
metadata_parsed__gama()2766 wuffs_base__more_information::metadata_parsed__gama() const {
2767 return wuffs_base__more_information__metadata_parsed__gama(this);
2768 }
2769
2770 inline uint32_t //
metadata_parsed__srgb()2771 wuffs_base__more_information::metadata_parsed__srgb() const {
2772 return wuffs_base__more_information__metadata_parsed__srgb(this);
2773 }
2774
2775 #endif // __cplusplus
2776
2777 // ---------------- I/O
2778 //
2779 // See (/doc/note/io-input-output.md).
2780
2781 // wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's
2782 // data.
2783 typedef struct wuffs_base__io_buffer_meta__struct {
2784 size_t wi; // Write index. Invariant: wi <= len.
2785 size_t ri; // Read index. Invariant: ri <= wi.
2786 uint64_t pos; // Buffer position (relative to the start of stream).
2787 bool closed; // No further writes are expected.
2788 } wuffs_base__io_buffer_meta;
2789
2790 // wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus
2791 // additional metadata.
2792 //
2793 // A value with all fields zero is a valid, empty buffer.
2794 typedef struct wuffs_base__io_buffer__struct {
2795 wuffs_base__slice_u8 data;
2796 wuffs_base__io_buffer_meta meta;
2797
2798 #ifdef __cplusplus
2799 inline bool is_valid() const;
2800 inline void compact();
2801 inline size_t reader_length() const;
2802 inline uint8_t* reader_pointer() const;
2803 inline uint64_t reader_position() const;
2804 inline wuffs_base__slice_u8 reader_slice() const;
2805 inline size_t writer_length() const;
2806 inline uint8_t* writer_pointer() const;
2807 inline uint64_t writer_position() const;
2808 inline wuffs_base__slice_u8 writer_slice() const;
2809
2810 // Deprecated: use reader_position.
2811 inline uint64_t reader_io_position() const;
2812 // Deprecated: use writer_position.
2813 inline uint64_t writer_io_position() const;
2814 #endif // __cplusplus
2815
2816 } wuffs_base__io_buffer;
2817
2818 static inline wuffs_base__io_buffer //
wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,wuffs_base__io_buffer_meta meta)2819 wuffs_base__make_io_buffer(wuffs_base__slice_u8 data,
2820 wuffs_base__io_buffer_meta meta) {
2821 wuffs_base__io_buffer ret;
2822 ret.data = data;
2823 ret.meta = meta;
2824 return ret;
2825 }
2826
2827 static inline wuffs_base__io_buffer_meta //
wuffs_base__make_io_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)2828 wuffs_base__make_io_buffer_meta(size_t wi,
2829 size_t ri,
2830 uint64_t pos,
2831 bool closed) {
2832 wuffs_base__io_buffer_meta ret;
2833 ret.wi = wi;
2834 ret.ri = ri;
2835 ret.pos = pos;
2836 ret.closed = closed;
2837 return ret;
2838 }
2839
2840 static inline wuffs_base__io_buffer //
wuffs_base__ptr_u8__reader(uint8_t * ptr,size_t len,bool closed)2841 wuffs_base__ptr_u8__reader(uint8_t* ptr, size_t len, bool closed) {
2842 wuffs_base__io_buffer ret;
2843 ret.data.ptr = ptr;
2844 ret.data.len = len;
2845 ret.meta.wi = len;
2846 ret.meta.ri = 0;
2847 ret.meta.pos = 0;
2848 ret.meta.closed = closed;
2849 return ret;
2850 }
2851
2852 static inline wuffs_base__io_buffer //
wuffs_base__ptr_u8__writer(uint8_t * ptr,size_t len)2853 wuffs_base__ptr_u8__writer(uint8_t* ptr, size_t len) {
2854 wuffs_base__io_buffer ret;
2855 ret.data.ptr = ptr;
2856 ret.data.len = len;
2857 ret.meta.wi = 0;
2858 ret.meta.ri = 0;
2859 ret.meta.pos = 0;
2860 ret.meta.closed = false;
2861 return ret;
2862 }
2863
2864 static inline wuffs_base__io_buffer //
wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s,bool closed)2865 wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s, bool closed) {
2866 wuffs_base__io_buffer ret;
2867 ret.data.ptr = s.ptr;
2868 ret.data.len = s.len;
2869 ret.meta.wi = s.len;
2870 ret.meta.ri = 0;
2871 ret.meta.pos = 0;
2872 ret.meta.closed = closed;
2873 return ret;
2874 }
2875
2876 static inline wuffs_base__io_buffer //
wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s)2877 wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s) {
2878 wuffs_base__io_buffer ret;
2879 ret.data.ptr = s.ptr;
2880 ret.data.len = s.len;
2881 ret.meta.wi = 0;
2882 ret.meta.ri = 0;
2883 ret.meta.pos = 0;
2884 ret.meta.closed = false;
2885 return ret;
2886 }
2887
2888 static inline wuffs_base__io_buffer //
wuffs_base__empty_io_buffer()2889 wuffs_base__empty_io_buffer() {
2890 wuffs_base__io_buffer ret;
2891 ret.data.ptr = NULL;
2892 ret.data.len = 0;
2893 ret.meta.wi = 0;
2894 ret.meta.ri = 0;
2895 ret.meta.pos = 0;
2896 ret.meta.closed = false;
2897 return ret;
2898 }
2899
2900 static inline wuffs_base__io_buffer_meta //
wuffs_base__empty_io_buffer_meta()2901 wuffs_base__empty_io_buffer_meta() {
2902 wuffs_base__io_buffer_meta ret;
2903 ret.wi = 0;
2904 ret.ri = 0;
2905 ret.pos = 0;
2906 ret.closed = false;
2907 return ret;
2908 }
2909
2910 static inline bool //
wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer * buf)2911 wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer* buf) {
2912 if (buf) {
2913 if (buf->data.ptr) {
2914 return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
2915 } else {
2916 return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
2917 }
2918 }
2919 return false;
2920 }
2921
2922 // wuffs_base__io_buffer__compact moves any written but unread bytes to the
2923 // start of the buffer.
2924 static inline void //
wuffs_base__io_buffer__compact(wuffs_base__io_buffer * buf)2925 wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) {
2926 if (!buf || (buf->meta.ri == 0)) {
2927 return;
2928 }
2929 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
2930 size_t n = buf->meta.wi - buf->meta.ri;
2931 if (n != 0) {
2932 memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, n);
2933 }
2934 buf->meta.wi = n;
2935 buf->meta.ri = 0;
2936 }
2937
2938 // Deprecated. Use wuffs_base__io_buffer__reader_position.
2939 static inline uint64_t //
wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer * buf)2940 wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer* buf) {
2941 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
2942 }
2943
2944 static inline size_t //
wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer * buf)2945 wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer* buf) {
2946 return buf ? buf->meta.wi - buf->meta.ri : 0;
2947 }
2948
2949 static inline uint8_t* //
wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer * buf)2950 wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer* buf) {
2951 return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
2952 }
2953
2954 static inline uint64_t //
wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer * buf)2955 wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer* buf) {
2956 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
2957 }
2958
2959 static inline wuffs_base__slice_u8 //
wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer * buf)2960 wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer* buf) {
2961 return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri,
2962 buf->meta.wi - buf->meta.ri)
2963 : wuffs_base__empty_slice_u8();
2964 }
2965
2966 // Deprecated. Use wuffs_base__io_buffer__writer_position.
2967 static inline uint64_t //
wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer * buf)2968 wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer* buf) {
2969 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
2970 }
2971
2972 static inline size_t //
wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer * buf)2973 wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer* buf) {
2974 return buf ? buf->data.len - buf->meta.wi : 0;
2975 }
2976
2977 static inline uint8_t* //
wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer * buf)2978 wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer* buf) {
2979 return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
2980 }
2981
2982 static inline uint64_t //
wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer * buf)2983 wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer* buf) {
2984 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
2985 }
2986
2987 static inline wuffs_base__slice_u8 //
wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer * buf)2988 wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer* buf) {
2989 return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi,
2990 buf->data.len - buf->meta.wi)
2991 : wuffs_base__empty_slice_u8();
2992 }
2993
2994 #ifdef __cplusplus
2995
2996 inline bool //
is_valid()2997 wuffs_base__io_buffer::is_valid() const {
2998 return wuffs_base__io_buffer__is_valid(this);
2999 }
3000
3001 inline void //
compact()3002 wuffs_base__io_buffer::compact() {
3003 wuffs_base__io_buffer__compact(this);
3004 }
3005
3006 inline uint64_t //
reader_io_position()3007 wuffs_base__io_buffer::reader_io_position() const {
3008 return wuffs_base__io_buffer__reader_io_position(this);
3009 }
3010
3011 inline size_t //
reader_length()3012 wuffs_base__io_buffer::reader_length() const {
3013 return wuffs_base__io_buffer__reader_length(this);
3014 }
3015
3016 inline uint8_t* //
reader_pointer()3017 wuffs_base__io_buffer::reader_pointer() const {
3018 return wuffs_base__io_buffer__reader_pointer(this);
3019 }
3020
3021 inline uint64_t //
reader_position()3022 wuffs_base__io_buffer::reader_position() const {
3023 return wuffs_base__io_buffer__reader_position(this);
3024 }
3025
3026 inline wuffs_base__slice_u8 //
reader_slice()3027 wuffs_base__io_buffer::reader_slice() const {
3028 return wuffs_base__io_buffer__reader_slice(this);
3029 }
3030
3031 inline uint64_t //
writer_io_position()3032 wuffs_base__io_buffer::writer_io_position() const {
3033 return wuffs_base__io_buffer__writer_io_position(this);
3034 }
3035
3036 inline size_t //
writer_length()3037 wuffs_base__io_buffer::writer_length() const {
3038 return wuffs_base__io_buffer__writer_length(this);
3039 }
3040
3041 inline uint8_t* //
writer_pointer()3042 wuffs_base__io_buffer::writer_pointer() const {
3043 return wuffs_base__io_buffer__writer_pointer(this);
3044 }
3045
3046 inline uint64_t //
writer_position()3047 wuffs_base__io_buffer::writer_position() const {
3048 return wuffs_base__io_buffer__writer_position(this);
3049 }
3050
3051 inline wuffs_base__slice_u8 //
writer_slice()3052 wuffs_base__io_buffer::writer_slice() const {
3053 return wuffs_base__io_buffer__writer_slice(this);
3054 }
3055
3056 #endif // __cplusplus
3057
3058 // ---------------- Tokens
3059
3060 // wuffs_base__token is an element of a byte stream's tokenization.
3061 //
3062 // See https://github.com/google/wuffs/blob/main/doc/note/tokens.md
3063 typedef struct wuffs_base__token__struct {
3064 uint64_t repr;
3065
3066 #ifdef __cplusplus
3067 inline int64_t value() const;
3068 inline int64_t value_extension() const;
3069 inline int64_t value_major() const;
3070 inline int64_t value_base_category() const;
3071 inline uint64_t value_minor() const;
3072 inline uint64_t value_base_detail() const;
3073 inline int64_t value_base_detail__sign_extended() const;
3074 inline bool continued() const;
3075 inline uint64_t length() const;
3076 #endif // __cplusplus
3077
3078 } wuffs_base__token;
3079
3080 static inline wuffs_base__token //
wuffs_base__make_token(uint64_t repr)3081 wuffs_base__make_token(uint64_t repr) {
3082 wuffs_base__token ret;
3083 ret.repr = repr;
3084 return ret;
3085 }
3086
3087 // --------
3088
3089 #define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF
3090
3091 #define WUFFS_BASE__TOKEN__VALUE__SHIFT 17
3092 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17
3093 #define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42
3094 #define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17
3095 #define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38
3096 #define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17
3097 #define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16
3098 #define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0
3099
3100 #define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46
3101
3102 // --------
3103
3104 #define WUFFS_BASE__TOKEN__VBC__FILLER 0
3105 #define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1
3106 #define WUFFS_BASE__TOKEN__VBC__STRING 2
3107 #define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3
3108 #define WUFFS_BASE__TOKEN__VBC__LITERAL 4
3109 #define WUFFS_BASE__TOKEN__VBC__NUMBER 5
3110 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6
3111 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED 7
3112
3113 // --------
3114
3115 #define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001
3116 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002
3117 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004
3118
3119 // COMMENT_ANY is a bit-wise or of COMMENT_BLOCK AND COMMENT_LINE.
3120 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006
3121
3122 // --------
3123
3124 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001
3125 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002
3126 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010
3127 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020
3128 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040
3129 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000
3130 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000
3131 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000
3132
3133 // --------
3134
3135 // DEFINITELY_FOO means that the destination bytes (and also the source bytes,
3136 // for 1_DST_1_SRC_COPY) are in the FOO format. Definitely means that the lack
3137 // of the bit means "maybe FOO". It does not necessarily mean "not FOO".
3138 //
3139 // CHAIN_ETC means that decoding the entire token chain forms a UTF-8 or ASCII
3140 // string, not just this current token. CHAIN_ETC_UTF_8 therefore distinguishes
3141 // Unicode (UTF-8) strings from byte strings. MUST means that the the token
3142 // producer (e.g. parser) must verify this. SHOULD means that the token
3143 // consumer (e.g. renderer) should verify this.
3144 //
3145 // When a CHAIN_ETC_UTF_8 bit is set, the parser must ensure that non-ASCII
3146 // code points (with multi-byte UTF-8 encodings) do not straddle token
3147 // boundaries. Checking UTF-8 validity can inspect each token separately.
3148 //
3149 // The lack of any particular bit is conservative: it is valid for all-ASCII
3150 // strings, in a single- or multi-token chain, to have none of these bits set.
3151 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001
3152 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002
3153 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_UTF_8 0x00004
3154 #define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010
3155 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020
3156 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_ASCII 0x00040
3157
3158 // CONVERT_D_DST_S_SRC means that multiples of S source bytes (possibly padded)
3159 // produces multiples of D destination bytes. For example,
3160 // CONVERT_1_DST_4_SRC_BACKSLASH_X means a source like "\\x23\\x67\\xAB", where
3161 // 12 src bytes encode 3 dst bytes.
3162 //
3163 // Post-processing may further transform those D destination bytes (e.g. treat
3164 // "\\xFF" as the Unicode code point U+00FF instead of the byte 0xFF), but that
3165 // is out of scope of this VBD's semantics.
3166 //
3167 // When src is the empty string, multiple conversion algorithms are applicable
3168 // (so these bits are not necessarily mutually exclusive), all producing the
3169 // same empty dst string.
3170 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100
3171 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200
3172 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00400
3173 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00800
3174 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x01000
3175 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x02000
3176 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000
3177 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_HEX 0x08000
3178 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_STD 0x10000
3179
3180 // --------
3181
3182 #define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001
3183 #define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002
3184 #define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004
3185 #define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008
3186
3187 // --------
3188
3189 // For a source string of "123" or "0x9A", it is valid for a tokenizer to
3190 // return any combination of:
3191 // - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT.
3192 // - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED.
3193 // - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED.
3194 //
3195 // For a source string of "+123" or "-0x9A", only the first two are valid.
3196 //
3197 // For a source string of "123.", only the first one is valid.
3198 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001
3199 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002
3200 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004
3201
3202 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010
3203 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF 0x00020
3204 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN 0x00040
3205 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN 0x00080
3206
3207 // The number 300 might be represented as "\x01\x2C", "\x2C\x01\x00\x00" or
3208 // "300", which are big-endian, little-endian or text. For binary formats, the
3209 // token length (after adjusting for FORMAT_IGNORE_ETC) discriminates
3210 // e.g. u16 little-endian vs u32 little-endian.
3211 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100
3212 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200
3213 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400
3214
3215 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000
3216
3217 // --------
3218
3219 // wuffs_base__token__value returns the token's high 46 bits, sign-extended. A
3220 // negative value means an extended token, non-negative means a simple token.
3221 static inline int64_t //
wuffs_base__token__value(const wuffs_base__token * t)3222 wuffs_base__token__value(const wuffs_base__token* t) {
3223 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE__SHIFT;
3224 }
3225
3226 // wuffs_base__token__value_extension returns a negative value if the token was
3227 // not an extended token.
3228 static inline int64_t //
wuffs_base__token__value_extension(const wuffs_base__token * t)3229 wuffs_base__token__value_extension(const wuffs_base__token* t) {
3230 return (~(int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT;
3231 }
3232
3233 // wuffs_base__token__value_major returns a negative value if the token was not
3234 // a simple token.
3235 static inline int64_t //
wuffs_base__token__value_major(const wuffs_base__token * t)3236 wuffs_base__token__value_major(const wuffs_base__token* t) {
3237 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT;
3238 }
3239
3240 // wuffs_base__token__value_base_category returns a negative value if the token
3241 // was not a simple token.
3242 static inline int64_t //
wuffs_base__token__value_base_category(const wuffs_base__token * t)3243 wuffs_base__token__value_base_category(const wuffs_base__token* t) {
3244 return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT;
3245 }
3246
3247 static inline uint64_t //
wuffs_base__token__value_minor(const wuffs_base__token * t)3248 wuffs_base__token__value_minor(const wuffs_base__token* t) {
3249 return (t->repr >> WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) & 0x1FFFFFF;
3250 }
3251
3252 static inline uint64_t //
wuffs_base__token__value_base_detail(const wuffs_base__token * t)3253 wuffs_base__token__value_base_detail(const wuffs_base__token* t) {
3254 return (t->repr >> WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) & 0x1FFFFF;
3255 }
3256
3257 static inline int64_t //
wuffs_base__token__value_base_detail__sign_extended(const wuffs_base__token * t)3258 wuffs_base__token__value_base_detail__sign_extended(
3259 const wuffs_base__token* t) {
3260 // The VBD is 21 bits in the middle of t->repr. Left shift the high (64 - 21
3261 // - ETC__SHIFT) bits off, then right shift (sign-extending) back down.
3262 uint64_t u = t->repr << (43 - WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT);
3263 return ((int64_t)u) >> 43;
3264 }
3265
3266 static inline bool //
wuffs_base__token__continued(const wuffs_base__token * t)3267 wuffs_base__token__continued(const wuffs_base__token* t) {
3268 return t->repr & 0x10000;
3269 }
3270
3271 static inline uint64_t //
wuffs_base__token__length(const wuffs_base__token * t)3272 wuffs_base__token__length(const wuffs_base__token* t) {
3273 return (t->repr >> WUFFS_BASE__TOKEN__LENGTH__SHIFT) & 0xFFFF;
3274 }
3275
3276 #ifdef __cplusplus
3277
3278 inline int64_t //
value()3279 wuffs_base__token::value() const {
3280 return wuffs_base__token__value(this);
3281 }
3282
3283 inline int64_t //
value_extension()3284 wuffs_base__token::value_extension() const {
3285 return wuffs_base__token__value_extension(this);
3286 }
3287
3288 inline int64_t //
value_major()3289 wuffs_base__token::value_major() const {
3290 return wuffs_base__token__value_major(this);
3291 }
3292
3293 inline int64_t //
value_base_category()3294 wuffs_base__token::value_base_category() const {
3295 return wuffs_base__token__value_base_category(this);
3296 }
3297
3298 inline uint64_t //
value_minor()3299 wuffs_base__token::value_minor() const {
3300 return wuffs_base__token__value_minor(this);
3301 }
3302
3303 inline uint64_t //
value_base_detail()3304 wuffs_base__token::value_base_detail() const {
3305 return wuffs_base__token__value_base_detail(this);
3306 }
3307
3308 inline int64_t //
value_base_detail__sign_extended()3309 wuffs_base__token::value_base_detail__sign_extended() const {
3310 return wuffs_base__token__value_base_detail__sign_extended(this);
3311 }
3312
3313 inline bool //
continued()3314 wuffs_base__token::continued() const {
3315 return wuffs_base__token__continued(this);
3316 }
3317
3318 inline uint64_t //
length()3319 wuffs_base__token::length() const {
3320 return wuffs_base__token__length(this);
3321 }
3322
3323 #endif // __cplusplus
3324
3325 // --------
3326
3327 typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token;
3328
3329 static inline wuffs_base__slice_token //
wuffs_base__make_slice_token(wuffs_base__token * ptr,size_t len)3330 wuffs_base__make_slice_token(wuffs_base__token* ptr, size_t len) {
3331 wuffs_base__slice_token ret;
3332 ret.ptr = ptr;
3333 ret.len = len;
3334 return ret;
3335 }
3336
3337 static inline wuffs_base__slice_token //
wuffs_base__empty_slice_token()3338 wuffs_base__empty_slice_token() {
3339 wuffs_base__slice_token ret;
3340 ret.ptr = NULL;
3341 ret.len = 0;
3342 return ret;
3343 }
3344
3345 // --------
3346
3347 // wuffs_base__token_buffer_meta is the metadata for a
3348 // wuffs_base__token_buffer's data.
3349 typedef struct wuffs_base__token_buffer_meta__struct {
3350 size_t wi; // Write index. Invariant: wi <= len.
3351 size_t ri; // Read index. Invariant: ri <= wi.
3352 uint64_t pos; // Position of the buffer start relative to the stream start.
3353 bool closed; // No further writes are expected.
3354 } wuffs_base__token_buffer_meta;
3355
3356 // wuffs_base__token_buffer is a 1-dimensional buffer (a pointer and length)
3357 // plus additional metadata.
3358 //
3359 // A value with all fields zero is a valid, empty buffer.
3360 typedef struct wuffs_base__token_buffer__struct {
3361 wuffs_base__slice_token data;
3362 wuffs_base__token_buffer_meta meta;
3363
3364 #ifdef __cplusplus
3365 inline bool is_valid() const;
3366 inline void compact();
3367 inline uint64_t reader_length() const;
3368 inline wuffs_base__token* reader_pointer() const;
3369 inline wuffs_base__slice_token reader_slice() const;
3370 inline uint64_t reader_token_position() const;
3371 inline uint64_t writer_length() const;
3372 inline uint64_t writer_token_position() const;
3373 inline wuffs_base__token* writer_pointer() const;
3374 inline wuffs_base__slice_token writer_slice() const;
3375 #endif // __cplusplus
3376
3377 } wuffs_base__token_buffer;
3378
3379 static inline wuffs_base__token_buffer //
wuffs_base__make_token_buffer(wuffs_base__slice_token data,wuffs_base__token_buffer_meta meta)3380 wuffs_base__make_token_buffer(wuffs_base__slice_token data,
3381 wuffs_base__token_buffer_meta meta) {
3382 wuffs_base__token_buffer ret;
3383 ret.data = data;
3384 ret.meta = meta;
3385 return ret;
3386 }
3387
3388 static inline wuffs_base__token_buffer_meta //
wuffs_base__make_token_buffer_meta(size_t wi,size_t ri,uint64_t pos,bool closed)3389 wuffs_base__make_token_buffer_meta(size_t wi,
3390 size_t ri,
3391 uint64_t pos,
3392 bool closed) {
3393 wuffs_base__token_buffer_meta ret;
3394 ret.wi = wi;
3395 ret.ri = ri;
3396 ret.pos = pos;
3397 ret.closed = closed;
3398 return ret;
3399 }
3400
3401 static inline wuffs_base__token_buffer //
wuffs_base__slice_token__reader(wuffs_base__slice_token s,bool closed)3402 wuffs_base__slice_token__reader(wuffs_base__slice_token s, bool closed) {
3403 wuffs_base__token_buffer ret;
3404 ret.data.ptr = s.ptr;
3405 ret.data.len = s.len;
3406 ret.meta.wi = s.len;
3407 ret.meta.ri = 0;
3408 ret.meta.pos = 0;
3409 ret.meta.closed = closed;
3410 return ret;
3411 }
3412
3413 static inline wuffs_base__token_buffer //
wuffs_base__slice_token__writer(wuffs_base__slice_token s)3414 wuffs_base__slice_token__writer(wuffs_base__slice_token s) {
3415 wuffs_base__token_buffer ret;
3416 ret.data.ptr = s.ptr;
3417 ret.data.len = s.len;
3418 ret.meta.wi = 0;
3419 ret.meta.ri = 0;
3420 ret.meta.pos = 0;
3421 ret.meta.closed = false;
3422 return ret;
3423 }
3424
3425 static inline wuffs_base__token_buffer //
wuffs_base__empty_token_buffer()3426 wuffs_base__empty_token_buffer() {
3427 wuffs_base__token_buffer ret;
3428 ret.data.ptr = NULL;
3429 ret.data.len = 0;
3430 ret.meta.wi = 0;
3431 ret.meta.ri = 0;
3432 ret.meta.pos = 0;
3433 ret.meta.closed = false;
3434 return ret;
3435 }
3436
3437 static inline wuffs_base__token_buffer_meta //
wuffs_base__empty_token_buffer_meta()3438 wuffs_base__empty_token_buffer_meta() {
3439 wuffs_base__token_buffer_meta ret;
3440 ret.wi = 0;
3441 ret.ri = 0;
3442 ret.pos = 0;
3443 ret.closed = false;
3444 return ret;
3445 }
3446
3447 static inline bool //
wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer * buf)3448 wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer* buf) {
3449 if (buf) {
3450 if (buf->data.ptr) {
3451 return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
3452 } else {
3453 return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
3454 }
3455 }
3456 return false;
3457 }
3458
3459 // wuffs_base__token_buffer__compact moves any written but unread tokens to the
3460 // start of the buffer.
3461 static inline void //
wuffs_base__token_buffer__compact(wuffs_base__token_buffer * buf)3462 wuffs_base__token_buffer__compact(wuffs_base__token_buffer* buf) {
3463 if (!buf || (buf->meta.ri == 0)) {
3464 return;
3465 }
3466 buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri);
3467 size_t n = buf->meta.wi - buf->meta.ri;
3468 if (n != 0) {
3469 memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri,
3470 n * sizeof(wuffs_base__token));
3471 }
3472 buf->meta.wi = n;
3473 buf->meta.ri = 0;
3474 }
3475
3476 static inline uint64_t //
wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer * buf)3477 wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer* buf) {
3478 return buf ? buf->meta.wi - buf->meta.ri : 0;
3479 }
3480
3481 static inline wuffs_base__token* //
wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer * buf)3482 wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer* buf) {
3483 return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
3484 }
3485
3486 static inline wuffs_base__slice_token //
wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer * buf)3487 wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer* buf) {
3488 return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.ri,
3489 buf->meta.wi - buf->meta.ri)
3490 : wuffs_base__empty_slice_token();
3491 }
3492
3493 static inline uint64_t //
wuffs_base__token_buffer__reader_token_position(const wuffs_base__token_buffer * buf)3494 wuffs_base__token_buffer__reader_token_position(
3495 const wuffs_base__token_buffer* buf) {
3496 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
3497 }
3498
3499 static inline uint64_t //
wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer * buf)3500 wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer* buf) {
3501 return buf ? buf->data.len - buf->meta.wi : 0;
3502 }
3503
3504 static inline wuffs_base__token* //
wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer * buf)3505 wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer* buf) {
3506 return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
3507 }
3508
3509 static inline wuffs_base__slice_token //
wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer * buf)3510 wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer* buf) {
3511 return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.wi,
3512 buf->data.len - buf->meta.wi)
3513 : wuffs_base__empty_slice_token();
3514 }
3515
3516 static inline uint64_t //
wuffs_base__token_buffer__writer_token_position(const wuffs_base__token_buffer * buf)3517 wuffs_base__token_buffer__writer_token_position(
3518 const wuffs_base__token_buffer* buf) {
3519 return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
3520 }
3521
3522 #ifdef __cplusplus
3523
3524 inline bool //
is_valid()3525 wuffs_base__token_buffer::is_valid() const {
3526 return wuffs_base__token_buffer__is_valid(this);
3527 }
3528
3529 inline void //
compact()3530 wuffs_base__token_buffer::compact() {
3531 wuffs_base__token_buffer__compact(this);
3532 }
3533
3534 inline uint64_t //
reader_length()3535 wuffs_base__token_buffer::reader_length() const {
3536 return wuffs_base__token_buffer__reader_length(this);
3537 }
3538
3539 inline wuffs_base__token* //
reader_pointer()3540 wuffs_base__token_buffer::reader_pointer() const {
3541 return wuffs_base__token_buffer__reader_pointer(this);
3542 }
3543
3544 inline wuffs_base__slice_token //
reader_slice()3545 wuffs_base__token_buffer::reader_slice() const {
3546 return wuffs_base__token_buffer__reader_slice(this);
3547 }
3548
3549 inline uint64_t //
reader_token_position()3550 wuffs_base__token_buffer::reader_token_position() const {
3551 return wuffs_base__token_buffer__reader_token_position(this);
3552 }
3553
3554 inline uint64_t //
writer_length()3555 wuffs_base__token_buffer::writer_length() const {
3556 return wuffs_base__token_buffer__writer_length(this);
3557 }
3558
3559 inline wuffs_base__token* //
writer_pointer()3560 wuffs_base__token_buffer::writer_pointer() const {
3561 return wuffs_base__token_buffer__writer_pointer(this);
3562 }
3563
3564 inline wuffs_base__slice_token //
writer_slice()3565 wuffs_base__token_buffer::writer_slice() const {
3566 return wuffs_base__token_buffer__writer_slice(this);
3567 }
3568
3569 inline uint64_t //
writer_token_position()3570 wuffs_base__token_buffer::writer_token_position() const {
3571 return wuffs_base__token_buffer__writer_token_position(this);
3572 }
3573
3574 #endif // __cplusplus
3575
3576 // ---------------- Memory Allocation
3577
3578 // The memory allocation related functions in this section aren't used by Wuffs
3579 // per se, but they may be helpful to the code that uses Wuffs.
3580
3581 // wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except
3582 // that it takes a uint64_t number of elements instead of a size_t size in
3583 // bytes, and it returns a slice (a pointer and a length) instead of just a
3584 // pointer.
3585 //
3586 // You can pass the C stdlib's malloc as the malloc_func.
3587 //
3588 // It returns an empty slice (containing a NULL ptr field) if (num_uxx *
3589 // sizeof(uintxx_t)) would overflow SIZE_MAX.
3590
3591 static inline wuffs_base__slice_u8 //
wuffs_base__malloc_slice_u8(void * (* malloc_func)(size_t),uint64_t num_u8)3592 wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) {
3593 if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) {
3594 void* p = (*malloc_func)((size_t)(num_u8 * sizeof(uint8_t)));
3595 if (p) {
3596 return wuffs_base__make_slice_u8((uint8_t*)(p), (size_t)num_u8);
3597 }
3598 }
3599 return wuffs_base__make_slice_u8(NULL, 0);
3600 }
3601
3602 static inline wuffs_base__slice_u16 //
wuffs_base__malloc_slice_u16(void * (* malloc_func)(size_t),uint64_t num_u16)3603 wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) {
3604 if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) {
3605 void* p = (*malloc_func)((size_t)(num_u16 * sizeof(uint16_t)));
3606 if (p) {
3607 return wuffs_base__make_slice_u16((uint16_t*)(p), (size_t)num_u16);
3608 }
3609 }
3610 return wuffs_base__make_slice_u16(NULL, 0);
3611 }
3612
3613 static inline wuffs_base__slice_u32 //
wuffs_base__malloc_slice_u32(void * (* malloc_func)(size_t),uint64_t num_u32)3614 wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) {
3615 if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) {
3616 void* p = (*malloc_func)((size_t)(num_u32 * sizeof(uint32_t)));
3617 if (p) {
3618 return wuffs_base__make_slice_u32((uint32_t*)(p), (size_t)num_u32);
3619 }
3620 }
3621 return wuffs_base__make_slice_u32(NULL, 0);
3622 }
3623
3624 static inline wuffs_base__slice_u64 //
wuffs_base__malloc_slice_u64(void * (* malloc_func)(size_t),uint64_t num_u64)3625 wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) {
3626 if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) {
3627 void* p = (*malloc_func)((size_t)(num_u64 * sizeof(uint64_t)));
3628 if (p) {
3629 return wuffs_base__make_slice_u64((uint64_t*)(p), (size_t)num_u64);
3630 }
3631 }
3632 return wuffs_base__make_slice_u64(NULL, 0);
3633 }
3634
3635 // ---------------- Images
3636
3637 // wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
3638 // Alpha, Red, Green, Blue color, as a uint32_t value. Its value is always
3639 // 0xAARRGGBB (Alpha most significant, Blue least), regardless of endianness.
3640 typedef uint32_t wuffs_base__color_u32_argb_premul;
3641
3642 // wuffs_base__color_u32_argb_premul__is_valid returns whether c's Red, Green
3643 // and Blue channels are all less than or equal to its Alpha channel. c uses
3644 // premultiplied alpha, so 50% opaque 100% saturated red is 0x7F7F_0000 and a
3645 // value like 0x7F80_0000 is invalid.
3646 static inline bool //
wuffs_base__color_u32_argb_premul__is_valid(wuffs_base__color_u32_argb_premul c)3647 wuffs_base__color_u32_argb_premul__is_valid(
3648 wuffs_base__color_u32_argb_premul c) {
3649 uint32_t a = 0xFF & (c >> 24);
3650 uint32_t r = 0xFF & (c >> 16);
3651 uint32_t g = 0xFF & (c >> 8);
3652 uint32_t b = 0xFF & (c >> 0);
3653 return (a >= r) && (a >= g) && (a >= b);
3654 }
3655
3656 static inline uint16_t //
wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(wuffs_base__color_u32_argb_premul c)3657 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
3658 wuffs_base__color_u32_argb_premul c) {
3659 uint32_t r5 = 0xF800 & (c >> 8);
3660 uint32_t g6 = 0x07E0 & (c >> 5);
3661 uint32_t b5 = 0x001F & (c >> 3);
3662 return (uint16_t)(r5 | g6 | b5);
3663 }
3664
3665 static inline wuffs_base__color_u32_argb_premul //
wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565)3666 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565) {
3667 uint32_t b5 = 0x1F & (rgb_565 >> 0);
3668 uint32_t b = (b5 << 3) | (b5 >> 2);
3669 uint32_t g6 = 0x3F & (rgb_565 >> 5);
3670 uint32_t g = (g6 << 2) | (g6 >> 4);
3671 uint32_t r5 = 0x1F & (rgb_565 >> 11);
3672 uint32_t r = (r5 << 3) | (r5 >> 2);
3673 return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
3674 }
3675
3676 static inline uint8_t //
wuffs_base__color_u32_argb_premul__as__color_u8_gray(wuffs_base__color_u32_argb_premul c)3677 wuffs_base__color_u32_argb_premul__as__color_u8_gray(
3678 wuffs_base__color_u32_argb_premul c) {
3679 // Work in 16-bit color.
3680 uint32_t cr = 0x101 * (0xFF & (c >> 16));
3681 uint32_t cg = 0x101 * (0xFF & (c >> 8));
3682 uint32_t cb = 0x101 * (0xFF & (c >> 0));
3683
3684 // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3685 // as those given by the JFIF specification.
3686 //
3687 // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16). We
3688 // shift by 24, not just by 16, because the return value is 8-bit color, not
3689 // 16-bit color.
3690 uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3691 return (uint8_t)(weighted_average >> 24);
3692 }
3693
3694 static inline uint16_t //
wuffs_base__color_u32_argb_premul__as__color_u16_gray(wuffs_base__color_u32_argb_premul c)3695 wuffs_base__color_u32_argb_premul__as__color_u16_gray(
3696 wuffs_base__color_u32_argb_premul c) {
3697 // Work in 16-bit color.
3698 uint32_t cr = 0x101 * (0xFF & (c >> 16));
3699 uint32_t cg = 0x101 * (0xFF & (c >> 8));
3700 uint32_t cb = 0x101 * (0xFF & (c >> 0));
3701
3702 // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
3703 // as those given by the JFIF specification.
3704 //
3705 // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16).
3706 uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
3707 return (uint16_t)(weighted_average >> 16);
3708 }
3709
3710 // wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul converts
3711 // from non-premultiplied alpha to premultiplied alpha.
3712 static inline wuffs_base__color_u32_argb_premul //
wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(uint32_t argb_nonpremul)3713 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
3714 uint32_t argb_nonpremul) {
3715 // Multiplying by 0x101 (twice, once for alpha and once for color) converts
3716 // from 8-bit to 16-bit color. Shifting right by 8 undoes that.
3717 //
3718 // Working in the higher bit depth can produce slightly different (and
3719 // arguably slightly more accurate) results. For example, given 8-bit blue
3720 // and alpha of 0x80 and 0x81:
3721 //
3722 // - ((0x80 * 0x81 ) / 0xFF ) = 0x40 = 0x40
3723 // - ((0x8080 * 0x8181) / 0xFFFF) >> 8 = 0x4101 >> 8 = 0x41
3724 uint32_t a = 0xFF & (argb_nonpremul >> 24);
3725 uint32_t a16 = a * (0x101 * 0x101);
3726
3727 uint32_t r = 0xFF & (argb_nonpremul >> 16);
3728 r = ((r * a16) / 0xFFFF) >> 8;
3729 uint32_t g = 0xFF & (argb_nonpremul >> 8);
3730 g = ((g * a16) / 0xFFFF) >> 8;
3731 uint32_t b = 0xFF & (argb_nonpremul >> 0);
3732 b = ((b * a16) / 0xFFFF) >> 8;
3733
3734 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3735 }
3736
3737 // wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul converts
3738 // from premultiplied alpha to non-premultiplied alpha.
3739 static inline uint32_t //
wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3740 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
3741 wuffs_base__color_u32_argb_premul c) {
3742 uint32_t a = 0xFF & (c >> 24);
3743 if (a == 0xFF) {
3744 return c;
3745 } else if (a == 0) {
3746 return 0;
3747 }
3748 uint32_t a16 = a * 0x101;
3749
3750 uint32_t r = 0xFF & (c >> 16);
3751 r = ((r * (0x101 * 0xFFFF)) / a16) >> 8;
3752 uint32_t g = 0xFF & (c >> 8);
3753 g = ((g * (0x101 * 0xFFFF)) / a16) >> 8;
3754 uint32_t b = 0xFF & (c >> 0);
3755 b = ((b * (0x101 * 0xFFFF)) / a16) >> 8;
3756
3757 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3758 }
3759
3760 // wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul converts
3761 // from 4x16LE non-premultiplied alpha to 4x8 premultiplied alpha.
3762 static inline wuffs_base__color_u32_argb_premul //
wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(uint64_t argb_nonpremul)3763 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
3764 uint64_t argb_nonpremul) {
3765 uint32_t a16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 48)));
3766
3767 uint32_t r16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 32)));
3768 r16 = (r16 * a16) / 0xFFFF;
3769 uint32_t g16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 16)));
3770 g16 = (g16 * a16) / 0xFFFF;
3771 uint32_t b16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 0)));
3772 b16 = (b16 * a16) / 0xFFFF;
3773
3774 return ((a16 >> 8) << 24) | ((r16 >> 8) << 16) | ((g16 >> 8) << 8) |
3775 ((b16 >> 8) << 0);
3776 }
3777
3778 // wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul converts
3779 // from 4x8 premultiplied alpha to 4x16LE non-premultiplied alpha.
3780 static inline uint64_t //
wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(wuffs_base__color_u32_argb_premul c)3781 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
3782 wuffs_base__color_u32_argb_premul c) {
3783 uint32_t a = 0xFF & (c >> 24);
3784 if (a == 0xFF) {
3785 uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3786 uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3787 uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3788 return 0xFFFF000000000000u | (r16 << 32) | (g16 << 16) | (b16 << 0);
3789 } else if (a == 0) {
3790 return 0;
3791 }
3792 uint64_t a16 = a * 0x101;
3793
3794 uint64_t r = 0xFF & (c >> 16);
3795 uint64_t r16 = (r * (0x101 * 0xFFFF)) / a16;
3796 uint64_t g = 0xFF & (c >> 8);
3797 uint64_t g16 = (g * (0x101 * 0xFFFF)) / a16;
3798 uint64_t b = 0xFF & (c >> 0);
3799 uint64_t b16 = (b * (0x101 * 0xFFFF)) / a16;
3800
3801 return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3802 }
3803
3804 static inline uint64_t //
wuffs_base__color_u32__as__color_u64(uint32_t c)3805 wuffs_base__color_u32__as__color_u64(uint32_t c) {
3806 uint64_t a16 = 0x101 * (0xFF & (c >> 24));
3807 uint64_t r16 = 0x101 * (0xFF & (c >> 16));
3808 uint64_t g16 = 0x101 * (0xFF & (c >> 8));
3809 uint64_t b16 = 0x101 * (0xFF & (c >> 0));
3810 return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
3811 }
3812
3813 static inline uint32_t //
wuffs_base__color_u64__as__color_u32(uint64_t c)3814 wuffs_base__color_u64__as__color_u32(uint64_t c) {
3815 uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
3816 uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
3817 uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
3818 uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
3819 return (a << 24) | (r << 16) | (g << 8) | (b << 0);
3820 }
3821
3822 // --------
3823
3824 typedef uint8_t wuffs_base__pixel_blend;
3825
3826 // wuffs_base__pixel_blend encodes how to blend source and destination pixels,
3827 // accounting for transparency. It encompasses the Porter-Duff compositing
3828 // operators as well as the other blending modes defined by PDF.
3829 //
3830 // TODO: implement the other modes.
3831 #define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
3832 #define WUFFS_BASE__PIXEL_BLEND__SRC_OVER ((wuffs_base__pixel_blend)1)
3833
3834 // --------
3835
3836 // wuffs_base__pixel_alpha_transparency is a pixel format's alpha channel
3837 // model. It is a property of the pixel format in general, not of a specific
3838 // pixel. An RGBA pixel format (with alpha) can still have fully opaque pixels.
3839 typedef uint32_t wuffs_base__pixel_alpha_transparency;
3840
3841 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE 0
3842 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA 1
3843 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__PREMULTIPLIED_ALPHA 2
3844 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__BINARY_ALPHA 3
3845
3846 // Deprecated: use WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA
3847 // instead.
3848 #define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NON_PREMULTIPLIED_ALPHA 1
3849
3850 // --------
3851
3852 #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
3853
3854 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
3855 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
3856
3857 // A palette is 256 entries × 4 bytes per entry (e.g. BGRA).
3858 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH 1024
3859
3860 // wuffs_base__pixel_format encodes the format of the bytes that constitute an
3861 // image frame's pixel data.
3862 //
3863 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-formats.md
3864 //
3865 // Do not manipulate its bits directly; they are private implementation
3866 // details. Use methods such as wuffs_base__pixel_format__num_planes instead.
3867 typedef struct wuffs_base__pixel_format__struct {
3868 uint32_t repr;
3869
3870 #ifdef __cplusplus
3871 inline bool is_valid() const;
3872 inline uint32_t bits_per_pixel() const;
3873 inline bool is_direct() const;
3874 inline bool is_indexed() const;
3875 inline bool is_interleaved() const;
3876 inline bool is_planar() const;
3877 inline uint32_t num_planes() const;
3878 inline wuffs_base__pixel_alpha_transparency transparency() const;
3879 #endif // __cplusplus
3880
3881 } wuffs_base__pixel_format;
3882
3883 static inline wuffs_base__pixel_format //
wuffs_base__make_pixel_format(uint32_t repr)3884 wuffs_base__make_pixel_format(uint32_t repr) {
3885 wuffs_base__pixel_format f;
3886 f.repr = repr;
3887 return f;
3888 }
3889
3890 // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid
3891 // wuffs_base__pixel_format values are present.
3892
3893 #define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000
3894
3895 #define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008
3896
3897 #define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008
3898 #define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B
3899 #define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B
3900 #define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000008
3901 #define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000008
3902
3903 #define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888
3904 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888
3905 #define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888
3906
3907 #define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888
3908 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888
3909 #define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888
3910
3911 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008
3912 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008
3913 #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008
3914
3915 #define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565
3916 #define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888
3917 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888
3918 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB
3919 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888
3920 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB
3921 #define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888
3922 #define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888
3923
3924 #define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888
3925 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888
3926 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB
3927 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888
3928 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB
3929 #define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888
3930 #define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888
3931
3932 #define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888
3933 #define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888
3934
3935 extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];
3936
3937 static inline bool //
wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format * f)3938 wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {
3939 return f->repr != 0;
3940 }
3941
3942 // wuffs_base__pixel_format__bits_per_pixel returns the number of bits per
3943 // pixel for interleaved pixel formats, and returns 0 for planar pixel formats.
3944 static inline uint32_t //
wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format * f)3945 wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) {
3946 if (((f->repr >> 16) & 0x03) != 0) {
3947 return 0;
3948 }
3949 return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] +
3950 wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] +
3951 wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 8)] +
3952 wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 12)];
3953 }
3954
3955 static inline bool //
wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format * f)3956 wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format* f) {
3957 return ((f->repr >> 18) & 0x01) == 0;
3958 }
3959
3960 static inline bool //
wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format * f)3961 wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format* f) {
3962 return ((f->repr >> 18) & 0x01) != 0;
3963 }
3964
3965 static inline bool //
wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format * f)3966 wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format* f) {
3967 return ((f->repr >> 16) & 0x03) == 0;
3968 }
3969
3970 static inline bool //
wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format * f)3971 wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format* f) {
3972 return ((f->repr >> 16) & 0x03) != 0;
3973 }
3974
3975 static inline uint32_t //
wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format * f)3976 wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format* f) {
3977 return ((f->repr >> 16) & 0x03) + 1;
3978 }
3979
3980 static inline wuffs_base__pixel_alpha_transparency //
wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format * f)3981 wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format* f) {
3982 return (wuffs_base__pixel_alpha_transparency)((f->repr >> 24) & 0x03);
3983 }
3984
3985 #ifdef __cplusplus
3986
3987 inline bool //
is_valid()3988 wuffs_base__pixel_format::is_valid() const {
3989 return wuffs_base__pixel_format__is_valid(this);
3990 }
3991
3992 inline uint32_t //
bits_per_pixel()3993 wuffs_base__pixel_format::bits_per_pixel() const {
3994 return wuffs_base__pixel_format__bits_per_pixel(this);
3995 }
3996
3997 inline bool //
is_direct()3998 wuffs_base__pixel_format::is_direct() const {
3999 return wuffs_base__pixel_format__is_direct(this);
4000 }
4001
4002 inline bool //
is_indexed()4003 wuffs_base__pixel_format::is_indexed() const {
4004 return wuffs_base__pixel_format__is_indexed(this);
4005 }
4006
4007 inline bool //
is_interleaved()4008 wuffs_base__pixel_format::is_interleaved() const {
4009 return wuffs_base__pixel_format__is_interleaved(this);
4010 }
4011
4012 inline bool //
is_planar()4013 wuffs_base__pixel_format::is_planar() const {
4014 return wuffs_base__pixel_format__is_planar(this);
4015 }
4016
4017 inline uint32_t //
num_planes()4018 wuffs_base__pixel_format::num_planes() const {
4019 return wuffs_base__pixel_format__num_planes(this);
4020 }
4021
4022 inline wuffs_base__pixel_alpha_transparency //
transparency()4023 wuffs_base__pixel_format::transparency() const {
4024 return wuffs_base__pixel_format__transparency(this);
4025 }
4026
4027 #endif // __cplusplus
4028
4029 // --------
4030
4031 // wuffs_base__pixel_subsampling encodes whether sample values cover one pixel
4032 // or cover multiple pixels.
4033 //
4034 // See https://github.com/google/wuffs/blob/main/doc/note/pixel-subsampling.md
4035 //
4036 // Do not manipulate its bits directly; they are private implementation
4037 // details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead.
4038 typedef struct wuffs_base__pixel_subsampling__struct {
4039 uint32_t repr;
4040
4041 #ifdef __cplusplus
4042 inline uint32_t bias_x(uint32_t plane) const;
4043 inline uint32_t denominator_x(uint32_t plane) const;
4044 inline uint32_t bias_y(uint32_t plane) const;
4045 inline uint32_t denominator_y(uint32_t plane) const;
4046 #endif // __cplusplus
4047
4048 } wuffs_base__pixel_subsampling;
4049
4050 static inline wuffs_base__pixel_subsampling //
wuffs_base__make_pixel_subsampling(uint32_t repr)4051 wuffs_base__make_pixel_subsampling(uint32_t repr) {
4052 wuffs_base__pixel_subsampling s;
4053 s.repr = repr;
4054 return s;
4055 }
4056
4057 #define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE 0x00000000
4058
4059 #define WUFFS_BASE__PIXEL_SUBSAMPLING__444 0x000000
4060 #define WUFFS_BASE__PIXEL_SUBSAMPLING__440 0x010100
4061 #define WUFFS_BASE__PIXEL_SUBSAMPLING__422 0x101000
4062 #define WUFFS_BASE__PIXEL_SUBSAMPLING__420 0x111100
4063 #define WUFFS_BASE__PIXEL_SUBSAMPLING__411 0x303000
4064 #define WUFFS_BASE__PIXEL_SUBSAMPLING__410 0x313100
4065
4066 static inline uint32_t //
wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4067 wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling* s,
4068 uint32_t plane) {
4069 uint32_t shift = ((plane & 0x03) * 8) + 6;
4070 return (s->repr >> shift) & 0x03;
4071 }
4072
4073 static inline uint32_t //
wuffs_base__pixel_subsampling__denominator_x(const wuffs_base__pixel_subsampling * s,uint32_t plane)4074 wuffs_base__pixel_subsampling__denominator_x(
4075 const wuffs_base__pixel_subsampling* s,
4076 uint32_t plane) {
4077 uint32_t shift = ((plane & 0x03) * 8) + 4;
4078 return ((s->repr >> shift) & 0x03) + 1;
4079 }
4080
4081 static inline uint32_t //
wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4082 wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling* s,
4083 uint32_t plane) {
4084 uint32_t shift = ((plane & 0x03) * 8) + 2;
4085 return (s->repr >> shift) & 0x03;
4086 }
4087
4088 static inline uint32_t //
wuffs_base__pixel_subsampling__denominator_y(const wuffs_base__pixel_subsampling * s,uint32_t plane)4089 wuffs_base__pixel_subsampling__denominator_y(
4090 const wuffs_base__pixel_subsampling* s,
4091 uint32_t plane) {
4092 uint32_t shift = ((plane & 0x03) * 8) + 0;
4093 return ((s->repr >> shift) & 0x03) + 1;
4094 }
4095
4096 #ifdef __cplusplus
4097
4098 inline uint32_t //
bias_x(uint32_t plane)4099 wuffs_base__pixel_subsampling::bias_x(uint32_t plane) const {
4100 return wuffs_base__pixel_subsampling__bias_x(this, plane);
4101 }
4102
4103 inline uint32_t //
denominator_x(uint32_t plane)4104 wuffs_base__pixel_subsampling::denominator_x(uint32_t plane) const {
4105 return wuffs_base__pixel_subsampling__denominator_x(this, plane);
4106 }
4107
4108 inline uint32_t //
bias_y(uint32_t plane)4109 wuffs_base__pixel_subsampling::bias_y(uint32_t plane) const {
4110 return wuffs_base__pixel_subsampling__bias_y(this, plane);
4111 }
4112
4113 inline uint32_t //
denominator_y(uint32_t plane)4114 wuffs_base__pixel_subsampling::denominator_y(uint32_t plane) const {
4115 return wuffs_base__pixel_subsampling__denominator_y(this, plane);
4116 }
4117
4118 #endif // __cplusplus
4119
4120 // --------
4121
4122 typedef struct wuffs_base__pixel_config__struct {
4123 // Do not access the private_impl's fields directly. There is no API/ABI
4124 // compatibility or safety guarantee if you do so.
4125 struct {
4126 wuffs_base__pixel_format pixfmt;
4127 wuffs_base__pixel_subsampling pixsub;
4128 uint32_t width;
4129 uint32_t height;
4130 } private_impl;
4131
4132 #ifdef __cplusplus
4133 inline void set(uint32_t pixfmt_repr,
4134 uint32_t pixsub_repr,
4135 uint32_t width,
4136 uint32_t height);
4137 inline void invalidate();
4138 inline bool is_valid() const;
4139 inline wuffs_base__pixel_format pixel_format() const;
4140 inline wuffs_base__pixel_subsampling pixel_subsampling() const;
4141 inline wuffs_base__rect_ie_u32 bounds() const;
4142 inline uint32_t width() const;
4143 inline uint32_t height() const;
4144 inline uint64_t pixbuf_len() const;
4145 #endif // __cplusplus
4146
4147 } wuffs_base__pixel_config;
4148
4149 static inline wuffs_base__pixel_config //
wuffs_base__null_pixel_config()4150 wuffs_base__null_pixel_config() {
4151 wuffs_base__pixel_config ret;
4152 ret.private_impl.pixfmt.repr = 0;
4153 ret.private_impl.pixsub.repr = 0;
4154 ret.private_impl.width = 0;
4155 ret.private_impl.height = 0;
4156 return ret;
4157 }
4158
4159 // TODO: Should this function return bool? An error type?
4160 static inline void //
wuffs_base__pixel_config__set(wuffs_base__pixel_config * c,uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height)4161 wuffs_base__pixel_config__set(wuffs_base__pixel_config* c,
4162 uint32_t pixfmt_repr,
4163 uint32_t pixsub_repr,
4164 uint32_t width,
4165 uint32_t height) {
4166 if (!c) {
4167 return;
4168 }
4169 if (pixfmt_repr) {
4170 uint64_t wh = ((uint64_t)width) * ((uint64_t)height);
4171 // TODO: handle things other than 1 byte per pixel.
4172 if (wh <= ((uint64_t)SIZE_MAX)) {
4173 c->private_impl.pixfmt.repr = pixfmt_repr;
4174 c->private_impl.pixsub.repr = pixsub_repr;
4175 c->private_impl.width = width;
4176 c->private_impl.height = height;
4177 return;
4178 }
4179 }
4180
4181 c->private_impl.pixfmt.repr = 0;
4182 c->private_impl.pixsub.repr = 0;
4183 c->private_impl.width = 0;
4184 c->private_impl.height = 0;
4185 }
4186
4187 static inline void //
wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config * c)4188 wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) {
4189 if (c) {
4190 c->private_impl.pixfmt.repr = 0;
4191 c->private_impl.pixsub.repr = 0;
4192 c->private_impl.width = 0;
4193 c->private_impl.height = 0;
4194 }
4195 }
4196
4197 static inline bool //
wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config * c)4198 wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) {
4199 return c && c->private_impl.pixfmt.repr;
4200 }
4201
4202 static inline wuffs_base__pixel_format //
wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config * c)4203 wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
4204 return c ? c->private_impl.pixfmt : wuffs_base__make_pixel_format(0);
4205 }
4206
4207 static inline wuffs_base__pixel_subsampling //
wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config * c)4208 wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) {
4209 return c ? c->private_impl.pixsub : wuffs_base__make_pixel_subsampling(0);
4210 }
4211
4212 static inline wuffs_base__rect_ie_u32 //
wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config * c)4213 wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) {
4214 if (c) {
4215 wuffs_base__rect_ie_u32 ret;
4216 ret.min_incl_x = 0;
4217 ret.min_incl_y = 0;
4218 ret.max_excl_x = c->private_impl.width;
4219 ret.max_excl_y = c->private_impl.height;
4220 return ret;
4221 }
4222
4223 wuffs_base__rect_ie_u32 ret;
4224 ret.min_incl_x = 0;
4225 ret.min_incl_y = 0;
4226 ret.max_excl_x = 0;
4227 ret.max_excl_y = 0;
4228 return ret;
4229 }
4230
4231 static inline uint32_t //
wuffs_base__pixel_config__width(const wuffs_base__pixel_config * c)4232 wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) {
4233 return c ? c->private_impl.width : 0;
4234 }
4235
4236 static inline uint32_t //
wuffs_base__pixel_config__height(const wuffs_base__pixel_config * c)4237 wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) {
4238 return c ? c->private_impl.height : 0;
4239 }
4240
4241 // TODO: this is the right API for planar (not interleaved) pixbufs? Should it
4242 // allow decoding into a color model different from the format's intrinsic one?
4243 // For example, decoding a JPEG image straight to RGBA instead of to YCbCr?
4244 static inline uint64_t //
wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config * c)4245 wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) {
4246 if (!c) {
4247 return 0;
4248 }
4249 if (wuffs_base__pixel_format__is_planar(&c->private_impl.pixfmt)) {
4250 // TODO: support planar pixel formats, concious of pixel subsampling.
4251 return 0;
4252 }
4253 uint32_t bits_per_pixel =
4254 wuffs_base__pixel_format__bits_per_pixel(&c->private_impl.pixfmt);
4255 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4256 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4257 return 0;
4258 }
4259 uint64_t bytes_per_pixel = bits_per_pixel / 8;
4260
4261 uint64_t n =
4262 ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height);
4263 if (n > (UINT64_MAX / bytes_per_pixel)) {
4264 return 0;
4265 }
4266 n *= bytes_per_pixel;
4267
4268 if (wuffs_base__pixel_format__is_indexed(&c->private_impl.pixfmt)) {
4269 if (n >
4270 (UINT64_MAX - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4271 return 0;
4272 }
4273 n += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4274 }
4275
4276 return n;
4277 }
4278
4279 #ifdef __cplusplus
4280
4281 inline void //
set(uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height)4282 wuffs_base__pixel_config::set(uint32_t pixfmt_repr,
4283 uint32_t pixsub_repr,
4284 uint32_t width,
4285 uint32_t height) {
4286 wuffs_base__pixel_config__set(this, pixfmt_repr, pixsub_repr, width, height);
4287 }
4288
4289 inline void //
invalidate()4290 wuffs_base__pixel_config::invalidate() {
4291 wuffs_base__pixel_config__invalidate(this);
4292 }
4293
4294 inline bool //
is_valid()4295 wuffs_base__pixel_config::is_valid() const {
4296 return wuffs_base__pixel_config__is_valid(this);
4297 }
4298
4299 inline wuffs_base__pixel_format //
pixel_format()4300 wuffs_base__pixel_config::pixel_format() const {
4301 return wuffs_base__pixel_config__pixel_format(this);
4302 }
4303
4304 inline wuffs_base__pixel_subsampling //
pixel_subsampling()4305 wuffs_base__pixel_config::pixel_subsampling() const {
4306 return wuffs_base__pixel_config__pixel_subsampling(this);
4307 }
4308
4309 inline wuffs_base__rect_ie_u32 //
bounds()4310 wuffs_base__pixel_config::bounds() const {
4311 return wuffs_base__pixel_config__bounds(this);
4312 }
4313
4314 inline uint32_t //
width()4315 wuffs_base__pixel_config::width() const {
4316 return wuffs_base__pixel_config__width(this);
4317 }
4318
4319 inline uint32_t //
height()4320 wuffs_base__pixel_config::height() const {
4321 return wuffs_base__pixel_config__height(this);
4322 }
4323
4324 inline uint64_t //
pixbuf_len()4325 wuffs_base__pixel_config::pixbuf_len() const {
4326 return wuffs_base__pixel_config__pixbuf_len(this);
4327 }
4328
4329 #endif // __cplusplus
4330
4331 // --------
4332
4333 typedef struct wuffs_base__image_config__struct {
4334 wuffs_base__pixel_config pixcfg;
4335
4336 // Do not access the private_impl's fields directly. There is no API/ABI
4337 // compatibility or safety guarantee if you do so.
4338 struct {
4339 uint64_t first_frame_io_position;
4340 bool first_frame_is_opaque;
4341 } private_impl;
4342
4343 #ifdef __cplusplus
4344 inline void set(uint32_t pixfmt_repr,
4345 uint32_t pixsub_repr,
4346 uint32_t width,
4347 uint32_t height,
4348 uint64_t first_frame_io_position,
4349 bool first_frame_is_opaque);
4350 inline void invalidate();
4351 inline bool is_valid() const;
4352 inline uint64_t first_frame_io_position() const;
4353 inline bool first_frame_is_opaque() const;
4354 #endif // __cplusplus
4355
4356 } wuffs_base__image_config;
4357
4358 static inline wuffs_base__image_config //
wuffs_base__null_image_config()4359 wuffs_base__null_image_config() {
4360 wuffs_base__image_config ret;
4361 ret.pixcfg = wuffs_base__null_pixel_config();
4362 ret.private_impl.first_frame_io_position = 0;
4363 ret.private_impl.first_frame_is_opaque = false;
4364 return ret;
4365 }
4366
4367 // TODO: Should this function return bool? An error type?
4368 static inline void //
wuffs_base__image_config__set(wuffs_base__image_config * c,uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height,uint64_t first_frame_io_position,bool first_frame_is_opaque)4369 wuffs_base__image_config__set(wuffs_base__image_config* c,
4370 uint32_t pixfmt_repr,
4371 uint32_t pixsub_repr,
4372 uint32_t width,
4373 uint32_t height,
4374 uint64_t first_frame_io_position,
4375 bool first_frame_is_opaque) {
4376 if (!c) {
4377 return;
4378 }
4379 if (pixfmt_repr) {
4380 c->pixcfg.private_impl.pixfmt.repr = pixfmt_repr;
4381 c->pixcfg.private_impl.pixsub.repr = pixsub_repr;
4382 c->pixcfg.private_impl.width = width;
4383 c->pixcfg.private_impl.height = height;
4384 c->private_impl.first_frame_io_position = first_frame_io_position;
4385 c->private_impl.first_frame_is_opaque = first_frame_is_opaque;
4386 return;
4387 }
4388
4389 c->pixcfg.private_impl.pixfmt.repr = 0;
4390 c->pixcfg.private_impl.pixsub.repr = 0;
4391 c->pixcfg.private_impl.width = 0;
4392 c->pixcfg.private_impl.height = 0;
4393 c->private_impl.first_frame_io_position = 0;
4394 c->private_impl.first_frame_is_opaque = 0;
4395 }
4396
4397 static inline void //
wuffs_base__image_config__invalidate(wuffs_base__image_config * c)4398 wuffs_base__image_config__invalidate(wuffs_base__image_config* c) {
4399 if (c) {
4400 c->pixcfg.private_impl.pixfmt.repr = 0;
4401 c->pixcfg.private_impl.pixsub.repr = 0;
4402 c->pixcfg.private_impl.width = 0;
4403 c->pixcfg.private_impl.height = 0;
4404 c->private_impl.first_frame_io_position = 0;
4405 c->private_impl.first_frame_is_opaque = 0;
4406 }
4407 }
4408
4409 static inline bool //
wuffs_base__image_config__is_valid(const wuffs_base__image_config * c)4410 wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) {
4411 return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg));
4412 }
4413
4414 static inline uint64_t //
wuffs_base__image_config__first_frame_io_position(const wuffs_base__image_config * c)4415 wuffs_base__image_config__first_frame_io_position(
4416 const wuffs_base__image_config* c) {
4417 return c ? c->private_impl.first_frame_io_position : 0;
4418 }
4419
4420 static inline bool //
wuffs_base__image_config__first_frame_is_opaque(const wuffs_base__image_config * c)4421 wuffs_base__image_config__first_frame_is_opaque(
4422 const wuffs_base__image_config* c) {
4423 return c ? c->private_impl.first_frame_is_opaque : false;
4424 }
4425
4426 #ifdef __cplusplus
4427
4428 inline void //
set(uint32_t pixfmt_repr,uint32_t pixsub_repr,uint32_t width,uint32_t height,uint64_t first_frame_io_position,bool first_frame_is_opaque)4429 wuffs_base__image_config::set(uint32_t pixfmt_repr,
4430 uint32_t pixsub_repr,
4431 uint32_t width,
4432 uint32_t height,
4433 uint64_t first_frame_io_position,
4434 bool first_frame_is_opaque) {
4435 wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, width, height,
4436 first_frame_io_position, first_frame_is_opaque);
4437 }
4438
4439 inline void //
invalidate()4440 wuffs_base__image_config::invalidate() {
4441 wuffs_base__image_config__invalidate(this);
4442 }
4443
4444 inline bool //
is_valid()4445 wuffs_base__image_config::is_valid() const {
4446 return wuffs_base__image_config__is_valid(this);
4447 }
4448
4449 inline uint64_t //
first_frame_io_position()4450 wuffs_base__image_config::first_frame_io_position() const {
4451 return wuffs_base__image_config__first_frame_io_position(this);
4452 }
4453
4454 inline bool //
first_frame_is_opaque()4455 wuffs_base__image_config::first_frame_is_opaque() const {
4456 return wuffs_base__image_config__first_frame_is_opaque(this);
4457 }
4458
4459 #endif // __cplusplus
4460
4461 // --------
4462
4463 // wuffs_base__animation_disposal encodes, for an animated image, how to
4464 // dispose of a frame after displaying it:
4465 // - None means to draw the next frame on top of this one.
4466 // - Restore Background means to clear the frame's dirty rectangle to "the
4467 // background color" (in practice, this means transparent black) before
4468 // drawing the next frame.
4469 // - Restore Previous means to undo the current frame, so that the next frame
4470 // is drawn on top of the previous one.
4471 typedef uint8_t wuffs_base__animation_disposal;
4472
4473 #define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0)
4474 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \
4475 ((wuffs_base__animation_disposal)1)
4476 #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \
4477 ((wuffs_base__animation_disposal)2)
4478
4479 // --------
4480
4481 typedef struct wuffs_base__frame_config__struct {
4482 // Do not access the private_impl's fields directly. There is no API/ABI
4483 // compatibility or safety guarantee if you do so.
4484 struct {
4485 wuffs_base__rect_ie_u32 bounds;
4486 wuffs_base__flicks duration;
4487 uint64_t index;
4488 uint64_t io_position;
4489 wuffs_base__animation_disposal disposal;
4490 bool opaque_within_bounds;
4491 bool overwrite_instead_of_blend;
4492 wuffs_base__color_u32_argb_premul background_color;
4493 } private_impl;
4494
4495 #ifdef __cplusplus
4496 inline void set(wuffs_base__rect_ie_u32 bounds,
4497 wuffs_base__flicks duration,
4498 uint64_t index,
4499 uint64_t io_position,
4500 wuffs_base__animation_disposal disposal,
4501 bool opaque_within_bounds,
4502 bool overwrite_instead_of_blend,
4503 wuffs_base__color_u32_argb_premul background_color);
4504 inline wuffs_base__rect_ie_u32 bounds() const;
4505 inline uint32_t width() const;
4506 inline uint32_t height() const;
4507 inline wuffs_base__flicks duration() const;
4508 inline uint64_t index() const;
4509 inline uint64_t io_position() const;
4510 inline wuffs_base__animation_disposal disposal() const;
4511 inline bool opaque_within_bounds() const;
4512 inline bool overwrite_instead_of_blend() const;
4513 inline wuffs_base__color_u32_argb_premul background_color() const;
4514 #endif // __cplusplus
4515
4516 } wuffs_base__frame_config;
4517
4518 static inline wuffs_base__frame_config //
wuffs_base__null_frame_config()4519 wuffs_base__null_frame_config() {
4520 wuffs_base__frame_config ret;
4521 ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0);
4522 ret.private_impl.duration = 0;
4523 ret.private_impl.index = 0;
4524 ret.private_impl.io_position = 0;
4525 ret.private_impl.disposal = 0;
4526 ret.private_impl.opaque_within_bounds = false;
4527 ret.private_impl.overwrite_instead_of_blend = false;
4528 return ret;
4529 }
4530
4531 static inline void //
wuffs_base__frame_config__set(wuffs_base__frame_config * c,wuffs_base__rect_ie_u32 bounds,wuffs_base__flicks duration,uint64_t index,uint64_t io_position,wuffs_base__animation_disposal disposal,bool opaque_within_bounds,bool overwrite_instead_of_blend,wuffs_base__color_u32_argb_premul background_color)4532 wuffs_base__frame_config__set(
4533 wuffs_base__frame_config* c,
4534 wuffs_base__rect_ie_u32 bounds,
4535 wuffs_base__flicks duration,
4536 uint64_t index,
4537 uint64_t io_position,
4538 wuffs_base__animation_disposal disposal,
4539 bool opaque_within_bounds,
4540 bool overwrite_instead_of_blend,
4541 wuffs_base__color_u32_argb_premul background_color) {
4542 if (!c) {
4543 return;
4544 }
4545
4546 c->private_impl.bounds = bounds;
4547 c->private_impl.duration = duration;
4548 c->private_impl.index = index;
4549 c->private_impl.io_position = io_position;
4550 c->private_impl.disposal = disposal;
4551 c->private_impl.opaque_within_bounds = opaque_within_bounds;
4552 c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
4553 c->private_impl.background_color = background_color;
4554 }
4555
4556 static inline wuffs_base__rect_ie_u32 //
wuffs_base__frame_config__bounds(const wuffs_base__frame_config * c)4557 wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) {
4558 if (c) {
4559 return c->private_impl.bounds;
4560 }
4561
4562 wuffs_base__rect_ie_u32 ret;
4563 ret.min_incl_x = 0;
4564 ret.min_incl_y = 0;
4565 ret.max_excl_x = 0;
4566 ret.max_excl_y = 0;
4567 return ret;
4568 }
4569
4570 static inline uint32_t //
wuffs_base__frame_config__width(const wuffs_base__frame_config * c)4571 wuffs_base__frame_config__width(const wuffs_base__frame_config* c) {
4572 return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0;
4573 }
4574
4575 static inline uint32_t //
wuffs_base__frame_config__height(const wuffs_base__frame_config * c)4576 wuffs_base__frame_config__height(const wuffs_base__frame_config* c) {
4577 return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0;
4578 }
4579
4580 // wuffs_base__frame_config__duration returns the amount of time to display
4581 // this frame. Zero means to display forever - a still (non-animated) image.
4582 static inline wuffs_base__flicks //
wuffs_base__frame_config__duration(const wuffs_base__frame_config * c)4583 wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) {
4584 return c ? c->private_impl.duration : 0;
4585 }
4586
4587 // wuffs_base__frame_config__index returns the index of this frame. The first
4588 // frame in an image has index 0, the second frame has index 1, and so on.
4589 static inline uint64_t //
wuffs_base__frame_config__index(const wuffs_base__frame_config * c)4590 wuffs_base__frame_config__index(const wuffs_base__frame_config* c) {
4591 return c ? c->private_impl.index : 0;
4592 }
4593
4594 // wuffs_base__frame_config__io_position returns the I/O stream position before
4595 // the frame config.
4596 static inline uint64_t //
wuffs_base__frame_config__io_position(const wuffs_base__frame_config * c)4597 wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) {
4598 return c ? c->private_impl.io_position : 0;
4599 }
4600
4601 // wuffs_base__frame_config__disposal returns, for an animated image, how to
4602 // dispose of this frame after displaying it.
4603 static inline wuffs_base__animation_disposal //
wuffs_base__frame_config__disposal(const wuffs_base__frame_config * c)4604 wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) {
4605 return c ? c->private_impl.disposal : 0;
4606 }
4607
4608 // wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
4609 // within the frame's bounds are fully opaque. It makes no claim about pixels
4610 // outside the frame bounds but still inside the overall image. The two
4611 // bounding rectangles can differ for animated images.
4612 //
4613 // Its semantics are conservative. It is valid for a fully opaque frame to have
4614 // this value be false: a false negative.
4615 //
4616 // If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
4617 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
4618 // resultant pixels, but the former may be faster.
4619 static inline bool //
wuffs_base__frame_config__opaque_within_bounds(const wuffs_base__frame_config * c)4620 wuffs_base__frame_config__opaque_within_bounds(
4621 const wuffs_base__frame_config* c) {
4622 return c && c->private_impl.opaque_within_bounds;
4623 }
4624
4625 // wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
4626 // animated image, whether to ignore the previous image state (within the frame
4627 // bounds) when drawing this incremental frame. Equivalently, whether to use
4628 // WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
4629 //
4630 // The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
4631 // calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
4632 // Wuffs' "overwrite_instead_of_blend".
4633 static inline bool //
wuffs_base__frame_config__overwrite_instead_of_blend(const wuffs_base__frame_config * c)4634 wuffs_base__frame_config__overwrite_instead_of_blend(
4635 const wuffs_base__frame_config* c) {
4636 return c && c->private_impl.overwrite_instead_of_blend;
4637 }
4638
4639 static inline wuffs_base__color_u32_argb_premul //
wuffs_base__frame_config__background_color(const wuffs_base__frame_config * c)4640 wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) {
4641 return c ? c->private_impl.background_color : 0;
4642 }
4643
4644 #ifdef __cplusplus
4645
4646 inline void //
set(wuffs_base__rect_ie_u32 bounds,wuffs_base__flicks duration,uint64_t index,uint64_t io_position,wuffs_base__animation_disposal disposal,bool opaque_within_bounds,bool overwrite_instead_of_blend,wuffs_base__color_u32_argb_premul background_color)4647 wuffs_base__frame_config::set(
4648 wuffs_base__rect_ie_u32 bounds,
4649 wuffs_base__flicks duration,
4650 uint64_t index,
4651 uint64_t io_position,
4652 wuffs_base__animation_disposal disposal,
4653 bool opaque_within_bounds,
4654 bool overwrite_instead_of_blend,
4655 wuffs_base__color_u32_argb_premul background_color) {
4656 wuffs_base__frame_config__set(this, bounds, duration, index, io_position,
4657 disposal, opaque_within_bounds,
4658 overwrite_instead_of_blend, background_color);
4659 }
4660
4661 inline wuffs_base__rect_ie_u32 //
bounds()4662 wuffs_base__frame_config::bounds() const {
4663 return wuffs_base__frame_config__bounds(this);
4664 }
4665
4666 inline uint32_t //
width()4667 wuffs_base__frame_config::width() const {
4668 return wuffs_base__frame_config__width(this);
4669 }
4670
4671 inline uint32_t //
height()4672 wuffs_base__frame_config::height() const {
4673 return wuffs_base__frame_config__height(this);
4674 }
4675
4676 inline wuffs_base__flicks //
duration()4677 wuffs_base__frame_config::duration() const {
4678 return wuffs_base__frame_config__duration(this);
4679 }
4680
4681 inline uint64_t //
index()4682 wuffs_base__frame_config::index() const {
4683 return wuffs_base__frame_config__index(this);
4684 }
4685
4686 inline uint64_t //
io_position()4687 wuffs_base__frame_config::io_position() const {
4688 return wuffs_base__frame_config__io_position(this);
4689 }
4690
4691 inline wuffs_base__animation_disposal //
disposal()4692 wuffs_base__frame_config::disposal() const {
4693 return wuffs_base__frame_config__disposal(this);
4694 }
4695
4696 inline bool //
opaque_within_bounds()4697 wuffs_base__frame_config::opaque_within_bounds() const {
4698 return wuffs_base__frame_config__opaque_within_bounds(this);
4699 }
4700
4701 inline bool //
overwrite_instead_of_blend()4702 wuffs_base__frame_config::overwrite_instead_of_blend() const {
4703 return wuffs_base__frame_config__overwrite_instead_of_blend(this);
4704 }
4705
4706 inline wuffs_base__color_u32_argb_premul //
background_color()4707 wuffs_base__frame_config::background_color() const {
4708 return wuffs_base__frame_config__background_color(this);
4709 }
4710
4711 #endif // __cplusplus
4712
4713 // --------
4714
4715 typedef struct wuffs_base__pixel_buffer__struct {
4716 wuffs_base__pixel_config pixcfg;
4717
4718 // Do not access the private_impl's fields directly. There is no API/ABI
4719 // compatibility or safety guarantee if you do so.
4720 struct {
4721 wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX];
4722 // TODO: color spaces.
4723 } private_impl;
4724
4725 #ifdef __cplusplus
4726 inline wuffs_base__status set_interleaved(
4727 const wuffs_base__pixel_config* pixcfg,
4728 wuffs_base__table_u8 primary_memory,
4729 wuffs_base__slice_u8 palette_memory);
4730 inline wuffs_base__status set_from_slice(
4731 const wuffs_base__pixel_config* pixcfg,
4732 wuffs_base__slice_u8 pixbuf_memory);
4733 inline wuffs_base__status set_from_table(
4734 const wuffs_base__pixel_config* pixcfg,
4735 wuffs_base__table_u8 primary_memory);
4736 inline wuffs_base__slice_u8 palette();
4737 inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
4738 inline wuffs_base__pixel_format pixel_format() const;
4739 inline wuffs_base__table_u8 plane(uint32_t p);
4740 inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,
4741 uint32_t y) const;
4742 inline wuffs_base__status set_color_u32_at(
4743 uint32_t x,
4744 uint32_t y,
4745 wuffs_base__color_u32_argb_premul color);
4746 inline wuffs_base__status set_color_u32_fill_rect(
4747 wuffs_base__rect_ie_u32 rect,
4748 wuffs_base__color_u32_argb_premul color);
4749 #endif // __cplusplus
4750
4751 } wuffs_base__pixel_buffer;
4752
4753 static inline wuffs_base__pixel_buffer //
wuffs_base__null_pixel_buffer()4754 wuffs_base__null_pixel_buffer() {
4755 wuffs_base__pixel_buffer ret;
4756 ret.pixcfg = wuffs_base__null_pixel_config();
4757 ret.private_impl.planes[0] = wuffs_base__empty_table_u8();
4758 ret.private_impl.planes[1] = wuffs_base__empty_table_u8();
4759 ret.private_impl.planes[2] = wuffs_base__empty_table_u8();
4760 ret.private_impl.planes[3] = wuffs_base__empty_table_u8();
4761 return ret;
4762 }
4763
4764 static inline wuffs_base__status //
wuffs_base__pixel_buffer__set_interleaved(wuffs_base__pixel_buffer * pb,const wuffs_base__pixel_config * pixcfg,wuffs_base__table_u8 primary_memory,wuffs_base__slice_u8 palette_memory)4765 wuffs_base__pixel_buffer__set_interleaved(
4766 wuffs_base__pixel_buffer* pb,
4767 const wuffs_base__pixel_config* pixcfg,
4768 wuffs_base__table_u8 primary_memory,
4769 wuffs_base__slice_u8 palette_memory) {
4770 if (!pb) {
4771 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4772 }
4773 memset(pb, 0, sizeof(*pb));
4774 if (!pixcfg ||
4775 wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4776 return wuffs_base__make_status(wuffs_base__error__bad_argument);
4777 }
4778 if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
4779 (palette_memory.len <
4780 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
4781 return wuffs_base__make_status(
4782 wuffs_base__error__bad_argument_length_too_short);
4783 }
4784 uint32_t bits_per_pixel =
4785 wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4786 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4787 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4788 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4789 }
4790 uint64_t bytes_per_pixel = bits_per_pixel / 8;
4791
4792 uint64_t width_in_bytes =
4793 ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
4794 if ((width_in_bytes > primary_memory.width) ||
4795 (pixcfg->private_impl.height > primary_memory.height)) {
4796 return wuffs_base__make_status(wuffs_base__error__bad_argument);
4797 }
4798
4799 pb->pixcfg = *pixcfg;
4800 pb->private_impl.planes[0] = primary_memory;
4801 if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
4802 wuffs_base__table_u8* tab =
4803 &pb->private_impl
4804 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4805 tab->ptr = palette_memory.ptr;
4806 tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4807 tab->height = 1;
4808 tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4809 }
4810 return wuffs_base__make_status(NULL);
4811 }
4812
4813 static inline wuffs_base__status //
wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer * pb,const wuffs_base__pixel_config * pixcfg,wuffs_base__slice_u8 pixbuf_memory)4814 wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
4815 const wuffs_base__pixel_config* pixcfg,
4816 wuffs_base__slice_u8 pixbuf_memory) {
4817 if (!pb) {
4818 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4819 }
4820 memset(pb, 0, sizeof(*pb));
4821 if (!pixcfg) {
4822 return wuffs_base__make_status(wuffs_base__error__bad_argument);
4823 }
4824 if (wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4825 // TODO: support planar pixel formats, concious of pixel subsampling.
4826 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4827 }
4828 uint32_t bits_per_pixel =
4829 wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4830 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4831 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4832 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4833 }
4834 uint64_t bytes_per_pixel = bits_per_pixel / 8;
4835
4836 uint8_t* ptr = pixbuf_memory.ptr;
4837 uint64_t len = pixbuf_memory.len;
4838 if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
4839 // Split a WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte
4840 // chunk (1024 bytes = 256 palette entries × 4 bytes per entry) from the
4841 // start of pixbuf_memory. We split from the start, not the end, so that
4842 // the both chunks' pointers have the same alignment as the original
4843 // pointer, up to an alignment of 1024.
4844 if (len < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
4845 return wuffs_base__make_status(
4846 wuffs_base__error__bad_argument_length_too_short);
4847 }
4848 wuffs_base__table_u8* tab =
4849 &pb->private_impl
4850 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4851 tab->ptr = ptr;
4852 tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4853 tab->height = 1;
4854 tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4855 ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4856 len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
4857 }
4858
4859 uint64_t wh = ((uint64_t)pixcfg->private_impl.width) *
4860 ((uint64_t)pixcfg->private_impl.height);
4861 size_t width = (size_t)(pixcfg->private_impl.width);
4862 if ((wh > (UINT64_MAX / bytes_per_pixel)) ||
4863 (width > (SIZE_MAX / bytes_per_pixel))) {
4864 return wuffs_base__make_status(wuffs_base__error__bad_argument);
4865 }
4866 wh *= bytes_per_pixel;
4867 width = ((size_t)(width * bytes_per_pixel));
4868 if (wh > len) {
4869 return wuffs_base__make_status(
4870 wuffs_base__error__bad_argument_length_too_short);
4871 }
4872
4873 pb->pixcfg = *pixcfg;
4874 wuffs_base__table_u8* tab = &pb->private_impl.planes[0];
4875 tab->ptr = ptr;
4876 tab->width = width;
4877 tab->height = pixcfg->private_impl.height;
4878 tab->stride = width;
4879 return wuffs_base__make_status(NULL);
4880 }
4881
4882 // Deprecated: does not handle indexed pixel configurations. Use
4883 // wuffs_base__pixel_buffer__set_interleaved instead.
4884 static inline wuffs_base__status //
wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer * pb,const wuffs_base__pixel_config * pixcfg,wuffs_base__table_u8 primary_memory)4885 wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* pb,
4886 const wuffs_base__pixel_config* pixcfg,
4887 wuffs_base__table_u8 primary_memory) {
4888 if (!pb) {
4889 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
4890 }
4891 memset(pb, 0, sizeof(*pb));
4892 if (!pixcfg ||
4893 wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) ||
4894 wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
4895 return wuffs_base__make_status(wuffs_base__error__bad_argument);
4896 }
4897 uint32_t bits_per_pixel =
4898 wuffs_base__pixel_format__bits_per_pixel(&pixcfg->private_impl.pixfmt);
4899 if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) {
4900 // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel?
4901 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
4902 }
4903 uint64_t bytes_per_pixel = bits_per_pixel / 8;
4904
4905 uint64_t width_in_bytes =
4906 ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel;
4907 if ((width_in_bytes > primary_memory.width) ||
4908 (pixcfg->private_impl.height > primary_memory.height)) {
4909 return wuffs_base__make_status(wuffs_base__error__bad_argument);
4910 }
4911
4912 pb->pixcfg = *pixcfg;
4913 pb->private_impl.planes[0] = primary_memory;
4914 return wuffs_base__make_status(NULL);
4915 }
4916
4917 // wuffs_base__pixel_buffer__palette returns the palette color data. If
4918 // non-empty, it will have length
4919 // WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH.
4920 static inline wuffs_base__slice_u8 //
wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer * pb)4921 wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {
4922 if (pb &&
4923 wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
4924 wuffs_base__table_u8* tab =
4925 &pb->private_impl
4926 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4927 if ((tab->width ==
4928 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
4929 (tab->height == 1)) {
4930 return wuffs_base__make_slice_u8(
4931 tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
4932 }
4933 }
4934 return wuffs_base__make_slice_u8(NULL, 0);
4935 }
4936
4937 static inline wuffs_base__slice_u8 //
wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer * pb,wuffs_base__slice_u8 fallback)4938 wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer* pb,
4939 wuffs_base__slice_u8 fallback) {
4940 if (pb &&
4941 wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
4942 wuffs_base__table_u8* tab =
4943 &pb->private_impl
4944 .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
4945 if ((tab->width ==
4946 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
4947 (tab->height == 1)) {
4948 return wuffs_base__make_slice_u8(
4949 tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
4950 }
4951 }
4952 return fallback;
4953 }
4954
4955 static inline wuffs_base__pixel_format //
wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer * pb)4956 wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {
4957 if (pb) {
4958 return pb->pixcfg.private_impl.pixfmt;
4959 }
4960 return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);
4961 }
4962
4963 static inline wuffs_base__table_u8 //
wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer * pb,uint32_t p)4964 wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {
4965 if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) {
4966 return pb->private_impl.planes[p];
4967 }
4968
4969 wuffs_base__table_u8 ret;
4970 ret.ptr = NULL;
4971 ret.width = 0;
4972 ret.height = 0;
4973 ret.stride = 0;
4974 return ret;
4975 }
4976
4977 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
4978 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
4979 uint32_t x,
4980 uint32_t y);
4981
4982 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
4983 wuffs_base__pixel_buffer__set_color_u32_at(
4984 wuffs_base__pixel_buffer* pb,
4985 uint32_t x,
4986 uint32_t y,
4987 wuffs_base__color_u32_argb_premul color);
4988
4989 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
4990 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
4991 wuffs_base__pixel_buffer* pb,
4992 wuffs_base__rect_ie_u32 rect,
4993 wuffs_base__color_u32_argb_premul color);
4994
4995 #ifdef __cplusplus
4996
4997 inline wuffs_base__status //
set_interleaved(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__table_u8 primary_memory,wuffs_base__slice_u8 palette_memory)4998 wuffs_base__pixel_buffer::set_interleaved(
4999 const wuffs_base__pixel_config* pixcfg_arg,
5000 wuffs_base__table_u8 primary_memory,
5001 wuffs_base__slice_u8 palette_memory) {
5002 return wuffs_base__pixel_buffer__set_interleaved(
5003 this, pixcfg_arg, primary_memory, palette_memory);
5004 }
5005
5006 inline wuffs_base__status //
set_from_slice(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__slice_u8 pixbuf_memory)5007 wuffs_base__pixel_buffer::set_from_slice(
5008 const wuffs_base__pixel_config* pixcfg_arg,
5009 wuffs_base__slice_u8 pixbuf_memory) {
5010 return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,
5011 pixbuf_memory);
5012 }
5013
5014 inline wuffs_base__status //
set_from_table(const wuffs_base__pixel_config * pixcfg_arg,wuffs_base__table_u8 primary_memory)5015 wuffs_base__pixel_buffer::set_from_table(
5016 const wuffs_base__pixel_config* pixcfg_arg,
5017 wuffs_base__table_u8 primary_memory) {
5018 return wuffs_base__pixel_buffer__set_from_table(this, pixcfg_arg,
5019 primary_memory);
5020 }
5021
5022 inline wuffs_base__slice_u8 //
palette()5023 wuffs_base__pixel_buffer::palette() {
5024 return wuffs_base__pixel_buffer__palette(this);
5025 }
5026
5027 inline wuffs_base__slice_u8 //
palette_or_else(wuffs_base__slice_u8 fallback)5028 wuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {
5029 return wuffs_base__pixel_buffer__palette_or_else(this, fallback);
5030 }
5031
5032 inline wuffs_base__pixel_format //
pixel_format()5033 wuffs_base__pixel_buffer::pixel_format() const {
5034 return wuffs_base__pixel_buffer__pixel_format(this);
5035 }
5036
5037 inline wuffs_base__table_u8 //
plane(uint32_t p)5038 wuffs_base__pixel_buffer::plane(uint32_t p) {
5039 return wuffs_base__pixel_buffer__plane(this, p);
5040 }
5041
5042 inline wuffs_base__color_u32_argb_premul //
color_u32_at(uint32_t x,uint32_t y)5043 wuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {
5044 return wuffs_base__pixel_buffer__color_u32_at(this, x, y);
5045 }
5046
5047 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
5048 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
5049 wuffs_base__pixel_buffer* pb,
5050 wuffs_base__rect_ie_u32 rect,
5051 wuffs_base__color_u32_argb_premul color);
5052
5053 inline wuffs_base__status //
set_color_u32_at(uint32_t x,uint32_t y,wuffs_base__color_u32_argb_premul color)5054 wuffs_base__pixel_buffer::set_color_u32_at(
5055 uint32_t x,
5056 uint32_t y,
5057 wuffs_base__color_u32_argb_premul color) {
5058 return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);
5059 }
5060
5061 inline wuffs_base__status //
set_color_u32_fill_rect(wuffs_base__rect_ie_u32 rect,wuffs_base__color_u32_argb_premul color)5062 wuffs_base__pixel_buffer::set_color_u32_fill_rect(
5063 wuffs_base__rect_ie_u32 rect,
5064 wuffs_base__color_u32_argb_premul color) {
5065 return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);
5066 }
5067
5068 #endif // __cplusplus
5069
5070 // --------
5071
5072 typedef struct wuffs_base__decode_frame_options__struct {
5073 // Do not access the private_impl's fields directly. There is no API/ABI
5074 // compatibility or safety guarantee if you do so.
5075 struct {
5076 uint8_t TODO;
5077 } private_impl;
5078
5079 #ifdef __cplusplus
5080 #endif // __cplusplus
5081
5082 } wuffs_base__decode_frame_options;
5083
5084 #ifdef __cplusplus
5085
5086 #endif // __cplusplus
5087
5088 // --------
5089
5090 // wuffs_base__pixel_palette__closest_element returns the index of the palette
5091 // element that minimizes the sum of squared differences of the four ARGB
5092 // channels, working in premultiplied alpha. Ties favor the smaller index.
5093 //
5094 // The palette_slice.len may equal (N*4), for N less than 256, which means that
5095 // only the first N palette elements are considered. It returns 0 when N is 0.
5096 //
5097 // Applying this function on a per-pixel basis will not produce whole-of-image
5098 // dithering.
5099 WUFFS_BASE__MAYBE_STATIC uint8_t //
5100 wuffs_base__pixel_palette__closest_element(
5101 wuffs_base__slice_u8 palette_slice,
5102 wuffs_base__pixel_format palette_format,
5103 wuffs_base__color_u32_argb_premul c);
5104
5105 // --------
5106
5107 // TODO: should the func type take restrict pointers?
5108 typedef uint64_t (*wuffs_base__pixel_swizzler__func)(uint8_t* dst_ptr,
5109 size_t dst_len,
5110 uint8_t* dst_palette_ptr,
5111 size_t dst_palette_len,
5112 const uint8_t* src_ptr,
5113 size_t src_len);
5114
5115 typedef uint64_t (*wuffs_base__pixel_swizzler__transparent_black_func)(
5116 uint8_t* dst_ptr,
5117 size_t dst_len,
5118 uint8_t* dst_palette_ptr,
5119 size_t dst_palette_len,
5120 uint64_t num_pixels,
5121 uint32_t dst_pixfmt_bytes_per_pixel);
5122
5123 typedef struct wuffs_base__pixel_swizzler__struct {
5124 // Do not access the private_impl's fields directly. There is no API/ABI
5125 // compatibility or safety guarantee if you do so.
5126 struct {
5127 wuffs_base__pixel_swizzler__func func;
5128 wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func;
5129 uint32_t dst_pixfmt_bytes_per_pixel;
5130 uint32_t src_pixfmt_bytes_per_pixel;
5131 } private_impl;
5132
5133 #ifdef __cplusplus
5134 inline wuffs_base__status prepare(wuffs_base__pixel_format dst_pixfmt,
5135 wuffs_base__slice_u8 dst_palette,
5136 wuffs_base__pixel_format src_pixfmt,
5137 wuffs_base__slice_u8 src_palette,
5138 wuffs_base__pixel_blend blend);
5139 inline uint64_t swizzle_interleaved_from_slice(
5140 wuffs_base__slice_u8 dst,
5141 wuffs_base__slice_u8 dst_palette,
5142 wuffs_base__slice_u8 src) const;
5143 #endif // __cplusplus
5144
5145 } wuffs_base__pixel_swizzler;
5146
5147 // wuffs_base__pixel_swizzler__prepare readies the pixel swizzler so that its
5148 // other methods may be called.
5149 //
5150 // For modular builds that divide the base module into sub-modules, using this
5151 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5152 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5153 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
5154 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
5155 wuffs_base__pixel_format dst_pixfmt,
5156 wuffs_base__slice_u8 dst_palette,
5157 wuffs_base__pixel_format src_pixfmt,
5158 wuffs_base__slice_u8 src_palette,
5159 wuffs_base__pixel_blend blend);
5160
5161 // wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice converts pixels
5162 // from a source format to a destination format.
5163 //
5164 // For modular builds that divide the base module into sub-modules, using this
5165 // function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
5166 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5167 WUFFS_BASE__MAYBE_STATIC uint64_t //
5168 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5169 const wuffs_base__pixel_swizzler* p,
5170 wuffs_base__slice_u8 dst,
5171 wuffs_base__slice_u8 dst_palette,
5172 wuffs_base__slice_u8 src);
5173
5174 #ifdef __cplusplus
5175
5176 inline wuffs_base__status //
prepare(wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__pixel_format src_pixfmt,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)5177 wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_pixfmt,
5178 wuffs_base__slice_u8 dst_palette,
5179 wuffs_base__pixel_format src_pixfmt,
5180 wuffs_base__slice_u8 src_palette,
5181 wuffs_base__pixel_blend blend) {
5182 return wuffs_base__pixel_swizzler__prepare(this, dst_pixfmt, dst_palette,
5183 src_pixfmt, src_palette, blend);
5184 }
5185
5186 uint64_t //
swizzle_interleaved_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)5187 wuffs_base__pixel_swizzler::swizzle_interleaved_from_slice(
5188 wuffs_base__slice_u8 dst,
5189 wuffs_base__slice_u8 dst_palette,
5190 wuffs_base__slice_u8 src) const {
5191 return wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
5192 this, dst, dst_palette, src);
5193 }
5194
5195 #endif // __cplusplus
5196
5197 // ---------------- String Conversions
5198
5199 // Options (bitwise or'ed together) for wuffs_base__parse_number_xxx
5200 // functions. The XXX options apply to both integer and floating point. The FXX
5201 // options apply only to floating point.
5202
5203 #define WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5204
5205 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES means to accept
5206 // inputs like "00", "0644" and "00.7". By default, they are rejected.
5207 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES \
5208 ((uint32_t)0x00000001)
5209
5210 // WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES means to accept inputs like
5211 // "1__2" and "_3.141_592". By default, they are rejected.
5212 #define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES ((uint32_t)0x00000002)
5213
5214 // WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to accept
5215 // "1,5" and not "1.5" as one-and-a-half.
5216 //
5217 // If the caller wants to accept either, it is responsible for canonicalizing
5218 // the input before calling wuffs_base__parse_number_fxx. The caller also has
5219 // more context on e.g. exactly how to treat something like "$1,234".
5220 #define WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5221 ((uint32_t)0x00000010)
5222
5223 // WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN means to reject inputs that
5224 // would lead to infinite or Not-a-Number floating point values. By default,
5225 // they are accepted.
5226 //
5227 // This affects the literal "inf" as input, but also affects inputs like
5228 // "1e999" that would overflow double-precision floating point.
5229 #define WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN ((uint32_t)0x00000020)
5230
5231 // --------
5232
5233 // Options (bitwise or'ed together) for wuffs_base__render_number_xxx
5234 // functions. The XXX options apply to both integer and floating point. The FXX
5235 // options apply only to floating point.
5236
5237 #define WUFFS_BASE__RENDER_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5238
5239 // WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT means to render to the right side
5240 // (higher indexes) of the destination slice, leaving any untouched bytes on
5241 // the left side (lower indexes). The default is vice versa: rendering on the
5242 // left with slack on the right.
5243 #define WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT ((uint32_t)0x00000100)
5244
5245 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN means to render the leading
5246 // "+" for non-negative numbers: "+0" and "+12.3" instead of "0" and "12.3".
5247 #define WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN ((uint32_t)0x00000200)
5248
5249 // WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to render
5250 // one-and-a-half as "1,5" instead of "1.5".
5251 #define WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
5252 ((uint32_t)0x00001000)
5253
5254 // WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ETC means whether to never
5255 // (EXPONENT_ABSENT, equivalent to printf's "%f") or to always
5256 // (EXPONENT_PRESENT, equivalent to printf's "%e") render a floating point
5257 // number as "1.23e+05" instead of "123000".
5258 //
5259 // Having both bits set is the same has having neither bit set, where the
5260 // notation used depends on whether the exponent is sufficiently large: "0.5"
5261 // is preferred over "5e-01" but "5e-09" is preferred over "0.000000005".
5262 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT ((uint32_t)0x00002000)
5263 #define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT ((uint32_t)0x00004000)
5264
5265 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION means to render the
5266 // smallest number of digits so that parsing the resultant string will recover
5267 // the same double-precision floating point number.
5268 //
5269 // For example, double-precision cannot distinguish between 0.3 and
5270 // 0.299999999999999988897769753748434595763683319091796875, so when this bit
5271 // is set, rendering the latter will produce "0.3" but rendering
5272 // 0.3000000000000000444089209850062616169452667236328125 will produce
5273 // "0.30000000000000004".
5274 #define WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION \
5275 ((uint32_t)0x00008000)
5276
5277 // ---------------- IEEE 754 Floating Point
5278
5279 // wuffs_base__ieee_754_bit_representation__etc converts between a double
5280 // precision numerical value and its IEEE 754 representations:
5281 // - 16-bit: 1 sign bit, 5 exponent bits, 10 explicit significand bits.
5282 // - 32-bit: 1 sign bit, 8 exponent bits, 23 explicit significand bits.
5283 // - 64-bit: 1 sign bit, 11 exponent bits, 52 explicit significand bits.
5284 //
5285 // For example, it converts between:
5286 // - +1.0 and 0x3C00, 0x3F80_0000 or 0x3FF0_0000_0000_0000.
5287 // - +5.5 and 0x4580, 0x40B0_0000 or 0x4016_0000_0000_0000.
5288 // - -inf and 0xFC00, 0xFF80_0000 or 0xFFF0_0000_0000_0000.
5289 //
5290 // Converting from f64 to shorter formats (f16 or f32, represented in C as
5291 // uint16_t and uint32_t) may be lossy. Such functions have names that look
5292 // like etc_truncate, as converting finite numbers produce equal or smaller
5293 // (closer-to-zero) finite numbers. For example, 1048576.0 is a perfectly valid
5294 // f64 number, but converting it to a f16 (with truncation) produces 65504.0,
5295 // the largest finite f16 number. Truncating a f64-typed value d to f32 does
5296 // not always produce the same result as the C-style cast ((float)d), as
5297 // casting can convert from finite numbers to infinite ones.
5298 //
5299 // Converting infinities or NaNs produces infinities or NaNs and always report
5300 // no loss, even though there a multiple NaN representations so that round-
5301 // tripping a f64-typed NaN may produce a different 64 bits. Nonetheless, the
5302 // etc_truncate functions preserve a NaN's "quiet vs signaling" bit.
5303 //
5304 // See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
5305
5306 typedef struct wuffs_base__lossy_value_u16__struct {
5307 uint16_t value;
5308 bool lossy;
5309 } wuffs_base__lossy_value_u16;
5310
5311 typedef struct wuffs_base__lossy_value_u32__struct {
5312 uint32_t value;
5313 bool lossy;
5314 } wuffs_base__lossy_value_u32;
5315
5316 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 //
5317 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f);
5318
5319 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 //
5320 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f);
5321
5322 static inline uint64_t //
wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f)5323 wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f) {
5324 uint64_t u = 0;
5325 if (sizeof(uint64_t) == sizeof(double)) {
5326 memcpy(&u, &f, sizeof(uint64_t));
5327 }
5328 return u;
5329 }
5330
5331 static inline double //
wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u)5332 wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u) {
5333 uint64_t v = ((uint64_t)(u & 0x8000)) << 48;
5334
5335 do {
5336 uint64_t exp = (u >> 10) & 0x1F;
5337 uint64_t man = u & 0x3FF;
5338 if (exp == 0x1F) { // Infinity or NaN.
5339 exp = 2047;
5340 } else if (exp != 0) { // Normal.
5341 exp += 1008; // 1008 = 1023 - 15, the difference in biases.
5342 } else if (man != 0) { // Subnormal but non-zero.
5343 uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
5344 exp = 1062 - clz; // 1062 = 1008 + 64 - 10.
5345 man = 0x3FF & (man << (clz - 53));
5346 } else { // Zero.
5347 break;
5348 }
5349 v |= (exp << 52) | (man << 42);
5350 } while (0);
5351
5352 double f = 0;
5353 if (sizeof(uint64_t) == sizeof(double)) {
5354 memcpy(&f, &v, sizeof(uint64_t));
5355 }
5356 return f;
5357 }
5358
5359 static inline double //
wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u)5360 wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u) {
5361 float f = 0;
5362 if (sizeof(uint32_t) == sizeof(float)) {
5363 memcpy(&f, &u, sizeof(uint32_t));
5364 }
5365 return (double)f;
5366 }
5367
5368 static inline double //
wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u)5369 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u) {
5370 double f = 0;
5371 if (sizeof(uint64_t) == sizeof(double)) {
5372 memcpy(&f, &u, sizeof(uint64_t));
5373 }
5374 return f;
5375 }
5376
5377 // ---------------- Parsing and Rendering Numbers
5378
5379 // wuffs_base__parse_number_f64 parses the floating point number in s. For
5380 // example, if s contains the bytes "1.5" then it will return the double 1.5.
5381 //
5382 // It returns an error if s does not contain a floating point number.
5383 //
5384 // It does not necessarily return an error if the conversion is lossy, e.g. if
5385 // s is "0.3", which double-precision floating point cannot represent exactly.
5386 //
5387 // Similarly, the returned value may be infinite (and no error returned) even
5388 // if s was not "inf", when the input is nominally finite but sufficiently
5389 // larger than DBL_MAX, about 1.8e+308.
5390 //
5391 // It is similar to the C standard library's strtod function, but:
5392 // - Errors are returned in-band (in a result type), not out-of-band (errno).
5393 // - It takes a slice (a pointer and length), not a NUL-terminated C string.
5394 // - It does not take an optional endptr argument. It does not allow a partial
5395 // parse: it returns an error unless all of s is consumed.
5396 // - It does not allow whitespace, leading or otherwise.
5397 // - It does not allow hexadecimal floating point numbers.
5398 // - It is not affected by i18n / l10n settings such as environment variables.
5399 //
5400 // The options argument can change these, but by default, it:
5401 // - Allows "inf", "+Infinity" and "-NAN", case insensitive. Similarly,
5402 // without an explicit opt-out, it would successfully parse "1e999" as
5403 // infinity, even though it overflows double-precision floating point.
5404 // - Rejects underscores. With an explicit opt-in, "_3.141_592" would
5405 // successfully parse as an approximation to π.
5406 // - Rejects unnecessary leading zeroes: "00", "0644" and "00.7".
5407 // - Uses a dot '1.5' instead of a comma '1,5' for the decimal separator.
5408 //
5409 // For modular builds that divide the base module into sub-modules, using this
5410 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5411 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5412 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
5413 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options);
5414
5415 // wuffs_base__parse_number_i64 parses the ASCII integer in s. For example, if
5416 // s contains the bytes "-123" then it will return the int64_t -123.
5417 //
5418 // It returns an error if s does not contain an integer or if the integer
5419 // within would overflow an int64_t.
5420 //
5421 // It is similar to wuffs_base__parse_number_u64 but it returns a signed
5422 // integer, not an unsigned integer. It also allows a leading '+' or '-'.
5423 //
5424 // For modular builds that divide the base module into sub-modules, using this
5425 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5426 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5427 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
5428 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options);
5429
5430 // wuffs_base__parse_number_u64 parses the ASCII integer in s. For example, if
5431 // s contains the bytes "123" then it will return the uint64_t 123.
5432 //
5433 // It returns an error if s does not contain an integer or if the integer
5434 // within would overflow a uint64_t.
5435 //
5436 // It is similar to the C standard library's strtoull function, but:
5437 // - Errors are returned in-band (in a result type), not out-of-band (errno).
5438 // - It takes a slice (a pointer and length), not a NUL-terminated C string.
5439 // - It does not take an optional endptr argument. It does not allow a partial
5440 // parse: it returns an error unless all of s is consumed.
5441 // - It does not allow whitespace, leading or otherwise.
5442 // - It does not allow a leading '+' or '-'.
5443 // - It does not take a base argument (e.g. base 10 vs base 16). Instead, it
5444 // always accepts both decimal (e.g "1234", "0d5678") and hexadecimal (e.g.
5445 // "0x9aBC"). The caller is responsible for prior filtering of e.g. hex
5446 // numbers if they are unwanted. For example, Wuffs' JSON decoder will only
5447 // produce a wuffs_base__token for decimal numbers, not hexadecimal.
5448 // - It is not affected by i18n / l10n settings such as environment variables.
5449 //
5450 // The options argument can change these, but by default, it:
5451 // - Rejects underscores. With an explicit opt-in, "__0D_1_002" would
5452 // successfully parse as "one thousand and two". Underscores are still
5453 // rejected inside the optional 2-byte opening "0d" or "0X" that denotes
5454 // base-10 or base-16.
5455 // - Rejects unnecessary leading zeroes: "00" and "0644".
5456 //
5457 // For modular builds that divide the base module into sub-modules, using this
5458 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5459 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5460 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
5461 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options);
5462
5463 // --------
5464
5465 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL is the string length of
5466 // "-9223372036854775808" and "+9223372036854775807", INT64_MIN and INT64_MAX.
5467 #define WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL 20
5468
5469 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL is the string length of
5470 // "+18446744073709551615", UINT64_MAX.
5471 #define WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL 21
5472
5473 // wuffs_base__render_number_f64 writes the decimal encoding of x to dst and
5474 // returns the number of bytes written. If dst is shorter than the entire
5475 // encoding, it returns 0 (and no bytes are written).
5476 //
5477 // For those familiar with C's printf or Go's fmt.Printf functions:
5478 // - "%e" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT option.
5479 // - "%f" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT option.
5480 // - "%g" means neither or both bits are set.
5481 //
5482 // The precision argument controls the number of digits rendered, excluding the
5483 // exponent (the "e+05" in "1.23e+05"):
5484 // - for "%e" and "%f" it is the number of digits after the decimal separator,
5485 // - for "%g" it is the number of significant digits (and trailing zeroes are
5486 // removed).
5487 //
5488 // A precision of 6 gives similar output to printf's defaults.
5489 //
5490 // A precision greater than 4095 is equivalent to 4095.
5491 //
5492 // The precision argument is ignored when the
5493 // WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION option is set. This is
5494 // similar to Go's strconv.FormatFloat with a negative (i.e. non-sensical)
5495 // precision, but there is no corresponding feature in C's printf.
5496 //
5497 // Extreme values of x will be rendered as "NaN", "Inf" (or "+Inf" if the
5498 // WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN option is set) or "-Inf".
5499 //
5500 // For modular builds that divide the base module into sub-modules, using this
5501 // function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
5502 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5503 WUFFS_BASE__MAYBE_STATIC size_t //
5504 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
5505 double x,
5506 uint32_t precision,
5507 uint32_t options);
5508
5509 // wuffs_base__render_number_i64 writes the decimal encoding of x to dst and
5510 // returns the number of bytes written. If dst is shorter than the entire
5511 // encoding, it returns 0 (and no bytes are written).
5512 //
5513 // dst will never be too short if its length is at least 20, also known as
5514 // WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL.
5515 //
5516 // For modular builds that divide the base module into sub-modules, using this
5517 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5518 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5519 WUFFS_BASE__MAYBE_STATIC size_t //
5520 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
5521 int64_t x,
5522 uint32_t options);
5523
5524 // wuffs_base__render_number_u64 writes the decimal encoding of x to dst and
5525 // returns the number of bytes written. If dst is shorter than the entire
5526 // encoding, it returns 0 (and no bytes are written).
5527 //
5528 // dst will never be too short if its length is at least 21, also known as
5529 // WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL.
5530 //
5531 // For modular builds that divide the base module into sub-modules, using this
5532 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5533 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5534 WUFFS_BASE__MAYBE_STATIC size_t //
5535 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
5536 uint64_t x,
5537 uint32_t options);
5538
5539 // ---------------- Base-16
5540
5541 // Options (bitwise or'ed together) for wuffs_base__base_16__xxx functions.
5542
5543 #define WUFFS_BASE__BASE_16__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5544
5545 // wuffs_base__base_16__decode2 converts "6A6b" to "jk", where e.g. 'j' is
5546 // U+006A. There are 2 src bytes for every dst byte.
5547 //
5548 // It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
5549 // repeated. It may write nonsense bytes if not, although it will not read or
5550 // write out of bounds.
5551 //
5552 // For modular builds that divide the base module into sub-modules, using this
5553 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5554 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5555 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
5556 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
5557 wuffs_base__slice_u8 src,
5558 bool src_closed,
5559 uint32_t options);
5560
5561 // wuffs_base__base_16__decode4 converts both "\\x6A\\x6b" and "??6a??6B" to
5562 // "jk", where e.g. 'j' is U+006A. There are 4 src bytes for every dst byte.
5563 //
5564 // It assumes that the src bytes are two ignored bytes and then two hexadecimal
5565 // digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
5566 // although it will not read or write out of bounds.
5567 //
5568 // For modular builds that divide the base module into sub-modules, using this
5569 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5570 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5571 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
5572 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
5573 wuffs_base__slice_u8 src,
5574 bool src_closed,
5575 uint32_t options);
5576
5577 // wuffs_base__base_16__encode2 converts "jk" to "6A6B", where e.g. 'j' is
5578 // U+006A. There are 2 dst bytes for every src byte.
5579 //
5580 // For modular builds that divide the base module into sub-modules, using this
5581 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5582 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5583 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
5584 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
5585 wuffs_base__slice_u8 src,
5586 bool src_closed,
5587 uint32_t options);
5588
5589 // wuffs_base__base_16__encode4 converts "jk" to "\\x6A\\x6B", where e.g. 'j'
5590 // is U+006A. There are 4 dst bytes for every src byte.
5591 //
5592 // For modular builds that divide the base module into sub-modules, using this
5593 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5594 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5595 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
5596 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
5597 wuffs_base__slice_u8 src,
5598 bool src_closed,
5599 uint32_t options);
5600
5601 // ---------------- Base-64
5602
5603 // Options (bitwise or'ed together) for wuffs_base__base_64__xxx functions.
5604
5605 #define WUFFS_BASE__BASE_64__DEFAULT_OPTIONS ((uint32_t)0x00000000)
5606
5607 // WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING means that, when decoding base-64,
5608 // the input may (but does not need to) be padded with '=' bytes so that the
5609 // overall encoded length in bytes is a multiple of 4. A successful decoding
5610 // will return a num_src that includes those padding bytes.
5611 //
5612 // Excess padding (e.g. three final '='s) will be rejected as bad data.
5613 #define WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING ((uint32_t)0x00000001)
5614
5615 // WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING means that, when encoding base-64,
5616 // the output will be padded with '=' bytes so that the overall encoded length
5617 // in bytes is a multiple of 4.
5618 #define WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING ((uint32_t)0x00000002)
5619
5620 // WUFFS_BASE__BASE_64__URL_ALPHABET means that, for base-64, the URL-friendly
5621 // and file-name-friendly alphabet be used, as per RFC 4648 section 5. When
5622 // this option bit is off, the standard alphabet from section 4 is used.
5623 #define WUFFS_BASE__BASE_64__URL_ALPHABET ((uint32_t)0x00000100)
5624
5625 // wuffs_base__base_64__decode transforms base-64 encoded bytes from src to
5626 // arbitrary bytes in dst.
5627 //
5628 // It will not permit line breaks or other whitespace in src. Filtering those
5629 // out is the responsibility of the caller.
5630 //
5631 // For modular builds that divide the base module into sub-modules, using this
5632 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5633 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5634 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
5635 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
5636 wuffs_base__slice_u8 src,
5637 bool src_closed,
5638 uint32_t options);
5639
5640 // wuffs_base__base_64__encode transforms arbitrary bytes from src to base-64
5641 // encoded bytes in dst.
5642 //
5643 // For modular builds that divide the base module into sub-modules, using this
5644 // function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
5645 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5646 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
5647 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
5648 wuffs_base__slice_u8 src,
5649 bool src_closed,
5650 uint32_t options);
5651
5652 // ---------------- Unicode and UTF-8
5653
5654 #define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
5655 #define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
5656
5657 #define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD
5658
5659 #define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800
5660 #define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF
5661
5662 #define WUFFS_BASE__ASCII__MIN_INCL 0x00
5663 #define WUFFS_BASE__ASCII__MAX_INCL 0x7F
5664
5665 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1
5666 #define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4
5667
5668 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000
5669 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F
5670 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080
5671 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF
5672 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800
5673 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF
5674 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MIN_INCL 0x00010000
5675 #define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF
5676
5677 // --------
5678
5679 // wuffs_base__utf_8__next__output is the type returned by
5680 // wuffs_base__utf_8__next.
5681 typedef struct wuffs_base__utf_8__next__output__struct {
5682 uint32_t code_point;
5683 uint32_t byte_length;
5684
5685 #ifdef __cplusplus
5686 inline bool is_valid() const;
5687 #endif // __cplusplus
5688
5689 } wuffs_base__utf_8__next__output;
5690
5691 static inline wuffs_base__utf_8__next__output //
wuffs_base__make_utf_8__next__output(uint32_t code_point,uint32_t byte_length)5692 wuffs_base__make_utf_8__next__output(uint32_t code_point,
5693 uint32_t byte_length) {
5694 wuffs_base__utf_8__next__output ret;
5695 ret.code_point = code_point;
5696 ret.byte_length = byte_length;
5697 return ret;
5698 }
5699
5700 static inline bool //
wuffs_base__utf_8__next__output__is_valid(const wuffs_base__utf_8__next__output * o)5701 wuffs_base__utf_8__next__output__is_valid(
5702 const wuffs_base__utf_8__next__output* o) {
5703 if (o) {
5704 uint32_t cp = o->code_point;
5705 switch (o->byte_length) {
5706 case 1:
5707 return (cp <= 0x7F);
5708 case 2:
5709 return (0x080 <= cp) && (cp <= 0x7FF);
5710 case 3:
5711 // Avoid the 0xD800 ..= 0xDFFF surrogate range.
5712 return ((0x0800 <= cp) && (cp <= 0xD7FF)) ||
5713 ((0xE000 <= cp) && (cp <= 0xFFFF));
5714 case 4:
5715 return (0x00010000 <= cp) && (cp <= 0x0010FFFF);
5716 }
5717 }
5718 return false;
5719 }
5720
5721 #ifdef __cplusplus
5722
5723 inline bool //
is_valid()5724 wuffs_base__utf_8__next__output::is_valid() const {
5725 return wuffs_base__utf_8__next__output__is_valid(this);
5726 }
5727
5728 #endif // __cplusplus
5729
5730 // --------
5731
5732 // wuffs_base__utf_8__encode writes the UTF-8 encoding of code_point to s and
5733 // returns the number of bytes written. If code_point is invalid, or if s is
5734 // shorter than the entire encoding, it returns 0 (and no bytes are written).
5735 //
5736 // s will never be too short if its length is at least 4, also known as
5737 // WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL.
5738 //
5739 // For modular builds that divide the base module into sub-modules, using this
5740 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5741 // WUFFS_CONFIG__MODULE__BASE__CORE.
5742 WUFFS_BASE__MAYBE_STATIC size_t //
5743 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point);
5744
5745 // wuffs_base__utf_8__next returns the next UTF-8 code point (and that code
5746 // point's byte length) at the start of the read-only slice (s_ptr, s_len).
5747 //
5748 // There are exactly two cases in which this function returns something where
5749 // wuffs_base__utf_8__next__output__is_valid is false:
5750 // - If s is empty then it returns {.code_point=0, .byte_length=0}.
5751 // - If s is non-empty and starts with invalid UTF-8 then it returns
5752 // {.code_point=WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, .byte_length=1}.
5753 //
5754 // Otherwise, it returns something where
5755 // wuffs_base__utf_8__next__output__is_valid is true.
5756 //
5757 // In any case, it always returns an output that satisfies both of:
5758 // - (output.code_point <= WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL).
5759 // - (output.byte_length <= s_len).
5760 //
5761 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5762 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5763 // code point, then this function may return something invalid. It is the
5764 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5765 //
5766 // For modular builds that divide the base module into sub-modules, using this
5767 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5768 // WUFFS_CONFIG__MODULE__BASE__CORE.
5769 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
5770 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len);
5771
5772 // wuffs_base__utf_8__next_from_end is like wuffs_base__utf_8__next except that
5773 // it looks at the end of (s_ptr, s_len) instead of the start.
5774 //
5775 // For modular builds that divide the base module into sub-modules, using this
5776 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5777 // WUFFS_CONFIG__MODULE__BASE__CORE.
5778 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
5779 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len);
5780
5781 // wuffs_base__utf_8__longest_valid_prefix returns the largest n such that the
5782 // sub-slice s[..n] is valid UTF-8, where s is the read-only slice (s_ptr,
5783 // s_len).
5784 //
5785 // In particular, it returns s_len if and only if all of s is valid UTF-8.
5786 //
5787 // If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
5788 // boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
5789 // code point, then this function will return less than s_len. It is the
5790 // caller's responsibility to split on or otherwise manage UTF-8 boundaries.
5791 //
5792 // For modular builds that divide the base module into sub-modules, using this
5793 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5794 // WUFFS_CONFIG__MODULE__BASE__CORE.
5795 WUFFS_BASE__MAYBE_STATIC size_t //
5796 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5797
5798 // wuffs_base__ascii__longest_valid_prefix returns the largest n such that the
5799 // sub-slice s[..n] is valid ASCII, where s is the read-only slice (s_ptr,
5800 // s_len).
5801 //
5802 // In particular, it returns s_len if and only if all of s is valid ASCII.
5803 // Equivalently, when none of the bytes in s have the 0x80 high bit set.
5804 //
5805 // For modular builds that divide the base module into sub-modules, using this
5806 // function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
5807 // WUFFS_CONFIG__MODULE__BASE__CORE.
5808 WUFFS_BASE__MAYBE_STATIC size_t //
5809 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
5810
5811 // ---------------- Interface Declarations.
5812
5813 // For modular builds that divide the base module into sub-modules, using these
5814 // functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
5815 // just WUFFS_CONFIG__MODULE__BASE__CORE.
5816
5817 // --------
5818
5819 extern const char wuffs_base__hasher_u32__vtable_name[];
5820
5821 typedef struct wuffs_base__hasher_u32__func_ptrs__struct {
5822 wuffs_base__empty_struct (*set_quirk_enabled)(
5823 void* self,
5824 uint32_t a_quirk,
5825 bool a_enabled);
5826 uint32_t (*update_u32)(
5827 void* self,
5828 wuffs_base__slice_u8 a_x);
5829 } wuffs_base__hasher_u32__func_ptrs;
5830
5831 typedef struct wuffs_base__hasher_u32__struct wuffs_base__hasher_u32;
5832
5833 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5834 wuffs_base__hasher_u32__set_quirk_enabled(
5835 wuffs_base__hasher_u32* self,
5836 uint32_t a_quirk,
5837 bool a_enabled);
5838
5839 WUFFS_BASE__MAYBE_STATIC uint32_t
5840 wuffs_base__hasher_u32__update_u32(
5841 wuffs_base__hasher_u32* self,
5842 wuffs_base__slice_u8 a_x);
5843
5844 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5845
5846 struct wuffs_base__hasher_u32__struct {
5847 struct {
5848 uint32_t magic;
5849 uint32_t active_coroutine;
5850 wuffs_base__vtable first_vtable;
5851 } private_impl;
5852
5853 #ifdef __cplusplus
5854 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
5855 using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, decltype(&free)>;
5856 #endif
5857
5858 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__hasher_u32__struct5859 set_quirk_enabled(
5860 uint32_t a_quirk,
5861 bool a_enabled) {
5862 return wuffs_base__hasher_u32__set_quirk_enabled(
5863 this, a_quirk, a_enabled);
5864 }
5865
5866 inline uint32_t
update_u32wuffs_base__hasher_u32__struct5867 update_u32(
5868 wuffs_base__slice_u8 a_x) {
5869 return wuffs_base__hasher_u32__update_u32(
5870 this, a_x);
5871 }
5872
5873 #endif // __cplusplus
5874 }; // struct wuffs_base__hasher_u32__struct
5875
5876 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5877
5878 // --------
5879
5880 extern const char wuffs_base__image_decoder__vtable_name[];
5881
5882 typedef struct wuffs_base__image_decoder__func_ptrs__struct {
5883 wuffs_base__status (*decode_frame)(
5884 void* self,
5885 wuffs_base__pixel_buffer* a_dst,
5886 wuffs_base__io_buffer* a_src,
5887 wuffs_base__pixel_blend a_blend,
5888 wuffs_base__slice_u8 a_workbuf,
5889 wuffs_base__decode_frame_options* a_opts);
5890 wuffs_base__status (*decode_frame_config)(
5891 void* self,
5892 wuffs_base__frame_config* a_dst,
5893 wuffs_base__io_buffer* a_src);
5894 wuffs_base__status (*decode_image_config)(
5895 void* self,
5896 wuffs_base__image_config* a_dst,
5897 wuffs_base__io_buffer* a_src);
5898 wuffs_base__rect_ie_u32 (*frame_dirty_rect)(
5899 const void* self);
5900 uint32_t (*num_animation_loops)(
5901 const void* self);
5902 uint64_t (*num_decoded_frame_configs)(
5903 const void* self);
5904 uint64_t (*num_decoded_frames)(
5905 const void* self);
5906 wuffs_base__status (*restart_frame)(
5907 void* self,
5908 uint64_t a_index,
5909 uint64_t a_io_position);
5910 wuffs_base__empty_struct (*set_quirk_enabled)(
5911 void* self,
5912 uint32_t a_quirk,
5913 bool a_enabled);
5914 wuffs_base__empty_struct (*set_report_metadata)(
5915 void* self,
5916 uint32_t a_fourcc,
5917 bool a_report);
5918 wuffs_base__status (*tell_me_more)(
5919 void* self,
5920 wuffs_base__io_buffer* a_dst,
5921 wuffs_base__more_information* a_minfo,
5922 wuffs_base__io_buffer* a_src);
5923 wuffs_base__range_ii_u64 (*workbuf_len)(
5924 const void* self);
5925 } wuffs_base__image_decoder__func_ptrs;
5926
5927 typedef struct wuffs_base__image_decoder__struct wuffs_base__image_decoder;
5928
5929 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5930 wuffs_base__image_decoder__decode_frame(
5931 wuffs_base__image_decoder* self,
5932 wuffs_base__pixel_buffer* a_dst,
5933 wuffs_base__io_buffer* a_src,
5934 wuffs_base__pixel_blend a_blend,
5935 wuffs_base__slice_u8 a_workbuf,
5936 wuffs_base__decode_frame_options* a_opts);
5937
5938 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5939 wuffs_base__image_decoder__decode_frame_config(
5940 wuffs_base__image_decoder* self,
5941 wuffs_base__frame_config* a_dst,
5942 wuffs_base__io_buffer* a_src);
5943
5944 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5945 wuffs_base__image_decoder__decode_image_config(
5946 wuffs_base__image_decoder* self,
5947 wuffs_base__image_config* a_dst,
5948 wuffs_base__io_buffer* a_src);
5949
5950 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
5951 wuffs_base__image_decoder__frame_dirty_rect(
5952 const wuffs_base__image_decoder* self);
5953
5954 WUFFS_BASE__MAYBE_STATIC uint32_t
5955 wuffs_base__image_decoder__num_animation_loops(
5956 const wuffs_base__image_decoder* self);
5957
5958 WUFFS_BASE__MAYBE_STATIC uint64_t
5959 wuffs_base__image_decoder__num_decoded_frame_configs(
5960 const wuffs_base__image_decoder* self);
5961
5962 WUFFS_BASE__MAYBE_STATIC uint64_t
5963 wuffs_base__image_decoder__num_decoded_frames(
5964 const wuffs_base__image_decoder* self);
5965
5966 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5967 wuffs_base__image_decoder__restart_frame(
5968 wuffs_base__image_decoder* self,
5969 uint64_t a_index,
5970 uint64_t a_io_position);
5971
5972 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5973 wuffs_base__image_decoder__set_quirk_enabled(
5974 wuffs_base__image_decoder* self,
5975 uint32_t a_quirk,
5976 bool a_enabled);
5977
5978 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
5979 wuffs_base__image_decoder__set_report_metadata(
5980 wuffs_base__image_decoder* self,
5981 uint32_t a_fourcc,
5982 bool a_report);
5983
5984 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
5985 wuffs_base__image_decoder__tell_me_more(
5986 wuffs_base__image_decoder* self,
5987 wuffs_base__io_buffer* a_dst,
5988 wuffs_base__more_information* a_minfo,
5989 wuffs_base__io_buffer* a_src);
5990
5991 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
5992 wuffs_base__image_decoder__workbuf_len(
5993 const wuffs_base__image_decoder* self);
5994
5995 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
5996
5997 struct wuffs_base__image_decoder__struct {
5998 struct {
5999 uint32_t magic;
6000 uint32_t active_coroutine;
6001 wuffs_base__vtable first_vtable;
6002 } private_impl;
6003
6004 #ifdef __cplusplus
6005 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6006 using unique_ptr = std::unique_ptr<wuffs_base__image_decoder, decltype(&free)>;
6007 #endif
6008
6009 inline wuffs_base__status
decode_framewuffs_base__image_decoder__struct6010 decode_frame(
6011 wuffs_base__pixel_buffer* a_dst,
6012 wuffs_base__io_buffer* a_src,
6013 wuffs_base__pixel_blend a_blend,
6014 wuffs_base__slice_u8 a_workbuf,
6015 wuffs_base__decode_frame_options* a_opts) {
6016 return wuffs_base__image_decoder__decode_frame(
6017 this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6018 }
6019
6020 inline wuffs_base__status
decode_frame_configwuffs_base__image_decoder__struct6021 decode_frame_config(
6022 wuffs_base__frame_config* a_dst,
6023 wuffs_base__io_buffer* a_src) {
6024 return wuffs_base__image_decoder__decode_frame_config(
6025 this, a_dst, a_src);
6026 }
6027
6028 inline wuffs_base__status
decode_image_configwuffs_base__image_decoder__struct6029 decode_image_config(
6030 wuffs_base__image_config* a_dst,
6031 wuffs_base__io_buffer* a_src) {
6032 return wuffs_base__image_decoder__decode_image_config(
6033 this, a_dst, a_src);
6034 }
6035
6036 inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_base__image_decoder__struct6037 frame_dirty_rect() const {
6038 return wuffs_base__image_decoder__frame_dirty_rect(this);
6039 }
6040
6041 inline uint32_t
num_animation_loopswuffs_base__image_decoder__struct6042 num_animation_loops() const {
6043 return wuffs_base__image_decoder__num_animation_loops(this);
6044 }
6045
6046 inline uint64_t
num_decoded_frame_configswuffs_base__image_decoder__struct6047 num_decoded_frame_configs() const {
6048 return wuffs_base__image_decoder__num_decoded_frame_configs(this);
6049 }
6050
6051 inline uint64_t
num_decoded_frameswuffs_base__image_decoder__struct6052 num_decoded_frames() const {
6053 return wuffs_base__image_decoder__num_decoded_frames(this);
6054 }
6055
6056 inline wuffs_base__status
restart_framewuffs_base__image_decoder__struct6057 restart_frame(
6058 uint64_t a_index,
6059 uint64_t a_io_position) {
6060 return wuffs_base__image_decoder__restart_frame(
6061 this, a_index, a_io_position);
6062 }
6063
6064 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__image_decoder__struct6065 set_quirk_enabled(
6066 uint32_t a_quirk,
6067 bool a_enabled) {
6068 return wuffs_base__image_decoder__set_quirk_enabled(
6069 this, a_quirk, a_enabled);
6070 }
6071
6072 inline wuffs_base__empty_struct
set_report_metadatawuffs_base__image_decoder__struct6073 set_report_metadata(
6074 uint32_t a_fourcc,
6075 bool a_report) {
6076 return wuffs_base__image_decoder__set_report_metadata(
6077 this, a_fourcc, a_report);
6078 }
6079
6080 inline wuffs_base__status
tell_me_morewuffs_base__image_decoder__struct6081 tell_me_more(
6082 wuffs_base__io_buffer* a_dst,
6083 wuffs_base__more_information* a_minfo,
6084 wuffs_base__io_buffer* a_src) {
6085 return wuffs_base__image_decoder__tell_me_more(
6086 this, a_dst, a_minfo, a_src);
6087 }
6088
6089 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__image_decoder__struct6090 workbuf_len() const {
6091 return wuffs_base__image_decoder__workbuf_len(this);
6092 }
6093
6094 #endif // __cplusplus
6095 }; // struct wuffs_base__image_decoder__struct
6096
6097 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6098
6099 // --------
6100
6101 extern const char wuffs_base__io_transformer__vtable_name[];
6102
6103 typedef struct wuffs_base__io_transformer__func_ptrs__struct {
6104 wuffs_base__empty_struct (*set_quirk_enabled)(
6105 void* self,
6106 uint32_t a_quirk,
6107 bool a_enabled);
6108 wuffs_base__status (*transform_io)(
6109 void* self,
6110 wuffs_base__io_buffer* a_dst,
6111 wuffs_base__io_buffer* a_src,
6112 wuffs_base__slice_u8 a_workbuf);
6113 wuffs_base__range_ii_u64 (*workbuf_len)(
6114 const void* self);
6115 } wuffs_base__io_transformer__func_ptrs;
6116
6117 typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer;
6118
6119 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6120 wuffs_base__io_transformer__set_quirk_enabled(
6121 wuffs_base__io_transformer* self,
6122 uint32_t a_quirk,
6123 bool a_enabled);
6124
6125 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6126 wuffs_base__io_transformer__transform_io(
6127 wuffs_base__io_transformer* self,
6128 wuffs_base__io_buffer* a_dst,
6129 wuffs_base__io_buffer* a_src,
6130 wuffs_base__slice_u8 a_workbuf);
6131
6132 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6133 wuffs_base__io_transformer__workbuf_len(
6134 const wuffs_base__io_transformer* self);
6135
6136 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6137
6138 struct wuffs_base__io_transformer__struct {
6139 struct {
6140 uint32_t magic;
6141 uint32_t active_coroutine;
6142 wuffs_base__vtable first_vtable;
6143 } private_impl;
6144
6145 #ifdef __cplusplus
6146 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6147 using unique_ptr = std::unique_ptr<wuffs_base__io_transformer, decltype(&free)>;
6148 #endif
6149
6150 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__io_transformer__struct6151 set_quirk_enabled(
6152 uint32_t a_quirk,
6153 bool a_enabled) {
6154 return wuffs_base__io_transformer__set_quirk_enabled(
6155 this, a_quirk, a_enabled);
6156 }
6157
6158 inline wuffs_base__status
transform_iowuffs_base__io_transformer__struct6159 transform_io(
6160 wuffs_base__io_buffer* a_dst,
6161 wuffs_base__io_buffer* a_src,
6162 wuffs_base__slice_u8 a_workbuf) {
6163 return wuffs_base__io_transformer__transform_io(
6164 this, a_dst, a_src, a_workbuf);
6165 }
6166
6167 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__io_transformer__struct6168 workbuf_len() const {
6169 return wuffs_base__io_transformer__workbuf_len(this);
6170 }
6171
6172 #endif // __cplusplus
6173 }; // struct wuffs_base__io_transformer__struct
6174
6175 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6176
6177 // --------
6178
6179 extern const char wuffs_base__token_decoder__vtable_name[];
6180
6181 typedef struct wuffs_base__token_decoder__func_ptrs__struct {
6182 wuffs_base__status (*decode_tokens)(
6183 void* self,
6184 wuffs_base__token_buffer* a_dst,
6185 wuffs_base__io_buffer* a_src,
6186 wuffs_base__slice_u8 a_workbuf);
6187 wuffs_base__empty_struct (*set_quirk_enabled)(
6188 void* self,
6189 uint32_t a_quirk,
6190 bool a_enabled);
6191 wuffs_base__range_ii_u64 (*workbuf_len)(
6192 const void* self);
6193 } wuffs_base__token_decoder__func_ptrs;
6194
6195 typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
6196
6197 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6198 wuffs_base__token_decoder__decode_tokens(
6199 wuffs_base__token_decoder* self,
6200 wuffs_base__token_buffer* a_dst,
6201 wuffs_base__io_buffer* a_src,
6202 wuffs_base__slice_u8 a_workbuf);
6203
6204 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6205 wuffs_base__token_decoder__set_quirk_enabled(
6206 wuffs_base__token_decoder* self,
6207 uint32_t a_quirk,
6208 bool a_enabled);
6209
6210 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6211 wuffs_base__token_decoder__workbuf_len(
6212 const wuffs_base__token_decoder* self);
6213
6214 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6215
6216 struct wuffs_base__token_decoder__struct {
6217 struct {
6218 uint32_t magic;
6219 uint32_t active_coroutine;
6220 wuffs_base__vtable first_vtable;
6221 } private_impl;
6222
6223 #ifdef __cplusplus
6224 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6225 using unique_ptr = std::unique_ptr<wuffs_base__token_decoder, decltype(&free)>;
6226 #endif
6227
6228 inline wuffs_base__status
decode_tokenswuffs_base__token_decoder__struct6229 decode_tokens(
6230 wuffs_base__token_buffer* a_dst,
6231 wuffs_base__io_buffer* a_src,
6232 wuffs_base__slice_u8 a_workbuf) {
6233 return wuffs_base__token_decoder__decode_tokens(
6234 this, a_dst, a_src, a_workbuf);
6235 }
6236
6237 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_base__token_decoder__struct6238 set_quirk_enabled(
6239 uint32_t a_quirk,
6240 bool a_enabled) {
6241 return wuffs_base__token_decoder__set_quirk_enabled(
6242 this, a_quirk, a_enabled);
6243 }
6244
6245 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_base__token_decoder__struct6246 workbuf_len() const {
6247 return wuffs_base__token_decoder__workbuf_len(this);
6248 }
6249
6250 #endif // __cplusplus
6251 }; // struct wuffs_base__token_decoder__struct
6252
6253 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6254
6255 // ----------------
6256
6257 #ifdef __cplusplus
6258 } // extern "C"
6259 #endif
6260
6261 // ---------------- Status Codes
6262
6263 // ---------------- Public Consts
6264
6265 // ---------------- Struct Declarations
6266
6267 typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
6268
6269 #ifdef __cplusplus
6270 extern "C" {
6271 #endif
6272
6273 // ---------------- Public Initializer Prototypes
6274
6275 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6276 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6277 //
6278 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6279 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6280
6281 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6282 wuffs_adler32__hasher__initialize(
6283 wuffs_adler32__hasher* self,
6284 size_t sizeof_star_self,
6285 uint64_t wuffs_version,
6286 uint32_t options);
6287
6288 size_t
6289 sizeof__wuffs_adler32__hasher();
6290
6291 // ---------------- Allocs
6292
6293 // These functions allocate and initialize Wuffs structs. They return NULL if
6294 // memory allocation fails. If they return non-NULL, there is no need to call
6295 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6296 // calling free on the returned pointer. That pointer is effectively a C++
6297 // std::unique_ptr<T, decltype(&free)>.
6298
6299 wuffs_adler32__hasher*
6300 wuffs_adler32__hasher__alloc();
6301
6302 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32()6303 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32() {
6304 return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
6305 }
6306
6307 // ---------------- Upcasts
6308
6309 static inline wuffs_base__hasher_u32*
wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(wuffs_adler32__hasher * p)6310 wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(
6311 wuffs_adler32__hasher* p) {
6312 return (wuffs_base__hasher_u32*)p;
6313 }
6314
6315 // ---------------- Public Function Prototypes
6316
6317 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6318 wuffs_adler32__hasher__set_quirk_enabled(
6319 wuffs_adler32__hasher* self,
6320 uint32_t a_quirk,
6321 bool a_enabled);
6322
6323 WUFFS_BASE__MAYBE_STATIC uint32_t
6324 wuffs_adler32__hasher__update_u32(
6325 wuffs_adler32__hasher* self,
6326 wuffs_base__slice_u8 a_x);
6327
6328 #ifdef __cplusplus
6329 } // extern "C"
6330 #endif
6331
6332 // ---------------- Struct Definitions
6333
6334 // These structs' fields, and the sizeof them, are private implementation
6335 // details that aren't guaranteed to be stable across Wuffs versions.
6336 //
6337 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6338
6339 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6340
6341 struct wuffs_adler32__hasher__struct {
6342 // Do not access the private_impl's or private_data's fields directly. There
6343 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6344 // the wuffs_foo__bar__baz functions.
6345 //
6346 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6347 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6348
6349 struct {
6350 uint32_t magic;
6351 uint32_t active_coroutine;
6352 wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
6353 wuffs_base__vtable null_vtable;
6354
6355 uint32_t f_state;
6356 bool f_started;
6357
6358 wuffs_base__empty_struct (*choosy_up)(
6359 wuffs_adler32__hasher* self,
6360 wuffs_base__slice_u8 a_x);
6361 } private_impl;
6362
6363 #ifdef __cplusplus
6364 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6365 using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, decltype(&free)>;
6366
6367 // On failure, the alloc_etc functions return nullptr. They don't throw.
6368
6369 static inline unique_ptr
allocwuffs_adler32__hasher__struct6370 alloc() {
6371 return unique_ptr(wuffs_adler32__hasher__alloc(), &free);
6372 }
6373
6374 static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6375 alloc_as__wuffs_base__hasher_u32() {
6376 return wuffs_base__hasher_u32::unique_ptr(
6377 wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(), &free);
6378 }
6379 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6380
6381 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6382 // Disallow constructing or copying an object via standard C++ mechanisms,
6383 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6384 // size and field layout is not part of the public, stable, memory-safe API.
6385 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6386 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6387 // their first argument) rather than tweaking bar.private_impl.qux fields.
6388 //
6389 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6390 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6391 // order to provide convenience methods. These forward on "this", so that you
6392 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6393 wuffs_adler32__hasher__struct() = delete;
6394 wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
6395 wuffs_adler32__hasher__struct& operator=(
6396 const wuffs_adler32__hasher__struct&) = delete;
6397 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6398
6399 #if !defined(WUFFS_IMPLEMENTATION)
6400 // As above, the size of the struct is not part of the public API, and unless
6401 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6402 // allocated, not stack allocated. Its size is not intended to be known at
6403 // compile time, but it is unfortunately divulged as a side effect of
6404 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6405 // instead of "sizeof T", invoking the operator. To make the two values
6406 // different, so that passing the latter will be rejected by the initialize
6407 // function, we add an arbitrary amount of dead weight.
6408 uint8_t dead_weight[123000000]; // 123 MB.
6409 #endif // !defined(WUFFS_IMPLEMENTATION)
6410
6411 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_adler32__hasher__struct6412 initialize(
6413 size_t sizeof_star_self,
6414 uint64_t wuffs_version,
6415 uint32_t options) {
6416 return wuffs_adler32__hasher__initialize(
6417 this, sizeof_star_self, wuffs_version, options);
6418 }
6419
6420 inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_adler32__hasher__struct6421 upcast_as__wuffs_base__hasher_u32() {
6422 return (wuffs_base__hasher_u32*)this;
6423 }
6424
6425 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_adler32__hasher__struct6426 set_quirk_enabled(
6427 uint32_t a_quirk,
6428 bool a_enabled) {
6429 return wuffs_adler32__hasher__set_quirk_enabled(this, a_quirk, a_enabled);
6430 }
6431
6432 inline uint32_t
update_u32wuffs_adler32__hasher__struct6433 update_u32(
6434 wuffs_base__slice_u8 a_x) {
6435 return wuffs_adler32__hasher__update_u32(this, a_x);
6436 }
6437
6438 #endif // __cplusplus
6439 }; // struct wuffs_adler32__hasher__struct
6440
6441 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6442
6443 // ---------------- Status Codes
6444
6445 extern const char wuffs_bmp__error__bad_header[];
6446 extern const char wuffs_bmp__error__bad_rle_compression[];
6447 extern const char wuffs_bmp__error__unsupported_bmp_file[];
6448
6449 // ---------------- Public Consts
6450
6451 #define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6452
6453 // ---------------- Struct Declarations
6454
6455 typedef struct wuffs_bmp__decoder__struct wuffs_bmp__decoder;
6456
6457 #ifdef __cplusplus
6458 extern "C" {
6459 #endif
6460
6461 // ---------------- Public Initializer Prototypes
6462
6463 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6464 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6465 //
6466 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6467 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6468
6469 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6470 wuffs_bmp__decoder__initialize(
6471 wuffs_bmp__decoder* self,
6472 size_t sizeof_star_self,
6473 uint64_t wuffs_version,
6474 uint32_t options);
6475
6476 size_t
6477 sizeof__wuffs_bmp__decoder();
6478
6479 // ---------------- Allocs
6480
6481 // These functions allocate and initialize Wuffs structs. They return NULL if
6482 // memory allocation fails. If they return non-NULL, there is no need to call
6483 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6484 // calling free on the returned pointer. That pointer is effectively a C++
6485 // std::unique_ptr<T, decltype(&free)>.
6486
6487 wuffs_bmp__decoder*
6488 wuffs_bmp__decoder__alloc();
6489
6490 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder()6491 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder() {
6492 return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
6493 }
6494
6495 // ---------------- Upcasts
6496
6497 static inline wuffs_base__image_decoder*
wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_bmp__decoder * p)6498 wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
6499 wuffs_bmp__decoder* p) {
6500 return (wuffs_base__image_decoder*)p;
6501 }
6502
6503 // ---------------- Public Function Prototypes
6504
6505 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6506 wuffs_bmp__decoder__set_quirk_enabled(
6507 wuffs_bmp__decoder* self,
6508 uint32_t a_quirk,
6509 bool a_enabled);
6510
6511 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6512 wuffs_bmp__decoder__decode_image_config(
6513 wuffs_bmp__decoder* self,
6514 wuffs_base__image_config* a_dst,
6515 wuffs_base__io_buffer* a_src);
6516
6517 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6518 wuffs_bmp__decoder__decode_frame_config(
6519 wuffs_bmp__decoder* self,
6520 wuffs_base__frame_config* a_dst,
6521 wuffs_base__io_buffer* a_src);
6522
6523 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6524 wuffs_bmp__decoder__decode_frame(
6525 wuffs_bmp__decoder* self,
6526 wuffs_base__pixel_buffer* a_dst,
6527 wuffs_base__io_buffer* a_src,
6528 wuffs_base__pixel_blend a_blend,
6529 wuffs_base__slice_u8 a_workbuf,
6530 wuffs_base__decode_frame_options* a_opts);
6531
6532 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
6533 wuffs_bmp__decoder__frame_dirty_rect(
6534 const wuffs_bmp__decoder* self);
6535
6536 WUFFS_BASE__MAYBE_STATIC uint32_t
6537 wuffs_bmp__decoder__num_animation_loops(
6538 const wuffs_bmp__decoder* self);
6539
6540 WUFFS_BASE__MAYBE_STATIC uint64_t
6541 wuffs_bmp__decoder__num_decoded_frame_configs(
6542 const wuffs_bmp__decoder* self);
6543
6544 WUFFS_BASE__MAYBE_STATIC uint64_t
6545 wuffs_bmp__decoder__num_decoded_frames(
6546 const wuffs_bmp__decoder* self);
6547
6548 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6549 wuffs_bmp__decoder__restart_frame(
6550 wuffs_bmp__decoder* self,
6551 uint64_t a_index,
6552 uint64_t a_io_position);
6553
6554 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6555 wuffs_bmp__decoder__set_report_metadata(
6556 wuffs_bmp__decoder* self,
6557 uint32_t a_fourcc,
6558 bool a_report);
6559
6560 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6561 wuffs_bmp__decoder__tell_me_more(
6562 wuffs_bmp__decoder* self,
6563 wuffs_base__io_buffer* a_dst,
6564 wuffs_base__more_information* a_minfo,
6565 wuffs_base__io_buffer* a_src);
6566
6567 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6568 wuffs_bmp__decoder__workbuf_len(
6569 const wuffs_bmp__decoder* self);
6570
6571 #ifdef __cplusplus
6572 } // extern "C"
6573 #endif
6574
6575 // ---------------- Struct Definitions
6576
6577 // These structs' fields, and the sizeof them, are private implementation
6578 // details that aren't guaranteed to be stable across Wuffs versions.
6579 //
6580 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6581
6582 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6583
6584 struct wuffs_bmp__decoder__struct {
6585 // Do not access the private_impl's or private_data's fields directly. There
6586 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6587 // the wuffs_foo__bar__baz functions.
6588 //
6589 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6590 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6591
6592 struct {
6593 uint32_t magic;
6594 uint32_t active_coroutine;
6595 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
6596 wuffs_base__vtable null_vtable;
6597
6598 uint32_t f_width;
6599 uint32_t f_height;
6600 uint8_t f_call_sequence;
6601 bool f_top_down;
6602 uint32_t f_pad_per_row;
6603 uint32_t f_src_pixfmt;
6604 uint32_t f_io_redirect_fourcc;
6605 uint64_t f_io_redirect_pos;
6606 uint64_t f_frame_config_io_position;
6607 uint32_t f_bitmap_info_len;
6608 uint32_t f_padding;
6609 uint32_t f_bits_per_pixel;
6610 uint32_t f_compression;
6611 uint32_t f_channel_masks[4];
6612 uint8_t f_channel_shifts[4];
6613 uint8_t f_channel_num_bits[4];
6614 uint32_t f_dst_x;
6615 uint32_t f_dst_y;
6616 uint32_t f_dst_y_inc;
6617 uint32_t f_pending_pad;
6618 uint32_t f_rle_state;
6619 uint32_t f_rle_length;
6620 uint8_t f_rle_delta_x;
6621 bool f_rle_padded;
6622 wuffs_base__pixel_swizzler f_swizzler;
6623
6624 uint32_t p_decode_image_config[1];
6625 uint32_t p_decode_frame_config[1];
6626 uint32_t p_decode_frame[1];
6627 uint32_t p_read_palette[1];
6628 } private_impl;
6629
6630 struct {
6631 uint8_t f_scratch[2048];
6632 uint8_t f_src_palette[1024];
6633
6634 struct {
6635 uint64_t scratch;
6636 } s_decode_image_config[1];
6637 struct {
6638 wuffs_base__status v_status;
6639 uint64_t scratch;
6640 } s_decode_frame[1];
6641 struct {
6642 uint32_t v_i;
6643 uint64_t scratch;
6644 } s_read_palette[1];
6645 } private_data;
6646
6647 #ifdef __cplusplus
6648 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6649 using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, decltype(&free)>;
6650
6651 // On failure, the alloc_etc functions return nullptr. They don't throw.
6652
6653 static inline unique_ptr
allocwuffs_bmp__decoder__struct6654 alloc() {
6655 return unique_ptr(wuffs_bmp__decoder__alloc(), &free);
6656 }
6657
6658 static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct6659 alloc_as__wuffs_base__image_decoder() {
6660 return wuffs_base__image_decoder::unique_ptr(
6661 wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
6662 }
6663 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6664
6665 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6666 // Disallow constructing or copying an object via standard C++ mechanisms,
6667 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6668 // size and field layout is not part of the public, stable, memory-safe API.
6669 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6670 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6671 // their first argument) rather than tweaking bar.private_impl.qux fields.
6672 //
6673 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6674 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6675 // order to provide convenience methods. These forward on "this", so that you
6676 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6677 wuffs_bmp__decoder__struct() = delete;
6678 wuffs_bmp__decoder__struct(const wuffs_bmp__decoder__struct&) = delete;
6679 wuffs_bmp__decoder__struct& operator=(
6680 const wuffs_bmp__decoder__struct&) = delete;
6681 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6682
6683 #if !defined(WUFFS_IMPLEMENTATION)
6684 // As above, the size of the struct is not part of the public API, and unless
6685 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6686 // allocated, not stack allocated. Its size is not intended to be known at
6687 // compile time, but it is unfortunately divulged as a side effect of
6688 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6689 // instead of "sizeof T", invoking the operator. To make the two values
6690 // different, so that passing the latter will be rejected by the initialize
6691 // function, we add an arbitrary amount of dead weight.
6692 uint8_t dead_weight[123000000]; // 123 MB.
6693 #endif // !defined(WUFFS_IMPLEMENTATION)
6694
6695 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_bmp__decoder__struct6696 initialize(
6697 size_t sizeof_star_self,
6698 uint64_t wuffs_version,
6699 uint32_t options) {
6700 return wuffs_bmp__decoder__initialize(
6701 this, sizeof_star_self, wuffs_version, options);
6702 }
6703
6704 inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_bmp__decoder__struct6705 upcast_as__wuffs_base__image_decoder() {
6706 return (wuffs_base__image_decoder*)this;
6707 }
6708
6709 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_bmp__decoder__struct6710 set_quirk_enabled(
6711 uint32_t a_quirk,
6712 bool a_enabled) {
6713 return wuffs_bmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6714 }
6715
6716 inline wuffs_base__status
decode_image_configwuffs_bmp__decoder__struct6717 decode_image_config(
6718 wuffs_base__image_config* a_dst,
6719 wuffs_base__io_buffer* a_src) {
6720 return wuffs_bmp__decoder__decode_image_config(this, a_dst, a_src);
6721 }
6722
6723 inline wuffs_base__status
decode_frame_configwuffs_bmp__decoder__struct6724 decode_frame_config(
6725 wuffs_base__frame_config* a_dst,
6726 wuffs_base__io_buffer* a_src) {
6727 return wuffs_bmp__decoder__decode_frame_config(this, a_dst, a_src);
6728 }
6729
6730 inline wuffs_base__status
decode_framewuffs_bmp__decoder__struct6731 decode_frame(
6732 wuffs_base__pixel_buffer* a_dst,
6733 wuffs_base__io_buffer* a_src,
6734 wuffs_base__pixel_blend a_blend,
6735 wuffs_base__slice_u8 a_workbuf,
6736 wuffs_base__decode_frame_options* a_opts) {
6737 return wuffs_bmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
6738 }
6739
6740 inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_bmp__decoder__struct6741 frame_dirty_rect() const {
6742 return wuffs_bmp__decoder__frame_dirty_rect(this);
6743 }
6744
6745 inline uint32_t
num_animation_loopswuffs_bmp__decoder__struct6746 num_animation_loops() const {
6747 return wuffs_bmp__decoder__num_animation_loops(this);
6748 }
6749
6750 inline uint64_t
num_decoded_frame_configswuffs_bmp__decoder__struct6751 num_decoded_frame_configs() const {
6752 return wuffs_bmp__decoder__num_decoded_frame_configs(this);
6753 }
6754
6755 inline uint64_t
num_decoded_frameswuffs_bmp__decoder__struct6756 num_decoded_frames() const {
6757 return wuffs_bmp__decoder__num_decoded_frames(this);
6758 }
6759
6760 inline wuffs_base__status
restart_framewuffs_bmp__decoder__struct6761 restart_frame(
6762 uint64_t a_index,
6763 uint64_t a_io_position) {
6764 return wuffs_bmp__decoder__restart_frame(this, a_index, a_io_position);
6765 }
6766
6767 inline wuffs_base__empty_struct
set_report_metadatawuffs_bmp__decoder__struct6768 set_report_metadata(
6769 uint32_t a_fourcc,
6770 bool a_report) {
6771 return wuffs_bmp__decoder__set_report_metadata(this, a_fourcc, a_report);
6772 }
6773
6774 inline wuffs_base__status
tell_me_morewuffs_bmp__decoder__struct6775 tell_me_more(
6776 wuffs_base__io_buffer* a_dst,
6777 wuffs_base__more_information* a_minfo,
6778 wuffs_base__io_buffer* a_src) {
6779 return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
6780 }
6781
6782 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_bmp__decoder__struct6783 workbuf_len() const {
6784 return wuffs_bmp__decoder__workbuf_len(this);
6785 }
6786
6787 #endif // __cplusplus
6788 }; // struct wuffs_bmp__decoder__struct
6789
6790 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6791
6792 // ---------------- Status Codes
6793
6794 extern const char wuffs_cbor__error__bad_input[];
6795 extern const char wuffs_cbor__error__unsupported_recursion_depth[];
6796
6797 // ---------------- Public Consts
6798
6799 #define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
6800
6801 #define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024
6802
6803 #define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2
6804
6805 #define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9
6806
6807 #define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997
6808
6809 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143
6810
6811 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216
6812
6813 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608
6814
6815 #define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304
6816
6817 // ---------------- Struct Declarations
6818
6819 typedef struct wuffs_cbor__decoder__struct wuffs_cbor__decoder;
6820
6821 #ifdef __cplusplus
6822 extern "C" {
6823 #endif
6824
6825 // ---------------- Public Initializer Prototypes
6826
6827 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
6828 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
6829 //
6830 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
6831 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
6832
6833 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
6834 wuffs_cbor__decoder__initialize(
6835 wuffs_cbor__decoder* self,
6836 size_t sizeof_star_self,
6837 uint64_t wuffs_version,
6838 uint32_t options);
6839
6840 size_t
6841 sizeof__wuffs_cbor__decoder();
6842
6843 // ---------------- Allocs
6844
6845 // These functions allocate and initialize Wuffs structs. They return NULL if
6846 // memory allocation fails. If they return non-NULL, there is no need to call
6847 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
6848 // calling free on the returned pointer. That pointer is effectively a C++
6849 // std::unique_ptr<T, decltype(&free)>.
6850
6851 wuffs_cbor__decoder*
6852 wuffs_cbor__decoder__alloc();
6853
6854 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder()6855 wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder() {
6856 return (wuffs_base__token_decoder*)(wuffs_cbor__decoder__alloc());
6857 }
6858
6859 // ---------------- Upcasts
6860
6861 static inline wuffs_base__token_decoder*
wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(wuffs_cbor__decoder * p)6862 wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(
6863 wuffs_cbor__decoder* p) {
6864 return (wuffs_base__token_decoder*)p;
6865 }
6866
6867 // ---------------- Public Function Prototypes
6868
6869 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
6870 wuffs_cbor__decoder__set_quirk_enabled(
6871 wuffs_cbor__decoder* self,
6872 uint32_t a_quirk,
6873 bool a_enabled);
6874
6875 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
6876 wuffs_cbor__decoder__workbuf_len(
6877 const wuffs_cbor__decoder* self);
6878
6879 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
6880 wuffs_cbor__decoder__decode_tokens(
6881 wuffs_cbor__decoder* self,
6882 wuffs_base__token_buffer* a_dst,
6883 wuffs_base__io_buffer* a_src,
6884 wuffs_base__slice_u8 a_workbuf);
6885
6886 #ifdef __cplusplus
6887 } // extern "C"
6888 #endif
6889
6890 // ---------------- Struct Definitions
6891
6892 // These structs' fields, and the sizeof them, are private implementation
6893 // details that aren't guaranteed to be stable across Wuffs versions.
6894 //
6895 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
6896
6897 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
6898
6899 struct wuffs_cbor__decoder__struct {
6900 // Do not access the private_impl's or private_data's fields directly. There
6901 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
6902 // the wuffs_foo__bar__baz functions.
6903 //
6904 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
6905 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
6906
6907 struct {
6908 uint32_t magic;
6909 uint32_t active_coroutine;
6910 wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
6911 wuffs_base__vtable null_vtable;
6912
6913 bool f_end_of_data;
6914
6915 uint32_t p_decode_tokens[1];
6916 } private_impl;
6917
6918 struct {
6919 uint32_t f_stack[64];
6920 uint64_t f_container_num_remaining[1024];
6921
6922 struct {
6923 uint64_t v_string_length;
6924 uint32_t v_depth;
6925 uint32_t v_token_length;
6926 bool v_tagged;
6927 uint8_t v_indefinite_string_major_type;
6928 } s_decode_tokens[1];
6929 } private_data;
6930
6931 #ifdef __cplusplus
6932 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6933 using unique_ptr = std::unique_ptr<wuffs_cbor__decoder, decltype(&free)>;
6934
6935 // On failure, the alloc_etc functions return nullptr. They don't throw.
6936
6937 static inline unique_ptr
allocwuffs_cbor__decoder__struct6938 alloc() {
6939 return unique_ptr(wuffs_cbor__decoder__alloc(), &free);
6940 }
6941
6942 static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct6943 alloc_as__wuffs_base__token_decoder() {
6944 return wuffs_base__token_decoder::unique_ptr(
6945 wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder(), &free);
6946 }
6947 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
6948
6949 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6950 // Disallow constructing or copying an object via standard C++ mechanisms,
6951 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
6952 // size and field layout is not part of the public, stable, memory-safe API.
6953 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
6954 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
6955 // their first argument) rather than tweaking bar.private_impl.qux fields.
6956 //
6957 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
6958 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
6959 // order to provide convenience methods. These forward on "this", so that you
6960 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
6961 wuffs_cbor__decoder__struct() = delete;
6962 wuffs_cbor__decoder__struct(const wuffs_cbor__decoder__struct&) = delete;
6963 wuffs_cbor__decoder__struct& operator=(
6964 const wuffs_cbor__decoder__struct&) = delete;
6965 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
6966
6967 #if !defined(WUFFS_IMPLEMENTATION)
6968 // As above, the size of the struct is not part of the public API, and unless
6969 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
6970 // allocated, not stack allocated. Its size is not intended to be known at
6971 // compile time, but it is unfortunately divulged as a side effect of
6972 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
6973 // instead of "sizeof T", invoking the operator. To make the two values
6974 // different, so that passing the latter will be rejected by the initialize
6975 // function, we add an arbitrary amount of dead weight.
6976 uint8_t dead_weight[123000000]; // 123 MB.
6977 #endif // !defined(WUFFS_IMPLEMENTATION)
6978
6979 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_cbor__decoder__struct6980 initialize(
6981 size_t sizeof_star_self,
6982 uint64_t wuffs_version,
6983 uint32_t options) {
6984 return wuffs_cbor__decoder__initialize(
6985 this, sizeof_star_self, wuffs_version, options);
6986 }
6987
6988 inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_cbor__decoder__struct6989 upcast_as__wuffs_base__token_decoder() {
6990 return (wuffs_base__token_decoder*)this;
6991 }
6992
6993 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_cbor__decoder__struct6994 set_quirk_enabled(
6995 uint32_t a_quirk,
6996 bool a_enabled) {
6997 return wuffs_cbor__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
6998 }
6999
7000 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_cbor__decoder__struct7001 workbuf_len() const {
7002 return wuffs_cbor__decoder__workbuf_len(this);
7003 }
7004
7005 inline wuffs_base__status
decode_tokenswuffs_cbor__decoder__struct7006 decode_tokens(
7007 wuffs_base__token_buffer* a_dst,
7008 wuffs_base__io_buffer* a_src,
7009 wuffs_base__slice_u8 a_workbuf) {
7010 return wuffs_cbor__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
7011 }
7012
7013 #endif // __cplusplus
7014 }; // struct wuffs_cbor__decoder__struct
7015
7016 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7017
7018 // ---------------- Status Codes
7019
7020 // ---------------- Public Consts
7021
7022 // ---------------- Struct Declarations
7023
7024 typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
7025
7026 #ifdef __cplusplus
7027 extern "C" {
7028 #endif
7029
7030 // ---------------- Public Initializer Prototypes
7031
7032 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7033 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7034 //
7035 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7036 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7037
7038 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7039 wuffs_crc32__ieee_hasher__initialize(
7040 wuffs_crc32__ieee_hasher* self,
7041 size_t sizeof_star_self,
7042 uint64_t wuffs_version,
7043 uint32_t options);
7044
7045 size_t
7046 sizeof__wuffs_crc32__ieee_hasher();
7047
7048 // ---------------- Allocs
7049
7050 // These functions allocate and initialize Wuffs structs. They return NULL if
7051 // memory allocation fails. If they return non-NULL, there is no need to call
7052 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7053 // calling free on the returned pointer. That pointer is effectively a C++
7054 // std::unique_ptr<T, decltype(&free)>.
7055
7056 wuffs_crc32__ieee_hasher*
7057 wuffs_crc32__ieee_hasher__alloc();
7058
7059 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32()7060 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32() {
7061 return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
7062 }
7063
7064 // ---------------- Upcasts
7065
7066 static inline wuffs_base__hasher_u32*
wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(wuffs_crc32__ieee_hasher * p)7067 wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(
7068 wuffs_crc32__ieee_hasher* p) {
7069 return (wuffs_base__hasher_u32*)p;
7070 }
7071
7072 // ---------------- Public Function Prototypes
7073
7074 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7075 wuffs_crc32__ieee_hasher__set_quirk_enabled(
7076 wuffs_crc32__ieee_hasher* self,
7077 uint32_t a_quirk,
7078 bool a_enabled);
7079
7080 WUFFS_BASE__MAYBE_STATIC uint32_t
7081 wuffs_crc32__ieee_hasher__update_u32(
7082 wuffs_crc32__ieee_hasher* self,
7083 wuffs_base__slice_u8 a_x);
7084
7085 #ifdef __cplusplus
7086 } // extern "C"
7087 #endif
7088
7089 // ---------------- Struct Definitions
7090
7091 // These structs' fields, and the sizeof them, are private implementation
7092 // details that aren't guaranteed to be stable across Wuffs versions.
7093 //
7094 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7095
7096 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7097
7098 struct wuffs_crc32__ieee_hasher__struct {
7099 // Do not access the private_impl's or private_data's fields directly. There
7100 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7101 // the wuffs_foo__bar__baz functions.
7102 //
7103 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7104 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7105
7106 struct {
7107 uint32_t magic;
7108 uint32_t active_coroutine;
7109 wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
7110 wuffs_base__vtable null_vtable;
7111
7112 uint32_t f_state;
7113
7114 wuffs_base__empty_struct (*choosy_up)(
7115 wuffs_crc32__ieee_hasher* self,
7116 wuffs_base__slice_u8 a_x);
7117 } private_impl;
7118
7119 #ifdef __cplusplus
7120 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7121 using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, decltype(&free)>;
7122
7123 // On failure, the alloc_etc functions return nullptr. They don't throw.
7124
7125 static inline unique_ptr
allocwuffs_crc32__ieee_hasher__struct7126 alloc() {
7127 return unique_ptr(wuffs_crc32__ieee_hasher__alloc(), &free);
7128 }
7129
7130 static inline wuffs_base__hasher_u32::unique_ptr
alloc_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct7131 alloc_as__wuffs_base__hasher_u32() {
7132 return wuffs_base__hasher_u32::unique_ptr(
7133 wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(), &free);
7134 }
7135 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7136
7137 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7138 // Disallow constructing or copying an object via standard C++ mechanisms,
7139 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7140 // size and field layout is not part of the public, stable, memory-safe API.
7141 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7142 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7143 // their first argument) rather than tweaking bar.private_impl.qux fields.
7144 //
7145 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7146 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7147 // order to provide convenience methods. These forward on "this", so that you
7148 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7149 wuffs_crc32__ieee_hasher__struct() = delete;
7150 wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) = delete;
7151 wuffs_crc32__ieee_hasher__struct& operator=(
7152 const wuffs_crc32__ieee_hasher__struct&) = delete;
7153 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7154
7155 #if !defined(WUFFS_IMPLEMENTATION)
7156 // As above, the size of the struct is not part of the public API, and unless
7157 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7158 // allocated, not stack allocated. Its size is not intended to be known at
7159 // compile time, but it is unfortunately divulged as a side effect of
7160 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7161 // instead of "sizeof T", invoking the operator. To make the two values
7162 // different, so that passing the latter will be rejected by the initialize
7163 // function, we add an arbitrary amount of dead weight.
7164 uint8_t dead_weight[123000000]; // 123 MB.
7165 #endif // !defined(WUFFS_IMPLEMENTATION)
7166
7167 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_crc32__ieee_hasher__struct7168 initialize(
7169 size_t sizeof_star_self,
7170 uint64_t wuffs_version,
7171 uint32_t options) {
7172 return wuffs_crc32__ieee_hasher__initialize(
7173 this, sizeof_star_self, wuffs_version, options);
7174 }
7175
7176 inline wuffs_base__hasher_u32*
upcast_as__wuffs_base__hasher_u32wuffs_crc32__ieee_hasher__struct7177 upcast_as__wuffs_base__hasher_u32() {
7178 return (wuffs_base__hasher_u32*)this;
7179 }
7180
7181 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_crc32__ieee_hasher__struct7182 set_quirk_enabled(
7183 uint32_t a_quirk,
7184 bool a_enabled) {
7185 return wuffs_crc32__ieee_hasher__set_quirk_enabled(this, a_quirk, a_enabled);
7186 }
7187
7188 inline uint32_t
update_u32wuffs_crc32__ieee_hasher__struct7189 update_u32(
7190 wuffs_base__slice_u8 a_x) {
7191 return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
7192 }
7193
7194 #endif // __cplusplus
7195 }; // struct wuffs_crc32__ieee_hasher__struct
7196
7197 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7198
7199 // ---------------- Status Codes
7200
7201 extern const char wuffs_deflate__error__bad_huffman_code_over_subscribed[];
7202 extern const char wuffs_deflate__error__bad_huffman_code_under_subscribed[];
7203 extern const char wuffs_deflate__error__bad_huffman_code_length_count[];
7204 extern const char wuffs_deflate__error__bad_huffman_code_length_repetition[];
7205 extern const char wuffs_deflate__error__bad_huffman_code[];
7206 extern const char wuffs_deflate__error__bad_huffman_minimum_code_length[];
7207 extern const char wuffs_deflate__error__bad_block[];
7208 extern const char wuffs_deflate__error__bad_distance[];
7209 extern const char wuffs_deflate__error__bad_distance_code_count[];
7210 extern const char wuffs_deflate__error__bad_literal_length_code_count[];
7211 extern const char wuffs_deflate__error__inconsistent_stored_block_length[];
7212 extern const char wuffs_deflate__error__missing_end_of_block_code[];
7213 extern const char wuffs_deflate__error__no_huffman_codes[];
7214
7215 // ---------------- Public Consts
7216
7217 #define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
7218
7219 // ---------------- Struct Declarations
7220
7221 typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
7222
7223 #ifdef __cplusplus
7224 extern "C" {
7225 #endif
7226
7227 // ---------------- Public Initializer Prototypes
7228
7229 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7230 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7231 //
7232 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7233 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7234
7235 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7236 wuffs_deflate__decoder__initialize(
7237 wuffs_deflate__decoder* self,
7238 size_t sizeof_star_self,
7239 uint64_t wuffs_version,
7240 uint32_t options);
7241
7242 size_t
7243 sizeof__wuffs_deflate__decoder();
7244
7245 // ---------------- Allocs
7246
7247 // These functions allocate and initialize Wuffs structs. They return NULL if
7248 // memory allocation fails. If they return non-NULL, there is no need to call
7249 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7250 // calling free on the returned pointer. That pointer is effectively a C++
7251 // std::unique_ptr<T, decltype(&free)>.
7252
7253 wuffs_deflate__decoder*
7254 wuffs_deflate__decoder__alloc();
7255
7256 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer()7257 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer() {
7258 return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
7259 }
7260
7261 // ---------------- Upcasts
7262
7263 static inline wuffs_base__io_transformer*
wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(wuffs_deflate__decoder * p)7264 wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(
7265 wuffs_deflate__decoder* p) {
7266 return (wuffs_base__io_transformer*)p;
7267 }
7268
7269 // ---------------- Public Function Prototypes
7270
7271 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7272 wuffs_deflate__decoder__add_history(
7273 wuffs_deflate__decoder* self,
7274 wuffs_base__slice_u8 a_hist);
7275
7276 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7277 wuffs_deflate__decoder__set_quirk_enabled(
7278 wuffs_deflate__decoder* self,
7279 uint32_t a_quirk,
7280 bool a_enabled);
7281
7282 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7283 wuffs_deflate__decoder__workbuf_len(
7284 const wuffs_deflate__decoder* self);
7285
7286 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7287 wuffs_deflate__decoder__transform_io(
7288 wuffs_deflate__decoder* self,
7289 wuffs_base__io_buffer* a_dst,
7290 wuffs_base__io_buffer* a_src,
7291 wuffs_base__slice_u8 a_workbuf);
7292
7293 #ifdef __cplusplus
7294 } // extern "C"
7295 #endif
7296
7297 // ---------------- Struct Definitions
7298
7299 // These structs' fields, and the sizeof them, are private implementation
7300 // details that aren't guaranteed to be stable across Wuffs versions.
7301 //
7302 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7303
7304 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7305
7306 struct wuffs_deflate__decoder__struct {
7307 // Do not access the private_impl's or private_data's fields directly. There
7308 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7309 // the wuffs_foo__bar__baz functions.
7310 //
7311 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7312 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7313
7314 struct {
7315 uint32_t magic;
7316 uint32_t active_coroutine;
7317 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7318 wuffs_base__vtable null_vtable;
7319
7320 uint32_t f_bits;
7321 uint32_t f_n_bits;
7322 uint64_t f_transformed_history_count;
7323 uint32_t f_history_index;
7324 uint32_t f_n_huffs_bits[2];
7325 bool f_end_of_block;
7326
7327 uint32_t p_transform_io[1];
7328 uint32_t p_decode_blocks[1];
7329 uint32_t p_decode_uncompressed[1];
7330 uint32_t p_init_dynamic_huffman[1];
7331 wuffs_base__status (*choosy_decode_huffman_fast64)(
7332 wuffs_deflate__decoder* self,
7333 wuffs_base__io_buffer* a_dst,
7334 wuffs_base__io_buffer* a_src);
7335 uint32_t p_decode_huffman_slow[1];
7336 } private_impl;
7337
7338 struct {
7339 uint32_t f_huffs[2][1024];
7340 uint8_t f_history[33025];
7341 uint8_t f_code_lengths[320];
7342
7343 struct {
7344 uint32_t v_final;
7345 } s_decode_blocks[1];
7346 struct {
7347 uint32_t v_length;
7348 uint64_t scratch;
7349 } s_decode_uncompressed[1];
7350 struct {
7351 uint32_t v_bits;
7352 uint32_t v_n_bits;
7353 uint32_t v_n_lit;
7354 uint32_t v_n_dist;
7355 uint32_t v_n_clen;
7356 uint32_t v_i;
7357 uint32_t v_mask;
7358 uint32_t v_table_entry;
7359 uint32_t v_n_extra_bits;
7360 uint8_t v_rep_symbol;
7361 uint32_t v_rep_count;
7362 } s_init_dynamic_huffman[1];
7363 struct {
7364 uint32_t v_bits;
7365 uint32_t v_n_bits;
7366 uint32_t v_table_entry;
7367 uint32_t v_table_entry_n_bits;
7368 uint32_t v_lmask;
7369 uint32_t v_dmask;
7370 uint32_t v_redir_top;
7371 uint32_t v_redir_mask;
7372 uint32_t v_length;
7373 uint32_t v_dist_minus_1;
7374 uint32_t v_hlen;
7375 uint64_t scratch;
7376 } s_decode_huffman_slow[1];
7377 } private_data;
7378
7379 #ifdef __cplusplus
7380 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7381 using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, decltype(&free)>;
7382
7383 // On failure, the alloc_etc functions return nullptr. They don't throw.
7384
7385 static inline unique_ptr
allocwuffs_deflate__decoder__struct7386 alloc() {
7387 return unique_ptr(wuffs_deflate__decoder__alloc(), &free);
7388 }
7389
7390 static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct7391 alloc_as__wuffs_base__io_transformer() {
7392 return wuffs_base__io_transformer::unique_ptr(
7393 wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(), &free);
7394 }
7395 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7396
7397 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7398 // Disallow constructing or copying an object via standard C++ mechanisms,
7399 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7400 // size and field layout is not part of the public, stable, memory-safe API.
7401 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7402 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7403 // their first argument) rather than tweaking bar.private_impl.qux fields.
7404 //
7405 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7406 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7407 // order to provide convenience methods. These forward on "this", so that you
7408 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7409 wuffs_deflate__decoder__struct() = delete;
7410 wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = delete;
7411 wuffs_deflate__decoder__struct& operator=(
7412 const wuffs_deflate__decoder__struct&) = delete;
7413 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7414
7415 #if !defined(WUFFS_IMPLEMENTATION)
7416 // As above, the size of the struct is not part of the public API, and unless
7417 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7418 // allocated, not stack allocated. Its size is not intended to be known at
7419 // compile time, but it is unfortunately divulged as a side effect of
7420 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7421 // instead of "sizeof T", invoking the operator. To make the two values
7422 // different, so that passing the latter will be rejected by the initialize
7423 // function, we add an arbitrary amount of dead weight.
7424 uint8_t dead_weight[123000000]; // 123 MB.
7425 #endif // !defined(WUFFS_IMPLEMENTATION)
7426
7427 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_deflate__decoder__struct7428 initialize(
7429 size_t sizeof_star_self,
7430 uint64_t wuffs_version,
7431 uint32_t options) {
7432 return wuffs_deflate__decoder__initialize(
7433 this, sizeof_star_self, wuffs_version, options);
7434 }
7435
7436 inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_deflate__decoder__struct7437 upcast_as__wuffs_base__io_transformer() {
7438 return (wuffs_base__io_transformer*)this;
7439 }
7440
7441 inline wuffs_base__empty_struct
add_historywuffs_deflate__decoder__struct7442 add_history(
7443 wuffs_base__slice_u8 a_hist) {
7444 return wuffs_deflate__decoder__add_history(this, a_hist);
7445 }
7446
7447 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_deflate__decoder__struct7448 set_quirk_enabled(
7449 uint32_t a_quirk,
7450 bool a_enabled) {
7451 return wuffs_deflate__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7452 }
7453
7454 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_deflate__decoder__struct7455 workbuf_len() const {
7456 return wuffs_deflate__decoder__workbuf_len(this);
7457 }
7458
7459 inline wuffs_base__status
transform_iowuffs_deflate__decoder__struct7460 transform_io(
7461 wuffs_base__io_buffer* a_dst,
7462 wuffs_base__io_buffer* a_src,
7463 wuffs_base__slice_u8 a_workbuf) {
7464 return wuffs_deflate__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7465 }
7466
7467 #endif // __cplusplus
7468 }; // struct wuffs_deflate__decoder__struct
7469
7470 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7471
7472 // ---------------- Status Codes
7473
7474 extern const char wuffs_lzw__error__bad_code[];
7475
7476 // ---------------- Public Consts
7477
7478 #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7479
7480 // ---------------- Struct Declarations
7481
7482 typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
7483
7484 #ifdef __cplusplus
7485 extern "C" {
7486 #endif
7487
7488 // ---------------- Public Initializer Prototypes
7489
7490 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7491 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7492 //
7493 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7494 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7495
7496 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7497 wuffs_lzw__decoder__initialize(
7498 wuffs_lzw__decoder* self,
7499 size_t sizeof_star_self,
7500 uint64_t wuffs_version,
7501 uint32_t options);
7502
7503 size_t
7504 sizeof__wuffs_lzw__decoder();
7505
7506 // ---------------- Allocs
7507
7508 // These functions allocate and initialize Wuffs structs. They return NULL if
7509 // memory allocation fails. If they return non-NULL, there is no need to call
7510 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7511 // calling free on the returned pointer. That pointer is effectively a C++
7512 // std::unique_ptr<T, decltype(&free)>.
7513
7514 wuffs_lzw__decoder*
7515 wuffs_lzw__decoder__alloc();
7516
7517 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer()7518 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer() {
7519 return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
7520 }
7521
7522 // ---------------- Upcasts
7523
7524 static inline wuffs_base__io_transformer*
wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(wuffs_lzw__decoder * p)7525 wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(
7526 wuffs_lzw__decoder* p) {
7527 return (wuffs_base__io_transformer*)p;
7528 }
7529
7530 // ---------------- Public Function Prototypes
7531
7532 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7533 wuffs_lzw__decoder__set_quirk_enabled(
7534 wuffs_lzw__decoder* self,
7535 uint32_t a_quirk,
7536 bool a_enabled);
7537
7538 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7539 wuffs_lzw__decoder__set_literal_width(
7540 wuffs_lzw__decoder* self,
7541 uint32_t a_lw);
7542
7543 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7544 wuffs_lzw__decoder__workbuf_len(
7545 const wuffs_lzw__decoder* self);
7546
7547 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7548 wuffs_lzw__decoder__transform_io(
7549 wuffs_lzw__decoder* self,
7550 wuffs_base__io_buffer* a_dst,
7551 wuffs_base__io_buffer* a_src,
7552 wuffs_base__slice_u8 a_workbuf);
7553
7554 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
7555 wuffs_lzw__decoder__flush(
7556 wuffs_lzw__decoder* self);
7557
7558 #ifdef __cplusplus
7559 } // extern "C"
7560 #endif
7561
7562 // ---------------- Struct Definitions
7563
7564 // These structs' fields, and the sizeof them, are private implementation
7565 // details that aren't guaranteed to be stable across Wuffs versions.
7566 //
7567 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7568
7569 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7570
7571 struct wuffs_lzw__decoder__struct {
7572 // Do not access the private_impl's or private_data's fields directly. There
7573 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7574 // the wuffs_foo__bar__baz functions.
7575 //
7576 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7577 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7578
7579 struct {
7580 uint32_t magic;
7581 uint32_t active_coroutine;
7582 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
7583 wuffs_base__vtable null_vtable;
7584
7585 uint32_t f_set_literal_width_arg;
7586 uint32_t f_literal_width;
7587 uint32_t f_clear_code;
7588 uint32_t f_end_code;
7589 uint32_t f_save_code;
7590 uint32_t f_prev_code;
7591 uint32_t f_width;
7592 uint32_t f_bits;
7593 uint32_t f_n_bits;
7594 uint32_t f_output_ri;
7595 uint32_t f_output_wi;
7596 uint32_t f_read_from_return_value;
7597 uint16_t f_prefixes[4096];
7598
7599 uint32_t p_transform_io[1];
7600 uint32_t p_write_to[1];
7601 } private_impl;
7602
7603 struct {
7604 uint8_t f_suffixes[4096][8];
7605 uint16_t f_lm1s[4096];
7606 uint8_t f_output[8199];
7607 } private_data;
7608
7609 #ifdef __cplusplus
7610 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7611 using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, decltype(&free)>;
7612
7613 // On failure, the alloc_etc functions return nullptr. They don't throw.
7614
7615 static inline unique_ptr
allocwuffs_lzw__decoder__struct7616 alloc() {
7617 return unique_ptr(wuffs_lzw__decoder__alloc(), &free);
7618 }
7619
7620 static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct7621 alloc_as__wuffs_base__io_transformer() {
7622 return wuffs_base__io_transformer::unique_ptr(
7623 wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(), &free);
7624 }
7625 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7626
7627 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7628 // Disallow constructing or copying an object via standard C++ mechanisms,
7629 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
7630 // size and field layout is not part of the public, stable, memory-safe API.
7631 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
7632 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
7633 // their first argument) rather than tweaking bar.private_impl.qux fields.
7634 //
7635 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
7636 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
7637 // order to provide convenience methods. These forward on "this", so that you
7638 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
7639 wuffs_lzw__decoder__struct() = delete;
7640 wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
7641 wuffs_lzw__decoder__struct& operator=(
7642 const wuffs_lzw__decoder__struct&) = delete;
7643 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
7644
7645 #if !defined(WUFFS_IMPLEMENTATION)
7646 // As above, the size of the struct is not part of the public API, and unless
7647 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
7648 // allocated, not stack allocated. Its size is not intended to be known at
7649 // compile time, but it is unfortunately divulged as a side effect of
7650 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
7651 // instead of "sizeof T", invoking the operator. To make the two values
7652 // different, so that passing the latter will be rejected by the initialize
7653 // function, we add an arbitrary amount of dead weight.
7654 uint8_t dead_weight[123000000]; // 123 MB.
7655 #endif // !defined(WUFFS_IMPLEMENTATION)
7656
7657 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_lzw__decoder__struct7658 initialize(
7659 size_t sizeof_star_self,
7660 uint64_t wuffs_version,
7661 uint32_t options) {
7662 return wuffs_lzw__decoder__initialize(
7663 this, sizeof_star_self, wuffs_version, options);
7664 }
7665
7666 inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_lzw__decoder__struct7667 upcast_as__wuffs_base__io_transformer() {
7668 return (wuffs_base__io_transformer*)this;
7669 }
7670
7671 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_lzw__decoder__struct7672 set_quirk_enabled(
7673 uint32_t a_quirk,
7674 bool a_enabled) {
7675 return wuffs_lzw__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
7676 }
7677
7678 inline wuffs_base__empty_struct
set_literal_widthwuffs_lzw__decoder__struct7679 set_literal_width(
7680 uint32_t a_lw) {
7681 return wuffs_lzw__decoder__set_literal_width(this, a_lw);
7682 }
7683
7684 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_lzw__decoder__struct7685 workbuf_len() const {
7686 return wuffs_lzw__decoder__workbuf_len(this);
7687 }
7688
7689 inline wuffs_base__status
transform_iowuffs_lzw__decoder__struct7690 transform_io(
7691 wuffs_base__io_buffer* a_dst,
7692 wuffs_base__io_buffer* a_src,
7693 wuffs_base__slice_u8 a_workbuf) {
7694 return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf);
7695 }
7696
7697 inline wuffs_base__slice_u8
flushwuffs_lzw__decoder__struct7698 flush() {
7699 return wuffs_lzw__decoder__flush(this);
7700 }
7701
7702 #endif // __cplusplus
7703 }; // struct wuffs_lzw__decoder__struct
7704
7705 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7706
7707 // ---------------- Status Codes
7708
7709 extern const char wuffs_gif__error__bad_extension_label[];
7710 extern const char wuffs_gif__error__bad_frame_size[];
7711 extern const char wuffs_gif__error__bad_graphic_control[];
7712 extern const char wuffs_gif__error__bad_header[];
7713 extern const char wuffs_gif__error__bad_literal_width[];
7714 extern const char wuffs_gif__error__bad_palette[];
7715
7716 // ---------------- Public Consts
7717
7718 #define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
7719
7720 #define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328
7721
7722 #define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329
7723
7724 #define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330
7725
7726 #define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331
7727
7728 #define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332
7729
7730 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333
7731
7732 #define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334
7733
7734 // ---------------- Struct Declarations
7735
7736 typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder;
7737
7738 #ifdef __cplusplus
7739 extern "C" {
7740 #endif
7741
7742 // ---------------- Public Initializer Prototypes
7743
7744 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
7745 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
7746 //
7747 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
7748 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
7749
7750 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
7751 wuffs_gif__decoder__initialize(
7752 wuffs_gif__decoder* self,
7753 size_t sizeof_star_self,
7754 uint64_t wuffs_version,
7755 uint32_t options);
7756
7757 size_t
7758 sizeof__wuffs_gif__decoder();
7759
7760 // ---------------- Allocs
7761
7762 // These functions allocate and initialize Wuffs structs. They return NULL if
7763 // memory allocation fails. If they return non-NULL, there is no need to call
7764 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
7765 // calling free on the returned pointer. That pointer is effectively a C++
7766 // std::unique_ptr<T, decltype(&free)>.
7767
7768 wuffs_gif__decoder*
7769 wuffs_gif__decoder__alloc();
7770
7771 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder()7772 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder() {
7773 return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
7774 }
7775
7776 // ---------------- Upcasts
7777
7778 static inline wuffs_base__image_decoder*
wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(wuffs_gif__decoder * p)7779 wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
7780 wuffs_gif__decoder* p) {
7781 return (wuffs_base__image_decoder*)p;
7782 }
7783
7784 // ---------------- Public Function Prototypes
7785
7786 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7787 wuffs_gif__decoder__set_quirk_enabled(
7788 wuffs_gif__decoder* self,
7789 uint32_t a_quirk,
7790 bool a_enabled);
7791
7792 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7793 wuffs_gif__decoder__decode_image_config(
7794 wuffs_gif__decoder* self,
7795 wuffs_base__image_config* a_dst,
7796 wuffs_base__io_buffer* a_src);
7797
7798 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
7799 wuffs_gif__decoder__set_report_metadata(
7800 wuffs_gif__decoder* self,
7801 uint32_t a_fourcc,
7802 bool a_report);
7803
7804 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7805 wuffs_gif__decoder__tell_me_more(
7806 wuffs_gif__decoder* self,
7807 wuffs_base__io_buffer* a_dst,
7808 wuffs_base__more_information* a_minfo,
7809 wuffs_base__io_buffer* a_src);
7810
7811 WUFFS_BASE__MAYBE_STATIC uint32_t
7812 wuffs_gif__decoder__num_animation_loops(
7813 const wuffs_gif__decoder* self);
7814
7815 WUFFS_BASE__MAYBE_STATIC uint64_t
7816 wuffs_gif__decoder__num_decoded_frame_configs(
7817 const wuffs_gif__decoder* self);
7818
7819 WUFFS_BASE__MAYBE_STATIC uint64_t
7820 wuffs_gif__decoder__num_decoded_frames(
7821 const wuffs_gif__decoder* self);
7822
7823 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
7824 wuffs_gif__decoder__frame_dirty_rect(
7825 const wuffs_gif__decoder* self);
7826
7827 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
7828 wuffs_gif__decoder__workbuf_len(
7829 const wuffs_gif__decoder* self);
7830
7831 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7832 wuffs_gif__decoder__restart_frame(
7833 wuffs_gif__decoder* self,
7834 uint64_t a_index,
7835 uint64_t a_io_position);
7836
7837 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7838 wuffs_gif__decoder__decode_frame_config(
7839 wuffs_gif__decoder* self,
7840 wuffs_base__frame_config* a_dst,
7841 wuffs_base__io_buffer* a_src);
7842
7843 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
7844 wuffs_gif__decoder__decode_frame(
7845 wuffs_gif__decoder* self,
7846 wuffs_base__pixel_buffer* a_dst,
7847 wuffs_base__io_buffer* a_src,
7848 wuffs_base__pixel_blend a_blend,
7849 wuffs_base__slice_u8 a_workbuf,
7850 wuffs_base__decode_frame_options* a_opts);
7851
7852 #ifdef __cplusplus
7853 } // extern "C"
7854 #endif
7855
7856 // ---------------- Struct Definitions
7857
7858 // These structs' fields, and the sizeof them, are private implementation
7859 // details that aren't guaranteed to be stable across Wuffs versions.
7860 //
7861 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
7862
7863 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
7864
7865 struct wuffs_gif__decoder__struct {
7866 // Do not access the private_impl's or private_data's fields directly. There
7867 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
7868 // the wuffs_foo__bar__baz functions.
7869 //
7870 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
7871 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
7872
7873 struct {
7874 uint32_t magic;
7875 uint32_t active_coroutine;
7876 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
7877 wuffs_base__vtable null_vtable;
7878
7879 uint32_t f_width;
7880 uint32_t f_height;
7881 uint8_t f_call_sequence;
7882 bool f_ignore_metadata;
7883 bool f_report_metadata_iccp;
7884 bool f_report_metadata_xmp;
7885 uint32_t f_metadata_fourcc;
7886 uint64_t f_metadata_io_position;
7887 bool f_quirks[7];
7888 bool f_delayed_num_decoded_frames;
7889 bool f_end_of_data;
7890 bool f_restarted;
7891 bool f_previous_lzw_decode_ended_abruptly;
7892 bool f_has_global_palette;
7893 uint8_t f_interlace;
7894 bool f_seen_num_animation_loops_value;
7895 uint32_t f_num_animation_loops_value;
7896 uint32_t f_background_color_u32_argb_premul;
7897 uint32_t f_black_color_u32_argb_premul;
7898 bool f_gc_has_transparent_index;
7899 uint8_t f_gc_transparent_index;
7900 uint8_t f_gc_disposal;
7901 uint64_t f_gc_duration;
7902 uint64_t f_frame_config_io_position;
7903 uint64_t f_num_decoded_frame_configs_value;
7904 uint64_t f_num_decoded_frames_value;
7905 uint32_t f_frame_rect_x0;
7906 uint32_t f_frame_rect_y0;
7907 uint32_t f_frame_rect_x1;
7908 uint32_t f_frame_rect_y1;
7909 uint32_t f_dst_x;
7910 uint32_t f_dst_y;
7911 uint32_t f_dirty_max_excl_y;
7912 uint64_t f_compressed_ri;
7913 uint64_t f_compressed_wi;
7914 wuffs_base__pixel_swizzler f_swizzler;
7915
7916 uint32_t p_decode_image_config[1];
7917 uint32_t p_tell_me_more[1];
7918 uint32_t p_decode_frame_config[1];
7919 uint32_t p_skip_frame[1];
7920 uint32_t p_decode_frame[1];
7921 uint32_t p_decode_up_to_id_part1[1];
7922 uint32_t p_decode_header[1];
7923 uint32_t p_decode_lsd[1];
7924 uint32_t p_decode_extension[1];
7925 uint32_t p_skip_blocks[1];
7926 uint32_t p_decode_ae[1];
7927 uint32_t p_decode_gc[1];
7928 uint32_t p_decode_id_part0[1];
7929 uint32_t p_decode_id_part1[1];
7930 uint32_t p_decode_id_part2[1];
7931 } private_impl;
7932
7933 struct {
7934 uint8_t f_compressed[4096];
7935 uint8_t f_palettes[2][1024];
7936 uint8_t f_dst_palette[1024];
7937 wuffs_lzw__decoder f_lzw;
7938
7939 struct {
7940 uint32_t v_background_color;
7941 } s_decode_frame_config[1];
7942 struct {
7943 uint64_t scratch;
7944 } s_skip_frame[1];
7945 struct {
7946 uint8_t v_c[6];
7947 uint32_t v_i;
7948 } s_decode_header[1];
7949 struct {
7950 uint8_t v_flags;
7951 uint8_t v_background_color_index;
7952 uint32_t v_num_palette_entries;
7953 uint32_t v_i;
7954 uint64_t scratch;
7955 } s_decode_lsd[1];
7956 struct {
7957 uint64_t scratch;
7958 } s_skip_blocks[1];
7959 struct {
7960 uint8_t v_block_size;
7961 bool v_is_animexts;
7962 bool v_is_netscape;
7963 bool v_is_iccp;
7964 bool v_is_xmp;
7965 uint64_t scratch;
7966 } s_decode_ae[1];
7967 struct {
7968 uint64_t scratch;
7969 } s_decode_gc[1];
7970 struct {
7971 uint64_t scratch;
7972 } s_decode_id_part0[1];
7973 struct {
7974 uint8_t v_which_palette;
7975 uint32_t v_num_palette_entries;
7976 uint32_t v_i;
7977 uint64_t scratch;
7978 } s_decode_id_part1[1];
7979 struct {
7980 uint64_t v_block_size;
7981 bool v_need_block_size;
7982 wuffs_base__status v_lzw_status;
7983 uint64_t scratch;
7984 } s_decode_id_part2[1];
7985 } private_data;
7986
7987 #ifdef __cplusplus
7988 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
7989 using unique_ptr = std::unique_ptr<wuffs_gif__decoder, decltype(&free)>;
7990
7991 // On failure, the alloc_etc functions return nullptr. They don't throw.
7992
7993 static inline unique_ptr
allocwuffs_gif__decoder__struct7994 alloc() {
7995 return unique_ptr(wuffs_gif__decoder__alloc(), &free);
7996 }
7997
7998 static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_gif__decoder__struct7999 alloc_as__wuffs_base__image_decoder() {
8000 return wuffs_base__image_decoder::unique_ptr(
8001 wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(), &free);
8002 }
8003 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8004
8005 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8006 // Disallow constructing or copying an object via standard C++ mechanisms,
8007 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8008 // size and field layout is not part of the public, stable, memory-safe API.
8009 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8010 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8011 // their first argument) rather than tweaking bar.private_impl.qux fields.
8012 //
8013 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8014 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8015 // order to provide convenience methods. These forward on "this", so that you
8016 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8017 wuffs_gif__decoder__struct() = delete;
8018 wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
8019 wuffs_gif__decoder__struct& operator=(
8020 const wuffs_gif__decoder__struct&) = delete;
8021 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8022
8023 #if !defined(WUFFS_IMPLEMENTATION)
8024 // As above, the size of the struct is not part of the public API, and unless
8025 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8026 // allocated, not stack allocated. Its size is not intended to be known at
8027 // compile time, but it is unfortunately divulged as a side effect of
8028 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8029 // instead of "sizeof T", invoking the operator. To make the two values
8030 // different, so that passing the latter will be rejected by the initialize
8031 // function, we add an arbitrary amount of dead weight.
8032 uint8_t dead_weight[123000000]; // 123 MB.
8033 #endif // !defined(WUFFS_IMPLEMENTATION)
8034
8035 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_gif__decoder__struct8036 initialize(
8037 size_t sizeof_star_self,
8038 uint64_t wuffs_version,
8039 uint32_t options) {
8040 return wuffs_gif__decoder__initialize(
8041 this, sizeof_star_self, wuffs_version, options);
8042 }
8043
8044 inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_gif__decoder__struct8045 upcast_as__wuffs_base__image_decoder() {
8046 return (wuffs_base__image_decoder*)this;
8047 }
8048
8049 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_gif__decoder__struct8050 set_quirk_enabled(
8051 uint32_t a_quirk,
8052 bool a_enabled) {
8053 return wuffs_gif__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8054 }
8055
8056 inline wuffs_base__status
decode_image_configwuffs_gif__decoder__struct8057 decode_image_config(
8058 wuffs_base__image_config* a_dst,
8059 wuffs_base__io_buffer* a_src) {
8060 return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
8061 }
8062
8063 inline wuffs_base__empty_struct
set_report_metadatawuffs_gif__decoder__struct8064 set_report_metadata(
8065 uint32_t a_fourcc,
8066 bool a_report) {
8067 return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
8068 }
8069
8070 inline wuffs_base__status
tell_me_morewuffs_gif__decoder__struct8071 tell_me_more(
8072 wuffs_base__io_buffer* a_dst,
8073 wuffs_base__more_information* a_minfo,
8074 wuffs_base__io_buffer* a_src) {
8075 return wuffs_gif__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
8076 }
8077
8078 inline uint32_t
num_animation_loopswuffs_gif__decoder__struct8079 num_animation_loops() const {
8080 return wuffs_gif__decoder__num_animation_loops(this);
8081 }
8082
8083 inline uint64_t
num_decoded_frame_configswuffs_gif__decoder__struct8084 num_decoded_frame_configs() const {
8085 return wuffs_gif__decoder__num_decoded_frame_configs(this);
8086 }
8087
8088 inline uint64_t
num_decoded_frameswuffs_gif__decoder__struct8089 num_decoded_frames() const {
8090 return wuffs_gif__decoder__num_decoded_frames(this);
8091 }
8092
8093 inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_gif__decoder__struct8094 frame_dirty_rect() const {
8095 return wuffs_gif__decoder__frame_dirty_rect(this);
8096 }
8097
8098 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gif__decoder__struct8099 workbuf_len() const {
8100 return wuffs_gif__decoder__workbuf_len(this);
8101 }
8102
8103 inline wuffs_base__status
restart_framewuffs_gif__decoder__struct8104 restart_frame(
8105 uint64_t a_index,
8106 uint64_t a_io_position) {
8107 return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
8108 }
8109
8110 inline wuffs_base__status
decode_frame_configwuffs_gif__decoder__struct8111 decode_frame_config(
8112 wuffs_base__frame_config* a_dst,
8113 wuffs_base__io_buffer* a_src) {
8114 return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
8115 }
8116
8117 inline wuffs_base__status
decode_framewuffs_gif__decoder__struct8118 decode_frame(
8119 wuffs_base__pixel_buffer* a_dst,
8120 wuffs_base__io_buffer* a_src,
8121 wuffs_base__pixel_blend a_blend,
8122 wuffs_base__slice_u8 a_workbuf,
8123 wuffs_base__decode_frame_options* a_opts) {
8124 return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
8125 }
8126
8127 #endif // __cplusplus
8128 }; // struct wuffs_gif__decoder__struct
8129
8130 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8131
8132 // ---------------- Status Codes
8133
8134 extern const char wuffs_gzip__error__bad_checksum[];
8135 extern const char wuffs_gzip__error__bad_compression_method[];
8136 extern const char wuffs_gzip__error__bad_encoding_flags[];
8137 extern const char wuffs_gzip__error__bad_header[];
8138
8139 // ---------------- Public Consts
8140
8141 #define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8142
8143 // ---------------- Struct Declarations
8144
8145 typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
8146
8147 #ifdef __cplusplus
8148 extern "C" {
8149 #endif
8150
8151 // ---------------- Public Initializer Prototypes
8152
8153 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8154 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8155 //
8156 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8157 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8158
8159 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8160 wuffs_gzip__decoder__initialize(
8161 wuffs_gzip__decoder* self,
8162 size_t sizeof_star_self,
8163 uint64_t wuffs_version,
8164 uint32_t options);
8165
8166 size_t
8167 sizeof__wuffs_gzip__decoder();
8168
8169 // ---------------- Allocs
8170
8171 // These functions allocate and initialize Wuffs structs. They return NULL if
8172 // memory allocation fails. If they return non-NULL, there is no need to call
8173 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8174 // calling free on the returned pointer. That pointer is effectively a C++
8175 // std::unique_ptr<T, decltype(&free)>.
8176
8177 wuffs_gzip__decoder*
8178 wuffs_gzip__decoder__alloc();
8179
8180 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer()8181 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer() {
8182 return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
8183 }
8184
8185 // ---------------- Upcasts
8186
8187 static inline wuffs_base__io_transformer*
wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(wuffs_gzip__decoder * p)8188 wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(
8189 wuffs_gzip__decoder* p) {
8190 return (wuffs_base__io_transformer*)p;
8191 }
8192
8193 // ---------------- Public Function Prototypes
8194
8195 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8196 wuffs_gzip__decoder__set_quirk_enabled(
8197 wuffs_gzip__decoder* self,
8198 uint32_t a_quirk,
8199 bool a_enabled);
8200
8201 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8202 wuffs_gzip__decoder__workbuf_len(
8203 const wuffs_gzip__decoder* self);
8204
8205 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8206 wuffs_gzip__decoder__transform_io(
8207 wuffs_gzip__decoder* self,
8208 wuffs_base__io_buffer* a_dst,
8209 wuffs_base__io_buffer* a_src,
8210 wuffs_base__slice_u8 a_workbuf);
8211
8212 #ifdef __cplusplus
8213 } // extern "C"
8214 #endif
8215
8216 // ---------------- Struct Definitions
8217
8218 // These structs' fields, and the sizeof them, are private implementation
8219 // details that aren't guaranteed to be stable across Wuffs versions.
8220 //
8221 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8222
8223 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8224
8225 struct wuffs_gzip__decoder__struct {
8226 // Do not access the private_impl's or private_data's fields directly. There
8227 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8228 // the wuffs_foo__bar__baz functions.
8229 //
8230 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8231 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8232
8233 struct {
8234 uint32_t magic;
8235 uint32_t active_coroutine;
8236 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
8237 wuffs_base__vtable null_vtable;
8238
8239 bool f_ignore_checksum;
8240
8241 uint32_t p_transform_io[1];
8242 } private_impl;
8243
8244 struct {
8245 wuffs_crc32__ieee_hasher f_checksum;
8246 wuffs_deflate__decoder f_flate;
8247
8248 struct {
8249 uint8_t v_flags;
8250 uint32_t v_checksum_got;
8251 uint32_t v_decoded_length_got;
8252 uint32_t v_checksum_want;
8253 uint64_t scratch;
8254 } s_transform_io[1];
8255 } private_data;
8256
8257 #ifdef __cplusplus
8258 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8259 using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, decltype(&free)>;
8260
8261 // On failure, the alloc_etc functions return nullptr. They don't throw.
8262
8263 static inline unique_ptr
allocwuffs_gzip__decoder__struct8264 alloc() {
8265 return unique_ptr(wuffs_gzip__decoder__alloc(), &free);
8266 }
8267
8268 static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct8269 alloc_as__wuffs_base__io_transformer() {
8270 return wuffs_base__io_transformer::unique_ptr(
8271 wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(), &free);
8272 }
8273 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8274
8275 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8276 // Disallow constructing or copying an object via standard C++ mechanisms,
8277 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8278 // size and field layout is not part of the public, stable, memory-safe API.
8279 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8280 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8281 // their first argument) rather than tweaking bar.private_impl.qux fields.
8282 //
8283 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8284 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8285 // order to provide convenience methods. These forward on "this", so that you
8286 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8287 wuffs_gzip__decoder__struct() = delete;
8288 wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
8289 wuffs_gzip__decoder__struct& operator=(
8290 const wuffs_gzip__decoder__struct&) = delete;
8291 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8292
8293 #if !defined(WUFFS_IMPLEMENTATION)
8294 // As above, the size of the struct is not part of the public API, and unless
8295 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8296 // allocated, not stack allocated. Its size is not intended to be known at
8297 // compile time, but it is unfortunately divulged as a side effect of
8298 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8299 // instead of "sizeof T", invoking the operator. To make the two values
8300 // different, so that passing the latter will be rejected by the initialize
8301 // function, we add an arbitrary amount of dead weight.
8302 uint8_t dead_weight[123000000]; // 123 MB.
8303 #endif // !defined(WUFFS_IMPLEMENTATION)
8304
8305 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_gzip__decoder__struct8306 initialize(
8307 size_t sizeof_star_self,
8308 uint64_t wuffs_version,
8309 uint32_t options) {
8310 return wuffs_gzip__decoder__initialize(
8311 this, sizeof_star_self, wuffs_version, options);
8312 }
8313
8314 inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_gzip__decoder__struct8315 upcast_as__wuffs_base__io_transformer() {
8316 return (wuffs_base__io_transformer*)this;
8317 }
8318
8319 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_gzip__decoder__struct8320 set_quirk_enabled(
8321 uint32_t a_quirk,
8322 bool a_enabled) {
8323 return wuffs_gzip__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8324 }
8325
8326 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_gzip__decoder__struct8327 workbuf_len() const {
8328 return wuffs_gzip__decoder__workbuf_len(this);
8329 }
8330
8331 inline wuffs_base__status
transform_iowuffs_gzip__decoder__struct8332 transform_io(
8333 wuffs_base__io_buffer* a_dst,
8334 wuffs_base__io_buffer* a_src,
8335 wuffs_base__slice_u8 a_workbuf) {
8336 return wuffs_gzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
8337 }
8338
8339 #endif // __cplusplus
8340 }; // struct wuffs_gzip__decoder__struct
8341
8342 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8343
8344 // ---------------- Status Codes
8345
8346 extern const char wuffs_json__error__bad_c0_control_code[];
8347 extern const char wuffs_json__error__bad_utf_8[];
8348 extern const char wuffs_json__error__bad_backslash_escape[];
8349 extern const char wuffs_json__error__bad_input[];
8350 extern const char wuffs_json__error__bad_new_line_in_a_string[];
8351 extern const char wuffs_json__error__bad_quirk_combination[];
8352 extern const char wuffs_json__error__unsupported_number_length[];
8353 extern const char wuffs_json__error__unsupported_recursion_depth[];
8354
8355 // ---------------- Public Consts
8356
8357 #define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
8358
8359 #define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024
8360
8361 #define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1
8362
8363 #define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100
8364
8365 #define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480
8366
8367 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481
8368
8369 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482
8370
8371 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483
8372
8373 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484
8374
8375 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485
8376
8377 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486
8378
8379 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487
8380
8381 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489
8382
8383 #define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490
8384
8385 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491
8386
8387 #define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492
8388
8389 #define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493
8390
8391 #define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494
8392
8393 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495
8394
8395 #define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496
8396
8397 #define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497
8398
8399 #define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498
8400
8401 #define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499
8402
8403 #define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500
8404
8405 // ---------------- Struct Declarations
8406
8407 typedef struct wuffs_json__decoder__struct wuffs_json__decoder;
8408
8409 #ifdef __cplusplus
8410 extern "C" {
8411 #endif
8412
8413 // ---------------- Public Initializer Prototypes
8414
8415 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8416 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8417 //
8418 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8419 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8420
8421 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8422 wuffs_json__decoder__initialize(
8423 wuffs_json__decoder* self,
8424 size_t sizeof_star_self,
8425 uint64_t wuffs_version,
8426 uint32_t options);
8427
8428 size_t
8429 sizeof__wuffs_json__decoder();
8430
8431 // ---------------- Allocs
8432
8433 // These functions allocate and initialize Wuffs structs. They return NULL if
8434 // memory allocation fails. If they return non-NULL, there is no need to call
8435 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8436 // calling free on the returned pointer. That pointer is effectively a C++
8437 // std::unique_ptr<T, decltype(&free)>.
8438
8439 wuffs_json__decoder*
8440 wuffs_json__decoder__alloc();
8441
8442 static inline wuffs_base__token_decoder*
wuffs_json__decoder__alloc_as__wuffs_base__token_decoder()8443 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder() {
8444 return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
8445 }
8446
8447 // ---------------- Upcasts
8448
8449 static inline wuffs_base__token_decoder*
wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(wuffs_json__decoder * p)8450 wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
8451 wuffs_json__decoder* p) {
8452 return (wuffs_base__token_decoder*)p;
8453 }
8454
8455 // ---------------- Public Function Prototypes
8456
8457 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8458 wuffs_json__decoder__set_quirk_enabled(
8459 wuffs_json__decoder* self,
8460 uint32_t a_quirk,
8461 bool a_enabled);
8462
8463 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8464 wuffs_json__decoder__workbuf_len(
8465 const wuffs_json__decoder* self);
8466
8467 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8468 wuffs_json__decoder__decode_tokens(
8469 wuffs_json__decoder* self,
8470 wuffs_base__token_buffer* a_dst,
8471 wuffs_base__io_buffer* a_src,
8472 wuffs_base__slice_u8 a_workbuf);
8473
8474 #ifdef __cplusplus
8475 } // extern "C"
8476 #endif
8477
8478 // ---------------- Struct Definitions
8479
8480 // These structs' fields, and the sizeof them, are private implementation
8481 // details that aren't guaranteed to be stable across Wuffs versions.
8482 //
8483 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8484
8485 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8486
8487 struct wuffs_json__decoder__struct {
8488 // Do not access the private_impl's or private_data's fields directly. There
8489 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8490 // the wuffs_foo__bar__baz functions.
8491 //
8492 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8493 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8494
8495 struct {
8496 uint32_t magic;
8497 uint32_t active_coroutine;
8498 wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
8499 wuffs_base__vtable null_vtable;
8500
8501 bool f_quirks[21];
8502 bool f_allow_leading_ars;
8503 bool f_allow_leading_ubom;
8504 bool f_end_of_data;
8505 uint8_t f_trailer_stop;
8506 uint8_t f_comment_type;
8507
8508 uint32_t p_decode_tokens[1];
8509 uint32_t p_decode_leading[1];
8510 uint32_t p_decode_comment[1];
8511 uint32_t p_decode_inf_nan[1];
8512 uint32_t p_decode_trailer[1];
8513 } private_impl;
8514
8515 struct {
8516 uint32_t f_stack[32];
8517
8518 struct {
8519 uint32_t v_depth;
8520 uint32_t v_expect;
8521 uint32_t v_expect_after_value;
8522 } s_decode_tokens[1];
8523 struct {
8524 uint32_t v_neg;
8525 } s_decode_inf_nan[1];
8526 } private_data;
8527
8528 #ifdef __cplusplus
8529 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8530 using unique_ptr = std::unique_ptr<wuffs_json__decoder, decltype(&free)>;
8531
8532 // On failure, the alloc_etc functions return nullptr. They don't throw.
8533
8534 static inline unique_ptr
allocwuffs_json__decoder__struct8535 alloc() {
8536 return unique_ptr(wuffs_json__decoder__alloc(), &free);
8537 }
8538
8539 static inline wuffs_base__token_decoder::unique_ptr
alloc_as__wuffs_base__token_decoderwuffs_json__decoder__struct8540 alloc_as__wuffs_base__token_decoder() {
8541 return wuffs_base__token_decoder::unique_ptr(
8542 wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(), &free);
8543 }
8544 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8545
8546 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8547 // Disallow constructing or copying an object via standard C++ mechanisms,
8548 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8549 // size and field layout is not part of the public, stable, memory-safe API.
8550 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8551 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8552 // their first argument) rather than tweaking bar.private_impl.qux fields.
8553 //
8554 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8555 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8556 // order to provide convenience methods. These forward on "this", so that you
8557 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8558 wuffs_json__decoder__struct() = delete;
8559 wuffs_json__decoder__struct(const wuffs_json__decoder__struct&) = delete;
8560 wuffs_json__decoder__struct& operator=(
8561 const wuffs_json__decoder__struct&) = delete;
8562 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8563
8564 #if !defined(WUFFS_IMPLEMENTATION)
8565 // As above, the size of the struct is not part of the public API, and unless
8566 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8567 // allocated, not stack allocated. Its size is not intended to be known at
8568 // compile time, but it is unfortunately divulged as a side effect of
8569 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8570 // instead of "sizeof T", invoking the operator. To make the two values
8571 // different, so that passing the latter will be rejected by the initialize
8572 // function, we add an arbitrary amount of dead weight.
8573 uint8_t dead_weight[123000000]; // 123 MB.
8574 #endif // !defined(WUFFS_IMPLEMENTATION)
8575
8576 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_json__decoder__struct8577 initialize(
8578 size_t sizeof_star_self,
8579 uint64_t wuffs_version,
8580 uint32_t options) {
8581 return wuffs_json__decoder__initialize(
8582 this, sizeof_star_self, wuffs_version, options);
8583 }
8584
8585 inline wuffs_base__token_decoder*
upcast_as__wuffs_base__token_decoderwuffs_json__decoder__struct8586 upcast_as__wuffs_base__token_decoder() {
8587 return (wuffs_base__token_decoder*)this;
8588 }
8589
8590 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_json__decoder__struct8591 set_quirk_enabled(
8592 uint32_t a_quirk,
8593 bool a_enabled) {
8594 return wuffs_json__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8595 }
8596
8597 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_json__decoder__struct8598 workbuf_len() const {
8599 return wuffs_json__decoder__workbuf_len(this);
8600 }
8601
8602 inline wuffs_base__status
decode_tokenswuffs_json__decoder__struct8603 decode_tokens(
8604 wuffs_base__token_buffer* a_dst,
8605 wuffs_base__io_buffer* a_src,
8606 wuffs_base__slice_u8 a_workbuf) {
8607 return wuffs_json__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
8608 }
8609
8610 #endif // __cplusplus
8611 }; // struct wuffs_json__decoder__struct
8612
8613 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8614
8615 // ---------------- Status Codes
8616
8617 extern const char wuffs_nie__error__bad_header[];
8618 extern const char wuffs_nie__error__unsupported_nie_file[];
8619
8620 // ---------------- Public Consts
8621
8622 #define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
8623
8624 // ---------------- Struct Declarations
8625
8626 typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder;
8627
8628 #ifdef __cplusplus
8629 extern "C" {
8630 #endif
8631
8632 // ---------------- Public Initializer Prototypes
8633
8634 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8635 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8636 //
8637 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8638 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8639
8640 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8641 wuffs_nie__decoder__initialize(
8642 wuffs_nie__decoder* self,
8643 size_t sizeof_star_self,
8644 uint64_t wuffs_version,
8645 uint32_t options);
8646
8647 size_t
8648 sizeof__wuffs_nie__decoder();
8649
8650 // ---------------- Allocs
8651
8652 // These functions allocate and initialize Wuffs structs. They return NULL if
8653 // memory allocation fails. If they return non-NULL, there is no need to call
8654 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8655 // calling free on the returned pointer. That pointer is effectively a C++
8656 // std::unique_ptr<T, decltype(&free)>.
8657
8658 wuffs_nie__decoder*
8659 wuffs_nie__decoder__alloc();
8660
8661 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder()8662 wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder() {
8663 return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc());
8664 }
8665
8666 // ---------------- Upcasts
8667
8668 static inline wuffs_base__image_decoder*
wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(wuffs_nie__decoder * p)8669 wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(
8670 wuffs_nie__decoder* p) {
8671 return (wuffs_base__image_decoder*)p;
8672 }
8673
8674 // ---------------- Public Function Prototypes
8675
8676 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8677 wuffs_nie__decoder__set_quirk_enabled(
8678 wuffs_nie__decoder* self,
8679 uint32_t a_quirk,
8680 bool a_enabled);
8681
8682 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8683 wuffs_nie__decoder__decode_image_config(
8684 wuffs_nie__decoder* self,
8685 wuffs_base__image_config* a_dst,
8686 wuffs_base__io_buffer* a_src);
8687
8688 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8689 wuffs_nie__decoder__decode_frame_config(
8690 wuffs_nie__decoder* self,
8691 wuffs_base__frame_config* a_dst,
8692 wuffs_base__io_buffer* a_src);
8693
8694 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8695 wuffs_nie__decoder__decode_frame(
8696 wuffs_nie__decoder* self,
8697 wuffs_base__pixel_buffer* a_dst,
8698 wuffs_base__io_buffer* a_src,
8699 wuffs_base__pixel_blend a_blend,
8700 wuffs_base__slice_u8 a_workbuf,
8701 wuffs_base__decode_frame_options* a_opts);
8702
8703 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
8704 wuffs_nie__decoder__frame_dirty_rect(
8705 const wuffs_nie__decoder* self);
8706
8707 WUFFS_BASE__MAYBE_STATIC uint32_t
8708 wuffs_nie__decoder__num_animation_loops(
8709 const wuffs_nie__decoder* self);
8710
8711 WUFFS_BASE__MAYBE_STATIC uint64_t
8712 wuffs_nie__decoder__num_decoded_frame_configs(
8713 const wuffs_nie__decoder* self);
8714
8715 WUFFS_BASE__MAYBE_STATIC uint64_t
8716 wuffs_nie__decoder__num_decoded_frames(
8717 const wuffs_nie__decoder* self);
8718
8719 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8720 wuffs_nie__decoder__restart_frame(
8721 wuffs_nie__decoder* self,
8722 uint64_t a_index,
8723 uint64_t a_io_position);
8724
8725 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
8726 wuffs_nie__decoder__set_report_metadata(
8727 wuffs_nie__decoder* self,
8728 uint32_t a_fourcc,
8729 bool a_report);
8730
8731 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
8732 wuffs_nie__decoder__tell_me_more(
8733 wuffs_nie__decoder* self,
8734 wuffs_base__io_buffer* a_dst,
8735 wuffs_base__more_information* a_minfo,
8736 wuffs_base__io_buffer* a_src);
8737
8738 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
8739 wuffs_nie__decoder__workbuf_len(
8740 const wuffs_nie__decoder* self);
8741
8742 #ifdef __cplusplus
8743 } // extern "C"
8744 #endif
8745
8746 // ---------------- Struct Definitions
8747
8748 // These structs' fields, and the sizeof them, are private implementation
8749 // details that aren't guaranteed to be stable across Wuffs versions.
8750 //
8751 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
8752
8753 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8754
8755 struct wuffs_nie__decoder__struct {
8756 // Do not access the private_impl's or private_data's fields directly. There
8757 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
8758 // the wuffs_foo__bar__baz functions.
8759 //
8760 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
8761 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
8762
8763 struct {
8764 uint32_t magic;
8765 uint32_t active_coroutine;
8766 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
8767 wuffs_base__vtable null_vtable;
8768
8769 uint32_t f_pixfmt;
8770 uint32_t f_width;
8771 uint32_t f_height;
8772 uint8_t f_call_sequence;
8773 uint32_t f_dst_x;
8774 uint32_t f_dst_y;
8775 wuffs_base__pixel_swizzler f_swizzler;
8776
8777 uint32_t p_decode_image_config[1];
8778 uint32_t p_decode_frame_config[1];
8779 uint32_t p_decode_frame[1];
8780 } private_impl;
8781
8782 struct {
8783 struct {
8784 uint64_t scratch;
8785 } s_decode_image_config[1];
8786 } private_data;
8787
8788 #ifdef __cplusplus
8789 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8790 using unique_ptr = std::unique_ptr<wuffs_nie__decoder, decltype(&free)>;
8791
8792 // On failure, the alloc_etc functions return nullptr. They don't throw.
8793
8794 static inline unique_ptr
allocwuffs_nie__decoder__struct8795 alloc() {
8796 return unique_ptr(wuffs_nie__decoder__alloc(), &free);
8797 }
8798
8799 static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_nie__decoder__struct8800 alloc_as__wuffs_base__image_decoder() {
8801 return wuffs_base__image_decoder::unique_ptr(
8802 wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(), &free);
8803 }
8804 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
8805
8806 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8807 // Disallow constructing or copying an object via standard C++ mechanisms,
8808 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
8809 // size and field layout is not part of the public, stable, memory-safe API.
8810 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
8811 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
8812 // their first argument) rather than tweaking bar.private_impl.qux fields.
8813 //
8814 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
8815 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
8816 // order to provide convenience methods. These forward on "this", so that you
8817 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
8818 wuffs_nie__decoder__struct() = delete;
8819 wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete;
8820 wuffs_nie__decoder__struct& operator=(
8821 const wuffs_nie__decoder__struct&) = delete;
8822 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
8823
8824 #if !defined(WUFFS_IMPLEMENTATION)
8825 // As above, the size of the struct is not part of the public API, and unless
8826 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
8827 // allocated, not stack allocated. Its size is not intended to be known at
8828 // compile time, but it is unfortunately divulged as a side effect of
8829 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
8830 // instead of "sizeof T", invoking the operator. To make the two values
8831 // different, so that passing the latter will be rejected by the initialize
8832 // function, we add an arbitrary amount of dead weight.
8833 uint8_t dead_weight[123000000]; // 123 MB.
8834 #endif // !defined(WUFFS_IMPLEMENTATION)
8835
8836 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_nie__decoder__struct8837 initialize(
8838 size_t sizeof_star_self,
8839 uint64_t wuffs_version,
8840 uint32_t options) {
8841 return wuffs_nie__decoder__initialize(
8842 this, sizeof_star_self, wuffs_version, options);
8843 }
8844
8845 inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_nie__decoder__struct8846 upcast_as__wuffs_base__image_decoder() {
8847 return (wuffs_base__image_decoder*)this;
8848 }
8849
8850 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_nie__decoder__struct8851 set_quirk_enabled(
8852 uint32_t a_quirk,
8853 bool a_enabled) {
8854 return wuffs_nie__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
8855 }
8856
8857 inline wuffs_base__status
decode_image_configwuffs_nie__decoder__struct8858 decode_image_config(
8859 wuffs_base__image_config* a_dst,
8860 wuffs_base__io_buffer* a_src) {
8861 return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src);
8862 }
8863
8864 inline wuffs_base__status
decode_frame_configwuffs_nie__decoder__struct8865 decode_frame_config(
8866 wuffs_base__frame_config* a_dst,
8867 wuffs_base__io_buffer* a_src) {
8868 return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src);
8869 }
8870
8871 inline wuffs_base__status
decode_framewuffs_nie__decoder__struct8872 decode_frame(
8873 wuffs_base__pixel_buffer* a_dst,
8874 wuffs_base__io_buffer* a_src,
8875 wuffs_base__pixel_blend a_blend,
8876 wuffs_base__slice_u8 a_workbuf,
8877 wuffs_base__decode_frame_options* a_opts) {
8878 return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
8879 }
8880
8881 inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_nie__decoder__struct8882 frame_dirty_rect() const {
8883 return wuffs_nie__decoder__frame_dirty_rect(this);
8884 }
8885
8886 inline uint32_t
num_animation_loopswuffs_nie__decoder__struct8887 num_animation_loops() const {
8888 return wuffs_nie__decoder__num_animation_loops(this);
8889 }
8890
8891 inline uint64_t
num_decoded_frame_configswuffs_nie__decoder__struct8892 num_decoded_frame_configs() const {
8893 return wuffs_nie__decoder__num_decoded_frame_configs(this);
8894 }
8895
8896 inline uint64_t
num_decoded_frameswuffs_nie__decoder__struct8897 num_decoded_frames() const {
8898 return wuffs_nie__decoder__num_decoded_frames(this);
8899 }
8900
8901 inline wuffs_base__status
restart_framewuffs_nie__decoder__struct8902 restart_frame(
8903 uint64_t a_index,
8904 uint64_t a_io_position) {
8905 return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position);
8906 }
8907
8908 inline wuffs_base__empty_struct
set_report_metadatawuffs_nie__decoder__struct8909 set_report_metadata(
8910 uint32_t a_fourcc,
8911 bool a_report) {
8912 return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report);
8913 }
8914
8915 inline wuffs_base__status
tell_me_morewuffs_nie__decoder__struct8916 tell_me_more(
8917 wuffs_base__io_buffer* a_dst,
8918 wuffs_base__more_information* a_minfo,
8919 wuffs_base__io_buffer* a_src) {
8920 return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
8921 }
8922
8923 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_nie__decoder__struct8924 workbuf_len() const {
8925 return wuffs_nie__decoder__workbuf_len(this);
8926 }
8927
8928 #endif // __cplusplus
8929 }; // struct wuffs_nie__decoder__struct
8930
8931 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
8932
8933 // ---------------- Status Codes
8934
8935 extern const char wuffs_zlib__note__dictionary_required[];
8936 extern const char wuffs_zlib__error__bad_checksum[];
8937 extern const char wuffs_zlib__error__bad_compression_method[];
8938 extern const char wuffs_zlib__error__bad_compression_window_size[];
8939 extern const char wuffs_zlib__error__bad_parity_check[];
8940 extern const char wuffs_zlib__error__incorrect_dictionary[];
8941
8942 // ---------------- Public Consts
8943
8944 #define WUFFS_ZLIB__QUIRK_JUST_RAW_DEFLATE 2113790976
8945
8946 #define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
8947
8948 // ---------------- Struct Declarations
8949
8950 typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
8951
8952 #ifdef __cplusplus
8953 extern "C" {
8954 #endif
8955
8956 // ---------------- Public Initializer Prototypes
8957
8958 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
8959 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
8960 //
8961 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
8962 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
8963
8964 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
8965 wuffs_zlib__decoder__initialize(
8966 wuffs_zlib__decoder* self,
8967 size_t sizeof_star_self,
8968 uint64_t wuffs_version,
8969 uint32_t options);
8970
8971 size_t
8972 sizeof__wuffs_zlib__decoder();
8973
8974 // ---------------- Allocs
8975
8976 // These functions allocate and initialize Wuffs structs. They return NULL if
8977 // memory allocation fails. If they return non-NULL, there is no need to call
8978 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
8979 // calling free on the returned pointer. That pointer is effectively a C++
8980 // std::unique_ptr<T, decltype(&free)>.
8981
8982 wuffs_zlib__decoder*
8983 wuffs_zlib__decoder__alloc();
8984
8985 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer()8986 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer() {
8987 return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
8988 }
8989
8990 // ---------------- Upcasts
8991
8992 static inline wuffs_base__io_transformer*
wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(wuffs_zlib__decoder * p)8993 wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(
8994 wuffs_zlib__decoder* p) {
8995 return (wuffs_base__io_transformer*)p;
8996 }
8997
8998 // ---------------- Public Function Prototypes
8999
9000 WUFFS_BASE__MAYBE_STATIC uint32_t
9001 wuffs_zlib__decoder__dictionary_id(
9002 const wuffs_zlib__decoder* self);
9003
9004 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9005 wuffs_zlib__decoder__add_dictionary(
9006 wuffs_zlib__decoder* self,
9007 wuffs_base__slice_u8 a_dict);
9008
9009 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9010 wuffs_zlib__decoder__set_quirk_enabled(
9011 wuffs_zlib__decoder* self,
9012 uint32_t a_quirk,
9013 bool a_enabled);
9014
9015 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9016 wuffs_zlib__decoder__workbuf_len(
9017 const wuffs_zlib__decoder* self);
9018
9019 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9020 wuffs_zlib__decoder__transform_io(
9021 wuffs_zlib__decoder* self,
9022 wuffs_base__io_buffer* a_dst,
9023 wuffs_base__io_buffer* a_src,
9024 wuffs_base__slice_u8 a_workbuf);
9025
9026 #ifdef __cplusplus
9027 } // extern "C"
9028 #endif
9029
9030 // ---------------- Struct Definitions
9031
9032 // These structs' fields, and the sizeof them, are private implementation
9033 // details that aren't guaranteed to be stable across Wuffs versions.
9034 //
9035 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9036
9037 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9038
9039 struct wuffs_zlib__decoder__struct {
9040 // Do not access the private_impl's or private_data's fields directly. There
9041 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9042 // the wuffs_foo__bar__baz functions.
9043 //
9044 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9045 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9046
9047 struct {
9048 uint32_t magic;
9049 uint32_t active_coroutine;
9050 wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
9051 wuffs_base__vtable null_vtable;
9052
9053 bool f_bad_call_sequence;
9054 bool f_header_complete;
9055 bool f_got_dictionary;
9056 bool f_want_dictionary;
9057 bool f_quirks[1];
9058 bool f_ignore_checksum;
9059 uint32_t f_dict_id_got;
9060 uint32_t f_dict_id_want;
9061
9062 uint32_t p_transform_io[1];
9063 } private_impl;
9064
9065 struct {
9066 wuffs_adler32__hasher f_checksum;
9067 wuffs_adler32__hasher f_dict_id_hasher;
9068 wuffs_deflate__decoder f_flate;
9069
9070 struct {
9071 uint32_t v_checksum_got;
9072 uint64_t scratch;
9073 } s_transform_io[1];
9074 } private_data;
9075
9076 #ifdef __cplusplus
9077 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9078 using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, decltype(&free)>;
9079
9080 // On failure, the alloc_etc functions return nullptr. They don't throw.
9081
9082 static inline unique_ptr
allocwuffs_zlib__decoder__struct9083 alloc() {
9084 return unique_ptr(wuffs_zlib__decoder__alloc(), &free);
9085 }
9086
9087 static inline wuffs_base__io_transformer::unique_ptr
alloc_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct9088 alloc_as__wuffs_base__io_transformer() {
9089 return wuffs_base__io_transformer::unique_ptr(
9090 wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(), &free);
9091 }
9092 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9093
9094 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9095 // Disallow constructing or copying an object via standard C++ mechanisms,
9096 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9097 // size and field layout is not part of the public, stable, memory-safe API.
9098 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9099 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9100 // their first argument) rather than tweaking bar.private_impl.qux fields.
9101 //
9102 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9103 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9104 // order to provide convenience methods. These forward on "this", so that you
9105 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9106 wuffs_zlib__decoder__struct() = delete;
9107 wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
9108 wuffs_zlib__decoder__struct& operator=(
9109 const wuffs_zlib__decoder__struct&) = delete;
9110 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9111
9112 #if !defined(WUFFS_IMPLEMENTATION)
9113 // As above, the size of the struct is not part of the public API, and unless
9114 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9115 // allocated, not stack allocated. Its size is not intended to be known at
9116 // compile time, but it is unfortunately divulged as a side effect of
9117 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9118 // instead of "sizeof T", invoking the operator. To make the two values
9119 // different, so that passing the latter will be rejected by the initialize
9120 // function, we add an arbitrary amount of dead weight.
9121 uint8_t dead_weight[123000000]; // 123 MB.
9122 #endif // !defined(WUFFS_IMPLEMENTATION)
9123
9124 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_zlib__decoder__struct9125 initialize(
9126 size_t sizeof_star_self,
9127 uint64_t wuffs_version,
9128 uint32_t options) {
9129 return wuffs_zlib__decoder__initialize(
9130 this, sizeof_star_self, wuffs_version, options);
9131 }
9132
9133 inline wuffs_base__io_transformer*
upcast_as__wuffs_base__io_transformerwuffs_zlib__decoder__struct9134 upcast_as__wuffs_base__io_transformer() {
9135 return (wuffs_base__io_transformer*)this;
9136 }
9137
9138 inline uint32_t
dictionary_idwuffs_zlib__decoder__struct9139 dictionary_id() const {
9140 return wuffs_zlib__decoder__dictionary_id(this);
9141 }
9142
9143 inline wuffs_base__empty_struct
add_dictionarywuffs_zlib__decoder__struct9144 add_dictionary(
9145 wuffs_base__slice_u8 a_dict) {
9146 return wuffs_zlib__decoder__add_dictionary(this, a_dict);
9147 }
9148
9149 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_zlib__decoder__struct9150 set_quirk_enabled(
9151 uint32_t a_quirk,
9152 bool a_enabled) {
9153 return wuffs_zlib__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9154 }
9155
9156 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_zlib__decoder__struct9157 workbuf_len() const {
9158 return wuffs_zlib__decoder__workbuf_len(this);
9159 }
9160
9161 inline wuffs_base__status
transform_iowuffs_zlib__decoder__struct9162 transform_io(
9163 wuffs_base__io_buffer* a_dst,
9164 wuffs_base__io_buffer* a_src,
9165 wuffs_base__slice_u8 a_workbuf) {
9166 return wuffs_zlib__decoder__transform_io(this, a_dst, a_src, a_workbuf);
9167 }
9168
9169 #endif // __cplusplus
9170 }; // struct wuffs_zlib__decoder__struct
9171
9172 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9173
9174 // ---------------- Status Codes
9175
9176 extern const char wuffs_png__error__bad_animation_sequence_number[];
9177 extern const char wuffs_png__error__bad_checksum[];
9178 extern const char wuffs_png__error__bad_chunk[];
9179 extern const char wuffs_png__error__bad_filter[];
9180 extern const char wuffs_png__error__bad_header[];
9181 extern const char wuffs_png__error__bad_text_chunk_not_latin_1[];
9182 extern const char wuffs_png__error__missing_palette[];
9183 extern const char wuffs_png__error__unsupported_png_compression_method[];
9184 extern const char wuffs_png__error__unsupported_png_file[];
9185
9186 // ---------------- Public Consts
9187
9188 #define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9189
9190 #define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8
9191
9192 // ---------------- Struct Declarations
9193
9194 typedef struct wuffs_png__decoder__struct wuffs_png__decoder;
9195
9196 #ifdef __cplusplus
9197 extern "C" {
9198 #endif
9199
9200 // ---------------- Public Initializer Prototypes
9201
9202 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9203 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9204 //
9205 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9206 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9207
9208 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9209 wuffs_png__decoder__initialize(
9210 wuffs_png__decoder* self,
9211 size_t sizeof_star_self,
9212 uint64_t wuffs_version,
9213 uint32_t options);
9214
9215 size_t
9216 sizeof__wuffs_png__decoder();
9217
9218 // ---------------- Allocs
9219
9220 // These functions allocate and initialize Wuffs structs. They return NULL if
9221 // memory allocation fails. If they return non-NULL, there is no need to call
9222 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9223 // calling free on the returned pointer. That pointer is effectively a C++
9224 // std::unique_ptr<T, decltype(&free)>.
9225
9226 wuffs_png__decoder*
9227 wuffs_png__decoder__alloc();
9228
9229 static inline wuffs_base__image_decoder*
wuffs_png__decoder__alloc_as__wuffs_base__image_decoder()9230 wuffs_png__decoder__alloc_as__wuffs_base__image_decoder() {
9231 return (wuffs_base__image_decoder*)(wuffs_png__decoder__alloc());
9232 }
9233
9234 // ---------------- Upcasts
9235
9236 static inline wuffs_base__image_decoder*
wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(wuffs_png__decoder * p)9237 wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(
9238 wuffs_png__decoder* p) {
9239 return (wuffs_base__image_decoder*)p;
9240 }
9241
9242 // ---------------- Public Function Prototypes
9243
9244 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9245 wuffs_png__decoder__set_quirk_enabled(
9246 wuffs_png__decoder* self,
9247 uint32_t a_quirk,
9248 bool a_enabled);
9249
9250 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9251 wuffs_png__decoder__decode_image_config(
9252 wuffs_png__decoder* self,
9253 wuffs_base__image_config* a_dst,
9254 wuffs_base__io_buffer* a_src);
9255
9256 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9257 wuffs_png__decoder__decode_frame_config(
9258 wuffs_png__decoder* self,
9259 wuffs_base__frame_config* a_dst,
9260 wuffs_base__io_buffer* a_src);
9261
9262 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9263 wuffs_png__decoder__decode_frame(
9264 wuffs_png__decoder* self,
9265 wuffs_base__pixel_buffer* a_dst,
9266 wuffs_base__io_buffer* a_src,
9267 wuffs_base__pixel_blend a_blend,
9268 wuffs_base__slice_u8 a_workbuf,
9269 wuffs_base__decode_frame_options* a_opts);
9270
9271 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9272 wuffs_png__decoder__frame_dirty_rect(
9273 const wuffs_png__decoder* self);
9274
9275 WUFFS_BASE__MAYBE_STATIC uint32_t
9276 wuffs_png__decoder__num_animation_loops(
9277 const wuffs_png__decoder* self);
9278
9279 WUFFS_BASE__MAYBE_STATIC uint64_t
9280 wuffs_png__decoder__num_decoded_frame_configs(
9281 const wuffs_png__decoder* self);
9282
9283 WUFFS_BASE__MAYBE_STATIC uint64_t
9284 wuffs_png__decoder__num_decoded_frames(
9285 const wuffs_png__decoder* self);
9286
9287 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9288 wuffs_png__decoder__restart_frame(
9289 wuffs_png__decoder* self,
9290 uint64_t a_index,
9291 uint64_t a_io_position);
9292
9293 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9294 wuffs_png__decoder__set_report_metadata(
9295 wuffs_png__decoder* self,
9296 uint32_t a_fourcc,
9297 bool a_report);
9298
9299 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9300 wuffs_png__decoder__tell_me_more(
9301 wuffs_png__decoder* self,
9302 wuffs_base__io_buffer* a_dst,
9303 wuffs_base__more_information* a_minfo,
9304 wuffs_base__io_buffer* a_src);
9305
9306 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9307 wuffs_png__decoder__workbuf_len(
9308 const wuffs_png__decoder* self);
9309
9310 #ifdef __cplusplus
9311 } // extern "C"
9312 #endif
9313
9314 // ---------------- Struct Definitions
9315
9316 // These structs' fields, and the sizeof them, are private implementation
9317 // details that aren't guaranteed to be stable across Wuffs versions.
9318 //
9319 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9320
9321 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9322
9323 struct wuffs_png__decoder__struct {
9324 // Do not access the private_impl's or private_data's fields directly. There
9325 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9326 // the wuffs_foo__bar__baz functions.
9327 //
9328 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9329 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9330
9331 struct {
9332 uint32_t magic;
9333 uint32_t active_coroutine;
9334 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9335 wuffs_base__vtable null_vtable;
9336
9337 uint32_t f_width;
9338 uint32_t f_height;
9339 uint64_t f_pass_bytes_per_row;
9340 uint64_t f_workbuf_wi;
9341 uint64_t f_workbuf_hist_pos_base;
9342 uint64_t f_overall_workbuf_length;
9343 uint64_t f_pass_workbuf_length;
9344 uint8_t f_call_sequence;
9345 bool f_report_metadata_chrm;
9346 bool f_report_metadata_exif;
9347 bool f_report_metadata_gama;
9348 bool f_report_metadata_iccp;
9349 bool f_report_metadata_kvp;
9350 bool f_report_metadata_srgb;
9351 bool f_ignore_checksum;
9352 uint8_t f_depth;
9353 uint8_t f_color_type;
9354 uint8_t f_filter_distance;
9355 uint8_t f_interlace_pass;
9356 bool f_seen_actl;
9357 bool f_seen_chrm;
9358 bool f_seen_fctl;
9359 bool f_seen_exif;
9360 bool f_seen_gama;
9361 bool f_seen_iccp;
9362 bool f_seen_idat;
9363 bool f_seen_plte;
9364 bool f_seen_srgb;
9365 bool f_seen_trns;
9366 bool f_metadata_is_zlib_compressed;
9367 bool f_zlib_is_dirty;
9368 uint32_t f_chunk_type;
9369 uint8_t f_chunk_type_array[4];
9370 uint32_t f_chunk_length;
9371 uint64_t f_remap_transparency;
9372 uint32_t f_dst_pixfmt;
9373 uint32_t f_src_pixfmt;
9374 uint32_t f_num_animation_frames_value;
9375 uint32_t f_num_animation_loops_value;
9376 uint32_t f_num_decoded_frame_configs_value;
9377 uint32_t f_num_decoded_frames_value;
9378 uint32_t f_frame_rect_x0;
9379 uint32_t f_frame_rect_y0;
9380 uint32_t f_frame_rect_x1;
9381 uint32_t f_frame_rect_y1;
9382 uint32_t f_first_rect_x0;
9383 uint32_t f_first_rect_y0;
9384 uint32_t f_first_rect_x1;
9385 uint32_t f_first_rect_y1;
9386 uint64_t f_frame_config_io_position;
9387 uint64_t f_first_config_io_position;
9388 uint64_t f_frame_duration;
9389 uint64_t f_first_duration;
9390 uint8_t f_frame_disposal;
9391 uint8_t f_first_disposal;
9392 bool f_frame_overwrite_instead_of_blend;
9393 bool f_first_overwrite_instead_of_blend;
9394 uint32_t f_next_animation_seq_num;
9395 uint32_t f_metadata_flavor;
9396 uint32_t f_metadata_fourcc;
9397 uint64_t f_metadata_x;
9398 uint64_t f_metadata_y;
9399 uint64_t f_metadata_z;
9400 uint32_t f_ztxt_ri;
9401 uint32_t f_ztxt_wi;
9402 uint64_t f_ztxt_hist_pos;
9403 wuffs_base__pixel_swizzler f_swizzler;
9404
9405 wuffs_base__empty_struct (*choosy_filter_1)(
9406 wuffs_png__decoder* self,
9407 wuffs_base__slice_u8 a_curr);
9408 wuffs_base__empty_struct (*choosy_filter_3)(
9409 wuffs_png__decoder* self,
9410 wuffs_base__slice_u8 a_curr,
9411 wuffs_base__slice_u8 a_prev);
9412 wuffs_base__empty_struct (*choosy_filter_4)(
9413 wuffs_png__decoder* self,
9414 wuffs_base__slice_u8 a_curr,
9415 wuffs_base__slice_u8 a_prev);
9416 uint32_t p_decode_image_config[1];
9417 uint32_t p_decode_ihdr[1];
9418 uint32_t p_decode_other_chunk[1];
9419 uint32_t p_decode_actl[1];
9420 uint32_t p_decode_chrm[1];
9421 uint32_t p_decode_fctl[1];
9422 uint32_t p_decode_gama[1];
9423 uint32_t p_decode_iccp[1];
9424 uint32_t p_decode_plte[1];
9425 uint32_t p_decode_srgb[1];
9426 uint32_t p_decode_trns[1];
9427 uint32_t p_decode_frame_config[1];
9428 uint32_t p_skip_frame[1];
9429 uint32_t p_decode_frame[1];
9430 uint32_t p_decode_pass[1];
9431 uint32_t p_tell_me_more[1];
9432 wuffs_base__status (*choosy_filter_and_swizzle)(
9433 wuffs_png__decoder* self,
9434 wuffs_base__pixel_buffer* a_dst,
9435 wuffs_base__slice_u8 a_workbuf);
9436 } private_impl;
9437
9438 struct {
9439 wuffs_crc32__ieee_hasher f_crc32;
9440 wuffs_zlib__decoder f_zlib;
9441 uint8_t f_dst_palette[1024];
9442 uint8_t f_src_palette[1024];
9443
9444 struct {
9445 uint32_t v_checksum_have;
9446 uint64_t scratch;
9447 } s_decode_image_config[1];
9448 struct {
9449 uint64_t scratch;
9450 } s_decode_ihdr[1];
9451 struct {
9452 uint64_t scratch;
9453 } s_decode_other_chunk[1];
9454 struct {
9455 uint64_t scratch;
9456 } s_decode_actl[1];
9457 struct {
9458 uint64_t scratch;
9459 } s_decode_chrm[1];
9460 struct {
9461 uint32_t v_x0;
9462 uint32_t v_x1;
9463 uint32_t v_y1;
9464 uint64_t scratch;
9465 } s_decode_fctl[1];
9466 struct {
9467 uint64_t scratch;
9468 } s_decode_gama[1];
9469 struct {
9470 uint32_t v_num_entries;
9471 uint32_t v_i;
9472 uint64_t scratch;
9473 } s_decode_plte[1];
9474 struct {
9475 uint32_t v_i;
9476 uint32_t v_n;
9477 uint64_t scratch;
9478 } s_decode_trns[1];
9479 struct {
9480 uint64_t scratch;
9481 } s_decode_frame_config[1];
9482 struct {
9483 uint64_t scratch;
9484 } s_skip_frame[1];
9485 struct {
9486 uint64_t scratch;
9487 } s_decode_frame[1];
9488 struct {
9489 uint64_t scratch;
9490 } s_decode_pass[1];
9491 struct {
9492 wuffs_base__status v_zlib_status;
9493 uint64_t scratch;
9494 } s_tell_me_more[1];
9495 } private_data;
9496
9497 #ifdef __cplusplus
9498 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9499 using unique_ptr = std::unique_ptr<wuffs_png__decoder, decltype(&free)>;
9500
9501 // On failure, the alloc_etc functions return nullptr. They don't throw.
9502
9503 static inline unique_ptr
allocwuffs_png__decoder__struct9504 alloc() {
9505 return unique_ptr(wuffs_png__decoder__alloc(), &free);
9506 }
9507
9508 static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_png__decoder__struct9509 alloc_as__wuffs_base__image_decoder() {
9510 return wuffs_base__image_decoder::unique_ptr(
9511 wuffs_png__decoder__alloc_as__wuffs_base__image_decoder(), &free);
9512 }
9513 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9514
9515 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9516 // Disallow constructing or copying an object via standard C++ mechanisms,
9517 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9518 // size and field layout is not part of the public, stable, memory-safe API.
9519 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9520 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9521 // their first argument) rather than tweaking bar.private_impl.qux fields.
9522 //
9523 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9524 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9525 // order to provide convenience methods. These forward on "this", so that you
9526 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9527 wuffs_png__decoder__struct() = delete;
9528 wuffs_png__decoder__struct(const wuffs_png__decoder__struct&) = delete;
9529 wuffs_png__decoder__struct& operator=(
9530 const wuffs_png__decoder__struct&) = delete;
9531 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9532
9533 #if !defined(WUFFS_IMPLEMENTATION)
9534 // As above, the size of the struct is not part of the public API, and unless
9535 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9536 // allocated, not stack allocated. Its size is not intended to be known at
9537 // compile time, but it is unfortunately divulged as a side effect of
9538 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9539 // instead of "sizeof T", invoking the operator. To make the two values
9540 // different, so that passing the latter will be rejected by the initialize
9541 // function, we add an arbitrary amount of dead weight.
9542 uint8_t dead_weight[123000000]; // 123 MB.
9543 #endif // !defined(WUFFS_IMPLEMENTATION)
9544
9545 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_png__decoder__struct9546 initialize(
9547 size_t sizeof_star_self,
9548 uint64_t wuffs_version,
9549 uint32_t options) {
9550 return wuffs_png__decoder__initialize(
9551 this, sizeof_star_self, wuffs_version, options);
9552 }
9553
9554 inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_png__decoder__struct9555 upcast_as__wuffs_base__image_decoder() {
9556 return (wuffs_base__image_decoder*)this;
9557 }
9558
9559 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_png__decoder__struct9560 set_quirk_enabled(
9561 uint32_t a_quirk,
9562 bool a_enabled) {
9563 return wuffs_png__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9564 }
9565
9566 inline wuffs_base__status
decode_image_configwuffs_png__decoder__struct9567 decode_image_config(
9568 wuffs_base__image_config* a_dst,
9569 wuffs_base__io_buffer* a_src) {
9570 return wuffs_png__decoder__decode_image_config(this, a_dst, a_src);
9571 }
9572
9573 inline wuffs_base__status
decode_frame_configwuffs_png__decoder__struct9574 decode_frame_config(
9575 wuffs_base__frame_config* a_dst,
9576 wuffs_base__io_buffer* a_src) {
9577 return wuffs_png__decoder__decode_frame_config(this, a_dst, a_src);
9578 }
9579
9580 inline wuffs_base__status
decode_framewuffs_png__decoder__struct9581 decode_frame(
9582 wuffs_base__pixel_buffer* a_dst,
9583 wuffs_base__io_buffer* a_src,
9584 wuffs_base__pixel_blend a_blend,
9585 wuffs_base__slice_u8 a_workbuf,
9586 wuffs_base__decode_frame_options* a_opts) {
9587 return wuffs_png__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9588 }
9589
9590 inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_png__decoder__struct9591 frame_dirty_rect() const {
9592 return wuffs_png__decoder__frame_dirty_rect(this);
9593 }
9594
9595 inline uint32_t
num_animation_loopswuffs_png__decoder__struct9596 num_animation_loops() const {
9597 return wuffs_png__decoder__num_animation_loops(this);
9598 }
9599
9600 inline uint64_t
num_decoded_frame_configswuffs_png__decoder__struct9601 num_decoded_frame_configs() const {
9602 return wuffs_png__decoder__num_decoded_frame_configs(this);
9603 }
9604
9605 inline uint64_t
num_decoded_frameswuffs_png__decoder__struct9606 num_decoded_frames() const {
9607 return wuffs_png__decoder__num_decoded_frames(this);
9608 }
9609
9610 inline wuffs_base__status
restart_framewuffs_png__decoder__struct9611 restart_frame(
9612 uint64_t a_index,
9613 uint64_t a_io_position) {
9614 return wuffs_png__decoder__restart_frame(this, a_index, a_io_position);
9615 }
9616
9617 inline wuffs_base__empty_struct
set_report_metadatawuffs_png__decoder__struct9618 set_report_metadata(
9619 uint32_t a_fourcc,
9620 bool a_report) {
9621 return wuffs_png__decoder__set_report_metadata(this, a_fourcc, a_report);
9622 }
9623
9624 inline wuffs_base__status
tell_me_morewuffs_png__decoder__struct9625 tell_me_more(
9626 wuffs_base__io_buffer* a_dst,
9627 wuffs_base__more_information* a_minfo,
9628 wuffs_base__io_buffer* a_src) {
9629 return wuffs_png__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9630 }
9631
9632 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_png__decoder__struct9633 workbuf_len() const {
9634 return wuffs_png__decoder__workbuf_len(this);
9635 }
9636
9637 #endif // __cplusplus
9638 }; // struct wuffs_png__decoder__struct
9639
9640 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9641
9642 // ---------------- Status Codes
9643
9644 extern const char wuffs_tga__error__bad_header[];
9645 extern const char wuffs_tga__error__bad_run_length_encoding[];
9646 extern const char wuffs_tga__error__unsupported_tga_file[];
9647
9648 // ---------------- Public Consts
9649
9650 #define WUFFS_TGA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9651
9652 // ---------------- Struct Declarations
9653
9654 typedef struct wuffs_tga__decoder__struct wuffs_tga__decoder;
9655
9656 #ifdef __cplusplus
9657 extern "C" {
9658 #endif
9659
9660 // ---------------- Public Initializer Prototypes
9661
9662 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
9663 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
9664 //
9665 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
9666 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
9667
9668 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
9669 wuffs_tga__decoder__initialize(
9670 wuffs_tga__decoder* self,
9671 size_t sizeof_star_self,
9672 uint64_t wuffs_version,
9673 uint32_t options);
9674
9675 size_t
9676 sizeof__wuffs_tga__decoder();
9677
9678 // ---------------- Allocs
9679
9680 // These functions allocate and initialize Wuffs structs. They return NULL if
9681 // memory allocation fails. If they return non-NULL, there is no need to call
9682 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
9683 // calling free on the returned pointer. That pointer is effectively a C++
9684 // std::unique_ptr<T, decltype(&free)>.
9685
9686 wuffs_tga__decoder*
9687 wuffs_tga__decoder__alloc();
9688
9689 static inline wuffs_base__image_decoder*
wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder()9690 wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder() {
9691 return (wuffs_base__image_decoder*)(wuffs_tga__decoder__alloc());
9692 }
9693
9694 // ---------------- Upcasts
9695
9696 static inline wuffs_base__image_decoder*
wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(wuffs_tga__decoder * p)9697 wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(
9698 wuffs_tga__decoder* p) {
9699 return (wuffs_base__image_decoder*)p;
9700 }
9701
9702 // ---------------- Public Function Prototypes
9703
9704 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9705 wuffs_tga__decoder__set_quirk_enabled(
9706 wuffs_tga__decoder* self,
9707 uint32_t a_quirk,
9708 bool a_enabled);
9709
9710 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9711 wuffs_tga__decoder__decode_image_config(
9712 wuffs_tga__decoder* self,
9713 wuffs_base__image_config* a_dst,
9714 wuffs_base__io_buffer* a_src);
9715
9716 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9717 wuffs_tga__decoder__decode_frame_config(
9718 wuffs_tga__decoder* self,
9719 wuffs_base__frame_config* a_dst,
9720 wuffs_base__io_buffer* a_src);
9721
9722 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9723 wuffs_tga__decoder__decode_frame(
9724 wuffs_tga__decoder* self,
9725 wuffs_base__pixel_buffer* a_dst,
9726 wuffs_base__io_buffer* a_src,
9727 wuffs_base__pixel_blend a_blend,
9728 wuffs_base__slice_u8 a_workbuf,
9729 wuffs_base__decode_frame_options* a_opts);
9730
9731 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
9732 wuffs_tga__decoder__frame_dirty_rect(
9733 const wuffs_tga__decoder* self);
9734
9735 WUFFS_BASE__MAYBE_STATIC uint32_t
9736 wuffs_tga__decoder__num_animation_loops(
9737 const wuffs_tga__decoder* self);
9738
9739 WUFFS_BASE__MAYBE_STATIC uint64_t
9740 wuffs_tga__decoder__num_decoded_frame_configs(
9741 const wuffs_tga__decoder* self);
9742
9743 WUFFS_BASE__MAYBE_STATIC uint64_t
9744 wuffs_tga__decoder__num_decoded_frames(
9745 const wuffs_tga__decoder* self);
9746
9747 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9748 wuffs_tga__decoder__restart_frame(
9749 wuffs_tga__decoder* self,
9750 uint64_t a_index,
9751 uint64_t a_io_position);
9752
9753 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
9754 wuffs_tga__decoder__set_report_metadata(
9755 wuffs_tga__decoder* self,
9756 uint32_t a_fourcc,
9757 bool a_report);
9758
9759 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
9760 wuffs_tga__decoder__tell_me_more(
9761 wuffs_tga__decoder* self,
9762 wuffs_base__io_buffer* a_dst,
9763 wuffs_base__more_information* a_minfo,
9764 wuffs_base__io_buffer* a_src);
9765
9766 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
9767 wuffs_tga__decoder__workbuf_len(
9768 const wuffs_tga__decoder* self);
9769
9770 #ifdef __cplusplus
9771 } // extern "C"
9772 #endif
9773
9774 // ---------------- Struct Definitions
9775
9776 // These structs' fields, and the sizeof them, are private implementation
9777 // details that aren't guaranteed to be stable across Wuffs versions.
9778 //
9779 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
9780
9781 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9782
9783 struct wuffs_tga__decoder__struct {
9784 // Do not access the private_impl's or private_data's fields directly. There
9785 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
9786 // the wuffs_foo__bar__baz functions.
9787 //
9788 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
9789 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
9790
9791 struct {
9792 uint32_t magic;
9793 uint32_t active_coroutine;
9794 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
9795 wuffs_base__vtable null_vtable;
9796
9797 uint32_t f_width;
9798 uint32_t f_height;
9799 uint8_t f_call_sequence;
9800 uint8_t f_header_id_length;
9801 uint8_t f_header_color_map_type;
9802 uint8_t f_header_image_type;
9803 uint16_t f_header_color_map_first_entry_index;
9804 uint16_t f_header_color_map_length;
9805 uint8_t f_header_color_map_entry_size;
9806 uint8_t f_header_pixel_depth;
9807 uint8_t f_header_image_descriptor;
9808 bool f_opaque;
9809 uint32_t f_scratch_bytes_per_pixel;
9810 uint32_t f_src_bytes_per_pixel;
9811 uint32_t f_src_pixfmt;
9812 uint64_t f_frame_config_io_position;
9813 wuffs_base__pixel_swizzler f_swizzler;
9814
9815 uint32_t p_decode_image_config[1];
9816 uint32_t p_decode_frame_config[1];
9817 uint32_t p_decode_frame[1];
9818 } private_impl;
9819
9820 struct {
9821 uint8_t f_dst_palette[1024];
9822 uint8_t f_src_palette[1024];
9823 uint8_t f_scratch[4];
9824
9825 struct {
9826 uint32_t v_i;
9827 uint64_t scratch;
9828 } s_decode_image_config[1];
9829 struct {
9830 uint64_t v_dst_bytes_per_pixel;
9831 uint32_t v_dst_x;
9832 uint32_t v_dst_y;
9833 uint64_t v_mark;
9834 uint32_t v_num_pixels32;
9835 uint32_t v_lit_length;
9836 uint32_t v_run_length;
9837 uint64_t v_num_dst_bytes;
9838 uint64_t scratch;
9839 } s_decode_frame[1];
9840 } private_data;
9841
9842 #ifdef __cplusplus
9843 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9844 using unique_ptr = std::unique_ptr<wuffs_tga__decoder, decltype(&free)>;
9845
9846 // On failure, the alloc_etc functions return nullptr. They don't throw.
9847
9848 static inline unique_ptr
allocwuffs_tga__decoder__struct9849 alloc() {
9850 return unique_ptr(wuffs_tga__decoder__alloc(), &free);
9851 }
9852
9853 static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_tga__decoder__struct9854 alloc_as__wuffs_base__image_decoder() {
9855 return wuffs_base__image_decoder::unique_ptr(
9856 wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(), &free);
9857 }
9858 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
9859
9860 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9861 // Disallow constructing or copying an object via standard C++ mechanisms,
9862 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
9863 // size and field layout is not part of the public, stable, memory-safe API.
9864 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
9865 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
9866 // their first argument) rather than tweaking bar.private_impl.qux fields.
9867 //
9868 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
9869 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
9870 // order to provide convenience methods. These forward on "this", so that you
9871 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
9872 wuffs_tga__decoder__struct() = delete;
9873 wuffs_tga__decoder__struct(const wuffs_tga__decoder__struct&) = delete;
9874 wuffs_tga__decoder__struct& operator=(
9875 const wuffs_tga__decoder__struct&) = delete;
9876 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
9877
9878 #if !defined(WUFFS_IMPLEMENTATION)
9879 // As above, the size of the struct is not part of the public API, and unless
9880 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
9881 // allocated, not stack allocated. Its size is not intended to be known at
9882 // compile time, but it is unfortunately divulged as a side effect of
9883 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
9884 // instead of "sizeof T", invoking the operator. To make the two values
9885 // different, so that passing the latter will be rejected by the initialize
9886 // function, we add an arbitrary amount of dead weight.
9887 uint8_t dead_weight[123000000]; // 123 MB.
9888 #endif // !defined(WUFFS_IMPLEMENTATION)
9889
9890 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_tga__decoder__struct9891 initialize(
9892 size_t sizeof_star_self,
9893 uint64_t wuffs_version,
9894 uint32_t options) {
9895 return wuffs_tga__decoder__initialize(
9896 this, sizeof_star_self, wuffs_version, options);
9897 }
9898
9899 inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_tga__decoder__struct9900 upcast_as__wuffs_base__image_decoder() {
9901 return (wuffs_base__image_decoder*)this;
9902 }
9903
9904 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_tga__decoder__struct9905 set_quirk_enabled(
9906 uint32_t a_quirk,
9907 bool a_enabled) {
9908 return wuffs_tga__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
9909 }
9910
9911 inline wuffs_base__status
decode_image_configwuffs_tga__decoder__struct9912 decode_image_config(
9913 wuffs_base__image_config* a_dst,
9914 wuffs_base__io_buffer* a_src) {
9915 return wuffs_tga__decoder__decode_image_config(this, a_dst, a_src);
9916 }
9917
9918 inline wuffs_base__status
decode_frame_configwuffs_tga__decoder__struct9919 decode_frame_config(
9920 wuffs_base__frame_config* a_dst,
9921 wuffs_base__io_buffer* a_src) {
9922 return wuffs_tga__decoder__decode_frame_config(this, a_dst, a_src);
9923 }
9924
9925 inline wuffs_base__status
decode_framewuffs_tga__decoder__struct9926 decode_frame(
9927 wuffs_base__pixel_buffer* a_dst,
9928 wuffs_base__io_buffer* a_src,
9929 wuffs_base__pixel_blend a_blend,
9930 wuffs_base__slice_u8 a_workbuf,
9931 wuffs_base__decode_frame_options* a_opts) {
9932 return wuffs_tga__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
9933 }
9934
9935 inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_tga__decoder__struct9936 frame_dirty_rect() const {
9937 return wuffs_tga__decoder__frame_dirty_rect(this);
9938 }
9939
9940 inline uint32_t
num_animation_loopswuffs_tga__decoder__struct9941 num_animation_loops() const {
9942 return wuffs_tga__decoder__num_animation_loops(this);
9943 }
9944
9945 inline uint64_t
num_decoded_frame_configswuffs_tga__decoder__struct9946 num_decoded_frame_configs() const {
9947 return wuffs_tga__decoder__num_decoded_frame_configs(this);
9948 }
9949
9950 inline uint64_t
num_decoded_frameswuffs_tga__decoder__struct9951 num_decoded_frames() const {
9952 return wuffs_tga__decoder__num_decoded_frames(this);
9953 }
9954
9955 inline wuffs_base__status
restart_framewuffs_tga__decoder__struct9956 restart_frame(
9957 uint64_t a_index,
9958 uint64_t a_io_position) {
9959 return wuffs_tga__decoder__restart_frame(this, a_index, a_io_position);
9960 }
9961
9962 inline wuffs_base__empty_struct
set_report_metadatawuffs_tga__decoder__struct9963 set_report_metadata(
9964 uint32_t a_fourcc,
9965 bool a_report) {
9966 return wuffs_tga__decoder__set_report_metadata(this, a_fourcc, a_report);
9967 }
9968
9969 inline wuffs_base__status
tell_me_morewuffs_tga__decoder__struct9970 tell_me_more(
9971 wuffs_base__io_buffer* a_dst,
9972 wuffs_base__more_information* a_minfo,
9973 wuffs_base__io_buffer* a_src) {
9974 return wuffs_tga__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
9975 }
9976
9977 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_tga__decoder__struct9978 workbuf_len() const {
9979 return wuffs_tga__decoder__workbuf_len(this);
9980 }
9981
9982 #endif // __cplusplus
9983 }; // struct wuffs_tga__decoder__struct
9984
9985 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
9986
9987 // ---------------- Status Codes
9988
9989 extern const char wuffs_wbmp__error__bad_header[];
9990
9991 // ---------------- Public Consts
9992
9993 #define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
9994
9995 // ---------------- Struct Declarations
9996
9997 typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder;
9998
9999 #ifdef __cplusplus
10000 extern "C" {
10001 #endif
10002
10003 // ---------------- Public Initializer Prototypes
10004
10005 // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self,
10006 // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)".
10007 //
10008 // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version.
10009 // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options.
10010
10011 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
10012 wuffs_wbmp__decoder__initialize(
10013 wuffs_wbmp__decoder* self,
10014 size_t sizeof_star_self,
10015 uint64_t wuffs_version,
10016 uint32_t options);
10017
10018 size_t
10019 sizeof__wuffs_wbmp__decoder();
10020
10021 // ---------------- Allocs
10022
10023 // These functions allocate and initialize Wuffs structs. They return NULL if
10024 // memory allocation fails. If they return non-NULL, there is no need to call
10025 // wuffs_foo__bar__initialize, but the caller is responsible for eventually
10026 // calling free on the returned pointer. That pointer is effectively a C++
10027 // std::unique_ptr<T, decltype(&free)>.
10028
10029 wuffs_wbmp__decoder*
10030 wuffs_wbmp__decoder__alloc();
10031
10032 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder()10033 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder() {
10034 return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
10035 }
10036
10037 // ---------------- Upcasts
10038
10039 static inline wuffs_base__image_decoder*
wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(wuffs_wbmp__decoder * p)10040 wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
10041 wuffs_wbmp__decoder* p) {
10042 return (wuffs_base__image_decoder*)p;
10043 }
10044
10045 // ---------------- Public Function Prototypes
10046
10047 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
10048 wuffs_wbmp__decoder__set_quirk_enabled(
10049 wuffs_wbmp__decoder* self,
10050 uint32_t a_quirk,
10051 bool a_enabled);
10052
10053 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10054 wuffs_wbmp__decoder__decode_image_config(
10055 wuffs_wbmp__decoder* self,
10056 wuffs_base__image_config* a_dst,
10057 wuffs_base__io_buffer* a_src);
10058
10059 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10060 wuffs_wbmp__decoder__decode_frame_config(
10061 wuffs_wbmp__decoder* self,
10062 wuffs_base__frame_config* a_dst,
10063 wuffs_base__io_buffer* a_src);
10064
10065 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10066 wuffs_wbmp__decoder__decode_frame(
10067 wuffs_wbmp__decoder* self,
10068 wuffs_base__pixel_buffer* a_dst,
10069 wuffs_base__io_buffer* a_src,
10070 wuffs_base__pixel_blend a_blend,
10071 wuffs_base__slice_u8 a_workbuf,
10072 wuffs_base__decode_frame_options* a_opts);
10073
10074 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
10075 wuffs_wbmp__decoder__frame_dirty_rect(
10076 const wuffs_wbmp__decoder* self);
10077
10078 WUFFS_BASE__MAYBE_STATIC uint32_t
10079 wuffs_wbmp__decoder__num_animation_loops(
10080 const wuffs_wbmp__decoder* self);
10081
10082 WUFFS_BASE__MAYBE_STATIC uint64_t
10083 wuffs_wbmp__decoder__num_decoded_frame_configs(
10084 const wuffs_wbmp__decoder* self);
10085
10086 WUFFS_BASE__MAYBE_STATIC uint64_t
10087 wuffs_wbmp__decoder__num_decoded_frames(
10088 const wuffs_wbmp__decoder* self);
10089
10090 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10091 wuffs_wbmp__decoder__restart_frame(
10092 wuffs_wbmp__decoder* self,
10093 uint64_t a_index,
10094 uint64_t a_io_position);
10095
10096 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
10097 wuffs_wbmp__decoder__set_report_metadata(
10098 wuffs_wbmp__decoder* self,
10099 uint32_t a_fourcc,
10100 bool a_report);
10101
10102 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
10103 wuffs_wbmp__decoder__tell_me_more(
10104 wuffs_wbmp__decoder* self,
10105 wuffs_base__io_buffer* a_dst,
10106 wuffs_base__more_information* a_minfo,
10107 wuffs_base__io_buffer* a_src);
10108
10109 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
10110 wuffs_wbmp__decoder__workbuf_len(
10111 const wuffs_wbmp__decoder* self);
10112
10113 #ifdef __cplusplus
10114 } // extern "C"
10115 #endif
10116
10117 // ---------------- Struct Definitions
10118
10119 // These structs' fields, and the sizeof them, are private implementation
10120 // details that aren't guaranteed to be stable across Wuffs versions.
10121 //
10122 // See https://en.wikipedia.org/wiki/Opaque_pointer#C
10123
10124 #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10125
10126 struct wuffs_wbmp__decoder__struct {
10127 // Do not access the private_impl's or private_data's fields directly. There
10128 // is no API/ABI compatibility or safety guarantee if you do so. Instead, use
10129 // the wuffs_foo__bar__baz functions.
10130 //
10131 // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct
10132 // can be stack allocated when WUFFS_IMPLEMENTATION is defined.
10133
10134 struct {
10135 uint32_t magic;
10136 uint32_t active_coroutine;
10137 wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
10138 wuffs_base__vtable null_vtable;
10139
10140 uint32_t f_width;
10141 uint32_t f_height;
10142 uint8_t f_call_sequence;
10143 uint64_t f_frame_config_io_position;
10144 wuffs_base__pixel_swizzler f_swizzler;
10145
10146 uint32_t p_decode_image_config[1];
10147 uint32_t p_decode_frame_config[1];
10148 uint32_t p_decode_frame[1];
10149 } private_impl;
10150
10151 struct {
10152 struct {
10153 uint32_t v_i;
10154 uint32_t v_x32;
10155 } s_decode_image_config[1];
10156 struct {
10157 uint64_t v_dst_bytes_per_pixel;
10158 uint32_t v_dst_x;
10159 uint32_t v_dst_y;
10160 uint8_t v_src[1];
10161 uint8_t v_c;
10162 } s_decode_frame[1];
10163 } private_data;
10164
10165 #ifdef __cplusplus
10166 #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10167 using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, decltype(&free)>;
10168
10169 // On failure, the alloc_etc functions return nullptr. They don't throw.
10170
10171 static inline unique_ptr
allocwuffs_wbmp__decoder__struct10172 alloc() {
10173 return unique_ptr(wuffs_wbmp__decoder__alloc(), &free);
10174 }
10175
10176 static inline wuffs_base__image_decoder::unique_ptr
alloc_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct10177 alloc_as__wuffs_base__image_decoder() {
10178 return wuffs_base__image_decoder::unique_ptr(
10179 wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(), &free);
10180 }
10181 #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10182
10183 #if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10184 // Disallow constructing or copying an object via standard C++ mechanisms,
10185 // e.g. the "new" operator, as this struct is intentionally opaque. Its total
10186 // size and field layout is not part of the public, stable, memory-safe API.
10187 // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
10188 // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
10189 // their first argument) rather than tweaking bar.private_impl.qux fields.
10190 //
10191 // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
10192 // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
10193 // order to provide convenience methods. These forward on "this", so that you
10194 // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
10195 wuffs_wbmp__decoder__struct() = delete;
10196 wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete;
10197 wuffs_wbmp__decoder__struct& operator=(
10198 const wuffs_wbmp__decoder__struct&) = delete;
10199 #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
10200
10201 #if !defined(WUFFS_IMPLEMENTATION)
10202 // As above, the size of the struct is not part of the public API, and unless
10203 // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
10204 // allocated, not stack allocated. Its size is not intended to be known at
10205 // compile time, but it is unfortunately divulged as a side effect of
10206 // defining C++ convenience methods. Use "sizeof__T()", calling the function,
10207 // instead of "sizeof T", invoking the operator. To make the two values
10208 // different, so that passing the latter will be rejected by the initialize
10209 // function, we add an arbitrary amount of dead weight.
10210 uint8_t dead_weight[123000000]; // 123 MB.
10211 #endif // !defined(WUFFS_IMPLEMENTATION)
10212
10213 inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
initializewuffs_wbmp__decoder__struct10214 initialize(
10215 size_t sizeof_star_self,
10216 uint64_t wuffs_version,
10217 uint32_t options) {
10218 return wuffs_wbmp__decoder__initialize(
10219 this, sizeof_star_self, wuffs_version, options);
10220 }
10221
10222 inline wuffs_base__image_decoder*
upcast_as__wuffs_base__image_decoderwuffs_wbmp__decoder__struct10223 upcast_as__wuffs_base__image_decoder() {
10224 return (wuffs_base__image_decoder*)this;
10225 }
10226
10227 inline wuffs_base__empty_struct
set_quirk_enabledwuffs_wbmp__decoder__struct10228 set_quirk_enabled(
10229 uint32_t a_quirk,
10230 bool a_enabled) {
10231 return wuffs_wbmp__decoder__set_quirk_enabled(this, a_quirk, a_enabled);
10232 }
10233
10234 inline wuffs_base__status
decode_image_configwuffs_wbmp__decoder__struct10235 decode_image_config(
10236 wuffs_base__image_config* a_dst,
10237 wuffs_base__io_buffer* a_src) {
10238 return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src);
10239 }
10240
10241 inline wuffs_base__status
decode_frame_configwuffs_wbmp__decoder__struct10242 decode_frame_config(
10243 wuffs_base__frame_config* a_dst,
10244 wuffs_base__io_buffer* a_src) {
10245 return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src);
10246 }
10247
10248 inline wuffs_base__status
decode_framewuffs_wbmp__decoder__struct10249 decode_frame(
10250 wuffs_base__pixel_buffer* a_dst,
10251 wuffs_base__io_buffer* a_src,
10252 wuffs_base__pixel_blend a_blend,
10253 wuffs_base__slice_u8 a_workbuf,
10254 wuffs_base__decode_frame_options* a_opts) {
10255 return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
10256 }
10257
10258 inline wuffs_base__rect_ie_u32
frame_dirty_rectwuffs_wbmp__decoder__struct10259 frame_dirty_rect() const {
10260 return wuffs_wbmp__decoder__frame_dirty_rect(this);
10261 }
10262
10263 inline uint32_t
num_animation_loopswuffs_wbmp__decoder__struct10264 num_animation_loops() const {
10265 return wuffs_wbmp__decoder__num_animation_loops(this);
10266 }
10267
10268 inline uint64_t
num_decoded_frame_configswuffs_wbmp__decoder__struct10269 num_decoded_frame_configs() const {
10270 return wuffs_wbmp__decoder__num_decoded_frame_configs(this);
10271 }
10272
10273 inline uint64_t
num_decoded_frameswuffs_wbmp__decoder__struct10274 num_decoded_frames() const {
10275 return wuffs_wbmp__decoder__num_decoded_frames(this);
10276 }
10277
10278 inline wuffs_base__status
restart_framewuffs_wbmp__decoder__struct10279 restart_frame(
10280 uint64_t a_index,
10281 uint64_t a_io_position) {
10282 return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position);
10283 }
10284
10285 inline wuffs_base__empty_struct
set_report_metadatawuffs_wbmp__decoder__struct10286 set_report_metadata(
10287 uint32_t a_fourcc,
10288 bool a_report) {
10289 return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report);
10290 }
10291
10292 inline wuffs_base__status
tell_me_morewuffs_wbmp__decoder__struct10293 tell_me_more(
10294 wuffs_base__io_buffer* a_dst,
10295 wuffs_base__more_information* a_minfo,
10296 wuffs_base__io_buffer* a_src) {
10297 return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
10298 }
10299
10300 inline wuffs_base__range_ii_u64
workbuf_lenwuffs_wbmp__decoder__struct10301 workbuf_len() const {
10302 return wuffs_wbmp__decoder__workbuf_len(this);
10303 }
10304
10305 #endif // __cplusplus
10306 }; // struct wuffs_wbmp__decoder__struct
10307
10308 #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
10309
10310 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10311
10312 // ---------------- Auxiliary - Base
10313
10314 // Auxiliary code is discussed at
10315 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
10316
10317 #include <stdio.h>
10318
10319 #include <string>
10320
10321 namespace wuffs_aux {
10322
10323 using IOBuffer = wuffs_base__io_buffer;
10324
10325 // MemOwner represents ownership of some memory. Dynamically allocated memory
10326 // (e.g. from malloc or new) is typically paired with free or delete, invoked
10327 // when the std::unique_ptr is destroyed. Statically allocated memory might use
10328 // MemOwner(nullptr, &free), even if that statically allocated memory is not
10329 // nullptr, since calling free(nullptr) is a no-op.
10330 using MemOwner = std::unique_ptr<void, decltype(&free)>;
10331
10332 namespace sync_io {
10333
10334 // --------
10335
10336 // DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array.
10337 // It owns that backing array and will free it in its destructor.
10338 //
10339 // The array size can be explicitly extended (by calling the grow method) but,
10340 // unlike a C++ std::vector, there is no implicit extension (e.g. by calling
10341 // std::vector::insert) and its maximum size is capped by the max_incl
10342 // constructor argument.
10343 //
10344 // It contains an IOBuffer-typed field whose reader side provides access to
10345 // previously written bytes and whose writer side provides access to the
10346 // allocated but not-yet-written-to slack space. For Go programmers, this slack
10347 // space is roughly analogous to the s[len(s):cap(s)] space of a slice s.
10348 class DynIOBuffer {
10349 public:
10350 enum GrowResult {
10351 OK = 0,
10352 FailedMaxInclExceeded = 1,
10353 FailedOutOfMemory = 2,
10354 };
10355
10356 // m_buf holds the dynamically sized byte array and its read/write indexes:
10357 // - m_buf.meta.wi is roughly analogous to a Go slice's length.
10358 // - m_buf.data.len is roughly analogous to a Go slice's capacity. It is
10359 // also equal to the m_buf.data.ptr malloc/realloc size.
10360 //
10361 // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as
10362 // they are conceptually private to this class), but they can modify the
10363 // bytes referenced by that pointer-length pair (e.g. compactions).
10364 IOBuffer m_buf;
10365
10366 // m_max_incl is an inclusive upper bound on the backing array size.
10367 const uint64_t m_max_incl;
10368
10369 // Constructor and destructor.
10370 explicit DynIOBuffer(uint64_t max_incl);
10371 ~DynIOBuffer();
10372
10373 // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be
10374 // used after a drop call. It just restarts from zero.
10375 void drop();
10376
10377 // grow ensures that the byte array size is at least min_incl and at most
10378 // max_incl. It returns FailedMaxInclExceeded if that would require
10379 // allocating more than max_incl bytes, including the case where (min_incl >
10380 // max_incl). It returns FailedOutOfMemory if memory allocation failed.
10381 GrowResult grow(uint64_t min_incl);
10382
10383 private:
10384 // Delete the copy and assign constructors.
10385 DynIOBuffer(const DynIOBuffer&) = delete;
10386 DynIOBuffer& operator=(const DynIOBuffer&) = delete;
10387
10388 static uint64_t round_up(uint64_t min_incl, uint64_t max_incl);
10389 };
10390
10391 // --------
10392
10393 class Input {
10394 public:
10395 virtual ~Input();
10396
10397 virtual IOBuffer* BringsItsOwnIOBuffer();
10398 virtual std::string CopyIn(IOBuffer* dst) = 0;
10399 };
10400
10401 // --------
10402
10403 // FileInput is an Input that reads from a file source.
10404 //
10405 // It does not take responsibility for closing the file when done.
10406 class FileInput : public Input {
10407 public:
10408 FileInput(FILE* f);
10409
10410 virtual std::string CopyIn(IOBuffer* dst);
10411
10412 private:
10413 FILE* m_f;
10414
10415 // Delete the copy and assign constructors.
10416 FileInput(const FileInput&) = delete;
10417 FileInput& operator=(const FileInput&) = delete;
10418 };
10419
10420 // --------
10421
10422 // MemoryInput is an Input that reads from an in-memory source.
10423 //
10424 // It does not take responsibility for freeing the memory when done.
10425 class MemoryInput : public Input {
10426 public:
10427 MemoryInput(const char* ptr, size_t len);
10428 MemoryInput(const uint8_t* ptr, size_t len);
10429
10430 virtual IOBuffer* BringsItsOwnIOBuffer();
10431 virtual std::string CopyIn(IOBuffer* dst);
10432
10433 private:
10434 IOBuffer m_io;
10435
10436 // Delete the copy and assign constructors.
10437 MemoryInput(const MemoryInput&) = delete;
10438 MemoryInput& operator=(const MemoryInput&) = delete;
10439 };
10440
10441 // --------
10442
10443 } // namespace sync_io
10444
10445 } // namespace wuffs_aux
10446
10447 // ---------------- Auxiliary - CBOR
10448
10449 namespace wuffs_aux {
10450
10451 struct DecodeCborResult {
10452 DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0);
10453
10454 std::string error_message;
10455 uint64_t cursor_position;
10456 };
10457
10458 class DecodeCborCallbacks {
10459 public:
10460 virtual ~DecodeCborCallbacks();
10461
10462 // AppendXxx are called for leaf nodes: literals, numbers, strings, etc.
10463
10464 virtual std::string AppendNull() = 0;
10465 virtual std::string AppendUndefined() = 0;
10466 virtual std::string AppendBool(bool val) = 0;
10467 virtual std::string AppendF64(double val) = 0;
10468 virtual std::string AppendI64(int64_t val) = 0;
10469 virtual std::string AppendU64(uint64_t val) = 0;
10470 virtual std::string AppendByteString(std::string&& val) = 0;
10471 virtual std::string AppendTextString(std::string&& val) = 0;
10472 virtual std::string AppendMinus1MinusX(uint64_t val) = 0;
10473 virtual std::string AppendCborSimpleValue(uint8_t val) = 0;
10474 virtual std::string AppendCborTag(uint64_t val) = 0;
10475
10476 // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR
10477 // maps (dictionaries).
10478 //
10479 // The flags bits combine exactly one of:
10480 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
10481 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
10482 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
10483 // and exactly one of:
10484 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
10485 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
10486 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
10487
10488 virtual std::string Push(uint32_t flags) = 0;
10489 virtual std::string Pop(uint32_t flags) = 0;
10490
10491 // Done is always the last Callback method called by DecodeCbor, whether or
10492 // not parsing the input as CBOR encountered an error. Even when successful,
10493 // trailing data may remain in input and buffer.
10494 //
10495 // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10496 // as DecodeCbor may then de-allocate the backing array.
10497 //
10498 // The default Done implementation is a no-op.
10499 virtual void //
10500 Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer);
10501 };
10502
10503 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10504 // inner representations for several reasons:
10505 // - It provides a home for the DefaultValue static method, for Foo callers
10506 // that want to override some but not all optional arguments.
10507 // - It provides the "Bar" name at Foo call sites, which can help self-
10508 // document Foo calls with many arguemnts.
10509 // - It provides some type safety against accidentally transposing or omitting
10510 // adjacent fundamentally-numeric-typed optional arguments.
10511
10512 // DecodeCborArgQuirks wraps an optional argument to DecodeCbor.
10513 struct DecodeCborArgQuirks {
10514 explicit DecodeCborArgQuirks(wuffs_base__slice_u32 repr0);
10515 explicit DecodeCborArgQuirks(uint32_t* ptr, size_t len);
10516
10517 // DefaultValue returns an empty slice.
10518 static DecodeCborArgQuirks DefaultValue();
10519
10520 wuffs_base__slice_u32 repr;
10521 };
10522
10523 // DecodeCbor calls callbacks based on the CBOR-formatted data in input.
10524 //
10525 // On success, the returned error_message is empty and cursor_position counts
10526 // the number of bytes consumed. On failure, error_message is non-empty and
10527 // cursor_position is the location of the error. That error may be a content
10528 // error (invalid CBOR) or an input error (e.g. network failure).
10529 DecodeCborResult //
10530 DecodeCbor(DecodeCborCallbacks& callbacks,
10531 sync_io::Input& input,
10532 DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue());
10533
10534 } // namespace wuffs_aux
10535
10536 // ---------------- Auxiliary - Image
10537
10538 namespace wuffs_aux {
10539
10540 struct DecodeImageResult {
10541 DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
10542 wuffs_base__pixel_buffer pixbuf0,
10543 std::string&& error_message0);
10544 DecodeImageResult(std::string&& error_message0);
10545
10546 MemOwner pixbuf_mem_owner;
10547 wuffs_base__pixel_buffer pixbuf;
10548 std::string error_message;
10549 };
10550
10551 // DecodeImageCallbacks are the callbacks given to DecodeImage. They are always
10552 // called in this order:
10553 // 1. SelectDecoder
10554 // 2. HandleMetadata
10555 // 3. SelectPixfmt
10556 // 4. AllocPixbuf
10557 // 5. AllocWorkbuf
10558 // 6. Done
10559 //
10560 // It may return early - the third callback might not be invoked if the second
10561 // one fails - but the final callback (Done) is always invoked.
10562 class DecodeImageCallbacks {
10563 public:
10564 // AllocPixbufResult holds a memory allocation (the result of malloc or new,
10565 // a statically allocated pointer, etc), or an error message. The memory is
10566 // de-allocated when mem_owner goes out of scope and is destroyed.
10567 struct AllocPixbufResult {
10568 AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
10569 AllocPixbufResult(std::string&& error_message0);
10570
10571 MemOwner mem_owner;
10572 wuffs_base__pixel_buffer pixbuf;
10573 std::string error_message;
10574 };
10575
10576 // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
10577 // a statically allocated pointer, etc), or an error message. The memory is
10578 // de-allocated when mem_owner goes out of scope and is destroyed.
10579 struct AllocWorkbufResult {
10580 AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
10581 AllocWorkbufResult(std::string&& error_message0);
10582
10583 MemOwner mem_owner;
10584 wuffs_base__slice_u8 workbuf;
10585 std::string error_message;
10586 };
10587
10588 virtual ~DecodeImageCallbacks();
10589
10590 // SelectDecoder returns the image decoder for the input data's file format.
10591 // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
10592 //
10593 // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
10594 // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that Wuffs'
10595 // standard library did not recognize the image format but if SelectDecoder
10596 // was overridden, it may examine the input data's starting bytes and still
10597 // provide its own image decoder, e.g. for an exotic image file format that's
10598 // not in Wuffs' standard library. The prefix_etc fields have the same
10599 // meaning as wuffs_base__magic_number_guess_fourcc arguments. SelectDecoder
10600 // implementations should not modify prefix_data's contents.
10601 //
10602 // SelectDecoder might be called more than once, since some image file
10603 // formats can wrap others. For example, a nominal BMP file can actually
10604 // contain a JPEG or a PNG.
10605 //
10606 // The default SelectDecoder accepts the FOURCC codes listed below. For
10607 // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
10608 // of the ETC file format is optional (for each value of ETC) and depends on
10609 // the corresponding module to be enabled at compile time (i.e. #define'ing
10610 // WUFFS_CONFIG__MODULE__ETC).
10611 // - WUFFS_BASE__FOURCC__BMP
10612 // - WUFFS_BASE__FOURCC__GIF
10613 // - WUFFS_BASE__FOURCC__NIE
10614 // - WUFFS_BASE__FOURCC__PNG
10615 // - WUFFS_BASE__FOURCC__TGA
10616 // - WUFFS_BASE__FOURCC__WBMP
10617 virtual wuffs_base__image_decoder::unique_ptr //
10618 SelectDecoder(uint32_t fourcc,
10619 wuffs_base__slice_u8 prefix_data,
10620 bool prefix_closed);
10621
10622 // HandleMetadata acknowledges image metadata. minfo.flavor will be one of:
10623 // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH
10624 // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED
10625 // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those
10626 // bytes should not be retained beyond the the HandleMetadata call.
10627 //
10628 // minfo.metadata__fourcc() will typically match one of the
10629 // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM |
10630 // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC
10631 // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA.
10632 //
10633 // It returns an error message, or an empty string on success.
10634 virtual std::string //
10635 HandleMetadata(const wuffs_base__more_information& minfo,
10636 wuffs_base__slice_u8 raw);
10637
10638 // SelectPixfmt returns the destination pixel format for AllocPixbuf. It
10639 // should return wuffs_base__make_pixel_format(etc) called with one of:
10640 // - WUFFS_BASE__PIXEL_FORMAT__BGR_565
10641 // - WUFFS_BASE__PIXEL_FORMAT__BGR
10642 // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL
10643 // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
10644 // - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL
10645 // - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL
10646 // - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL
10647 // or return image_config.pixcfg.pixel_format(). The latter means to use the
10648 // image file's natural pixel format. For example, GIF images' natural pixel
10649 // format is an indexed one.
10650 //
10651 // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).
10652 //
10653 // The default SelectPixfmt implementation returns
10654 // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which
10655 // is 4 bytes per pixel (8 bits per channel × 4 channels).
10656 virtual wuffs_base__pixel_format //
10657 SelectPixfmt(const wuffs_base__image_config& image_config);
10658
10659 // AllocPixbuf allocates the pixel buffer.
10660 //
10661 // allow_uninitialized_memory will be true if a valid background_color was
10662 // passed to DecodeImage, since the pixel buffer's contents will be
10663 // overwritten with that color after AllocPixbuf returns.
10664 //
10665 // The default AllocPixbuf implementation allocates either uninitialized or
10666 // zeroed memory. Zeroed memory typically corresponds to filling with opaque
10667 // black or transparent black, depending on the pixel format.
10668 virtual AllocPixbufResult //
10669 AllocPixbuf(const wuffs_base__image_config& image_config,
10670 bool allow_uninitialized_memory);
10671
10672 // AllocWorkbuf allocates the work buffer. The allocated buffer's length
10673 // should be at least len_range.min_incl, but larger allocations (up to
10674 // len_range.max_incl) may have better performance (by using more memory).
10675 //
10676 // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
10677 // of either uninitialized or zeroed memory.
10678 virtual AllocWorkbufResult //
10679 AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
10680 bool allow_uninitialized_memory);
10681
10682 // Done is always the last Callback method called by DecodeImage, whether or
10683 // not parsing the input encountered an error. Even when successful, trailing
10684 // data may remain in input and buffer.
10685 //
10686 // The image_decoder is the one returned by SelectDecoder (if SelectDecoder
10687 // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,
10688 // ownership moves to the Done implementation.
10689 //
10690 // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10691 // as DecodeImage may then de-allocate the backing array.
10692 //
10693 // The default Done implementation is a no-op, other than running the
10694 // image_decoder unique_ptr destructor.
10695 virtual void //
10696 Done(DecodeImageResult& result,
10697 sync_io::Input& input,
10698 IOBuffer& buffer,
10699 wuffs_base__image_decoder::unique_ptr image_decoder);
10700 };
10701
10702 extern const char DecodeImage_BufferIsTooShort[];
10703 extern const char DecodeImage_MaxInclDimensionExceeded[];
10704 extern const char DecodeImage_MaxInclMetadataLengthExceeded[];
10705 extern const char DecodeImage_OutOfMemory[];
10706 extern const char DecodeImage_UnexpectedEndOfFile[];
10707 extern const char DecodeImage_UnsupportedImageFormat[];
10708 extern const char DecodeImage_UnsupportedMetadata[];
10709 extern const char DecodeImage_UnsupportedPixelBlend[];
10710 extern const char DecodeImage_UnsupportedPixelConfiguration[];
10711 extern const char DecodeImage_UnsupportedPixelFormat[];
10712
10713 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10714 // inner representations for several reasons:
10715 // - It provides a home for the DefaultValue static method, for Foo callers
10716 // that want to override some but not all optional arguments.
10717 // - It provides the "Bar" name at Foo call sites, which can help self-
10718 // document Foo calls with many arguemnts.
10719 // - It provides some type safety against accidentally transposing or omitting
10720 // adjacent fundamentally-numeric-typed optional arguments.
10721
10722 // DecodeImageArgQuirks wraps an optional argument to DecodeImage.
10723 struct DecodeImageArgQuirks {
10724 explicit DecodeImageArgQuirks(wuffs_base__slice_u32 repr0);
10725 explicit DecodeImageArgQuirks(uint32_t* ptr, size_t len);
10726
10727 // DefaultValue returns an empty slice.
10728 static DecodeImageArgQuirks DefaultValue();
10729
10730 wuffs_base__slice_u32 repr;
10731 };
10732
10733 // DecodeImageArgFlags wraps an optional argument to DecodeImage.
10734 struct DecodeImageArgFlags {
10735 explicit DecodeImageArgFlags(uint64_t repr0);
10736
10737 // DefaultValue returns 0.
10738 static DecodeImageArgFlags DefaultValue();
10739
10740 // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, EXIF,
10741 // GAMA, ICCP, KVP, SRGB and XMP.
10742
10743 // Background Color.
10744 static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001;
10745 // Primary Chromaticities and White Point.
10746 static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002;
10747 // Exchangeable Image File Format.
10748 static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004;
10749 // Gamma Correction.
10750 static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008;
10751 // International Color Consortium Profile.
10752 static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010;
10753 // Key-Value Pair.
10754 //
10755 // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the
10756 // HandleMetadata callback, the raw argument contains UTF-8 strings.
10757 static constexpr uint64_t REPORT_METADATA_KVP = 0x0020;
10758 // Modification Time.
10759 static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040;
10760 // Offset (2-Dimensional).
10761 static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080;
10762 // Physical Dimensions.
10763 static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100;
10764 // Standard Red Green Blue (Rendering Intent).
10765 static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200;
10766 // Extensible Metadata Platform.
10767 static constexpr uint64_t REPORT_METADATA_XMP = 0x0400;
10768
10769 uint64_t repr;
10770 };
10771
10772 // DecodeImageArgPixelBlend wraps an optional argument to DecodeImage.
10773 struct DecodeImageArgPixelBlend {
10774 explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0);
10775
10776 // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC.
10777 static DecodeImageArgPixelBlend DefaultValue();
10778
10779 wuffs_base__pixel_blend repr;
10780 };
10781
10782 // DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage.
10783 struct DecodeImageArgBackgroundColor {
10784 explicit DecodeImageArgBackgroundColor(
10785 wuffs_base__color_u32_argb_premul repr0);
10786
10787 // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul.
10788 static DecodeImageArgBackgroundColor DefaultValue();
10789
10790 wuffs_base__color_u32_argb_premul repr;
10791 };
10792
10793 // DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage.
10794 struct DecodeImageArgMaxInclDimension {
10795 explicit DecodeImageArgMaxInclDimension(uint32_t repr0);
10796
10797 // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels.
10798 static DecodeImageArgMaxInclDimension DefaultValue();
10799
10800 uint32_t repr;
10801 };
10802
10803 // DecodeImageArgMaxInclMetadataLength wraps an optional argument to
10804 // DecodeImage.
10805 struct DecodeImageArgMaxInclMetadataLength {
10806 explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0);
10807
10808 // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB.
10809 static DecodeImageArgMaxInclMetadataLength DefaultValue();
10810
10811 uint64_t repr;
10812 };
10813
10814 // DecodeImage decodes the image data in input. A variety of image file formats
10815 // can be decoded, depending on what callbacks.SelectDecoder returns.
10816 //
10817 // For animated formats, only the first frame is returned, since the API is
10818 // simpler for synchronous I/O and having DecodeImage only return when
10819 // completely done, but rendering animation often involves handling other
10820 // events in between animation frames. To decode multiple frames of animated
10821 // images, or for asynchronous I/O (e.g. when decoding an image streamed over
10822 // the network), use Wuffs' lower level C API instead of its higher level,
10823 // simplified C++ API (the wuffs_aux API).
10824 //
10825 // The DecodeImageResult's fields depend on whether decoding succeeded:
10826 // - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()
10827 // is true.
10828 // - On partial success (e.g. the input file was truncated but we are still
10829 // able to decode some of the pixels), error_message is non-empty but
10830 // pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to
10831 // accept or reject partial success.
10832 // - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()
10833 // is false.
10834 //
10835 // The callbacks allocate the pixel buffer memory and work buffer memory. On
10836 // success, pixel buffer memory ownership is passed to the DecodeImage caller
10837 // as the returned pixbuf_mem_owner. Regardless of success or failure, the work
10838 // buffer memory is deleted.
10839 //
10840 // The pixel_blend (one of the constants listed below) determines how to
10841 // composite the decoded image over the pixel buffer's original pixels (as
10842 // returned by callbacks.AllocPixbuf):
10843 // - WUFFS_BASE__PIXEL_BLEND__SRC
10844 // - WUFFS_BASE__PIXEL_BLEND__SRC_OVER
10845 //
10846 // The background_color is used to fill the pixel buffer after
10847 // callbacks.AllocPixbuf returns, if it is valid in the
10848 // wuffs_base__color_u32_argb_premul__is_valid sense. The default value,
10849 // 0x0000_0001, is not valid since its Blue channel value (0x01) is greater
10850 // than its Alpha channel value (0x00). A valid background_color will typically
10851 // be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might
10852 // still be visible on partial (not total) success or when pixel_blend is
10853 // WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.
10854 //
10855 // Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's
10856 // width or height is greater than max_incl_dimension or if any opted-in (via
10857 // flags bits) metadata is longer than max_incl_metadata_length.
10858 DecodeImageResult //
10859 DecodeImage(DecodeImageCallbacks& callbacks,
10860 sync_io::Input& input,
10861 DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(),
10862 DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(),
10863 DecodeImageArgPixelBlend pixel_blend =
10864 DecodeImageArgPixelBlend::DefaultValue(),
10865 DecodeImageArgBackgroundColor background_color =
10866 DecodeImageArgBackgroundColor::DefaultValue(),
10867 DecodeImageArgMaxInclDimension max_incl_dimension =
10868 DecodeImageArgMaxInclDimension::DefaultValue(),
10869 DecodeImageArgMaxInclMetadataLength max_incl_metadata_length =
10870 DecodeImageArgMaxInclMetadataLength::DefaultValue());
10871
10872 } // namespace wuffs_aux
10873
10874 // ---------------- Auxiliary - JSON
10875
10876 namespace wuffs_aux {
10877
10878 struct DecodeJsonResult {
10879 DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0);
10880
10881 std::string error_message;
10882 uint64_t cursor_position;
10883 };
10884
10885 class DecodeJsonCallbacks {
10886 public:
10887 virtual ~DecodeJsonCallbacks();
10888
10889 // AppendXxx are called for leaf nodes: literals, numbers and strings. For
10890 // strings, the Callbacks implementation is responsible for tracking map keys
10891 // versus other values.
10892
10893 virtual std::string AppendNull() = 0;
10894 virtual std::string AppendBool(bool val) = 0;
10895 virtual std::string AppendF64(double val) = 0;
10896 virtual std::string AppendI64(int64_t val) = 0;
10897 virtual std::string AppendTextString(std::string&& val) = 0;
10898
10899 // Push and Pop are called for container nodes: JSON arrays (lists) and JSON
10900 // objects (dictionaries).
10901 //
10902 // The flags bits combine exactly one of:
10903 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
10904 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
10905 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
10906 // and exactly one of:
10907 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
10908 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
10909 // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
10910
10911 virtual std::string Push(uint32_t flags) = 0;
10912 virtual std::string Pop(uint32_t flags) = 0;
10913
10914 // Done is always the last Callback method called by DecodeJson, whether or
10915 // not parsing the input as JSON encountered an error. Even when successful,
10916 // trailing data may remain in input and buffer. See "Unintuitive JSON
10917 // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON
10918 // parsing and when it stops.
10919 //
10920 // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
10921 // as DecodeJson may then de-allocate the backing array.
10922 //
10923 // The default Done implementation is a no-op.
10924 virtual void //
10925 Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer);
10926 };
10927
10928 extern const char DecodeJson_BadJsonPointer[];
10929 extern const char DecodeJson_NoMatch[];
10930
10931 // The FooArgBar types add structure to Foo's optional arguments. They wrap
10932 // inner representations for several reasons:
10933 // - It provides a home for the DefaultValue static method, for Foo callers
10934 // that want to override some but not all optional arguments.
10935 // - It provides the "Bar" name at Foo call sites, which can help self-
10936 // document Foo calls with many arguemnts.
10937 // - It provides some type safety against accidentally transposing or omitting
10938 // adjacent fundamentally-numeric-typed optional arguments.
10939
10940 // DecodeJsonArgQuirks wraps an optional argument to DecodeJson.
10941 struct DecodeJsonArgQuirks {
10942 explicit DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0);
10943 explicit DecodeJsonArgQuirks(uint32_t* ptr, size_t len);
10944
10945 // DefaultValue returns an empty slice.
10946 static DecodeJsonArgQuirks DefaultValue();
10947
10948 wuffs_base__slice_u32 repr;
10949 };
10950
10951 // DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson.
10952 struct DecodeJsonArgJsonPointer {
10953 explicit DecodeJsonArgJsonPointer(std::string repr0);
10954
10955 // DefaultValue returns an empty string.
10956 static DecodeJsonArgJsonPointer DefaultValue();
10957
10958 std::string repr;
10959 };
10960
10961 // DecodeJson calls callbacks based on the JSON-formatted data in input.
10962 //
10963 // On success, the returned error_message is empty and cursor_position counts
10964 // the number of bytes consumed. On failure, error_message is non-empty and
10965 // cursor_position is the location of the error. That error may be a content
10966 // error (invalid JSON) or an input error (e.g. network failure).
10967 //
10968 // json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks
10969 // run for the input's sub-node that matches the query. DecodeJson_NoMatch is
10970 // returned if no matching sub-node was found. The empty query matches the
10971 // input's root node, consistent with JSON Pointer semantics.
10972 //
10973 // The JSON Pointer implementation is greedy: duplicate keys are not rejected
10974 // but only the first match for each '/'-separated fragment is followed.
10975 DecodeJsonResult //
10976 DecodeJson(DecodeJsonCallbacks& callbacks,
10977 sync_io::Input& input,
10978 DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(),
10979 DecodeJsonArgJsonPointer json_pointer =
10980 DecodeJsonArgJsonPointer::DefaultValue());
10981
10982 } // namespace wuffs_aux
10983
10984 #endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
10985
10986 // ‼ WUFFS C HEADER ENDS HERE.
10987 #ifdef WUFFS_IMPLEMENTATION
10988
10989 #ifdef __cplusplus
10990 extern "C" {
10991 #endif
10992
10993 // ---------------- Fundamentals
10994
10995 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
10996 // It's not foolproof, given C doesn't automatically zero memory before use,
10997 // but it should catch 99.99% of cases.
10998 //
10999 // Its (non-zero) value is arbitrary, based on md5sum("wuffs").
11000 #define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
11001
11002 // WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
11003 // error was previously encountered.
11004 //
11005 // Its (non-zero) value is arbitrary, based on md5sum("disabled").
11006 #define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
11007
11008 // Use switch cases for coroutine suspension points, similar to the technique
11009 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
11010 //
11011 // The implicit fallthrough is intentional.
11012 //
11013 // We use trivial macros instead of an explicit assignment and case statement
11014 // so that clang-format doesn't get confused by the unusual "case"s.
11015 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
11016 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
11017 coro_susp_point = n; \
11018 case n:;
11019
11020 #define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
11021 if (!status.repr) { \
11022 goto ok; \
11023 } else if (*status.repr != '$') { \
11024 goto exit; \
11025 } \
11026 coro_susp_point = n; \
11027 goto suspend; \
11028 case n:;
11029
11030 // The "defined(__clang__)" isn't redundant. While vanilla clang defines
11031 // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
11032 #if defined(__GNUC__) || defined(__clang__)
11033 #define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
11034 #define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
11035 #else
11036 #define WUFFS_BASE__LIKELY(expr) (expr)
11037 #define WUFFS_BASE__UNLIKELY(expr) (expr)
11038 #endif
11039
11040 // --------
11041
11042 static inline wuffs_base__empty_struct //
wuffs_base__ignore_status(wuffs_base__status z)11043 wuffs_base__ignore_status(wuffs_base__status z) {
11044 return wuffs_base__make_empty_struct();
11045 }
11046
11047 static inline wuffs_base__status //
wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z)11048 wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
11049 if (z.repr && (*z.repr == '$')) {
11050 z.repr = wuffs_base__error__cannot_return_a_suspension;
11051 }
11052 return z;
11053 }
11054
11055 // --------
11056
11057 // wuffs_base__iterate_total_advance returns the exclusive pointer-offset at
11058 // which iteration should stop. The overall slice has length total_len, each
11059 // iteration's sub-slice has length iter_len and are placed iter_advance apart.
11060 //
11061 // The iter_advance may not be larger than iter_len. The iter_advance may be
11062 // smaller than iter_len, in which case the sub-slices will overlap.
11063 //
11064 // The return value r satisfies ((0 <= r) && (r <= total_len)).
11065 //
11066 // For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are
11067 // four iterations at offsets 0, 3, 6 and 9. This function returns 12.
11068 //
11069 // 0123456789012345
11070 // [....]
11071 // [....]
11072 // [....]
11073 // [....]
11074 // $
11075 // 0123456789012345
11076 //
11077 // For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are
11078 // three iterations at offsets 0, 5 and 10. This function returns 15.
11079 //
11080 // 0123456789012345
11081 // [....]
11082 // [....]
11083 // [....]
11084 // $
11085 // 0123456789012345
11086 static inline size_t //
wuffs_base__iterate_total_advance(size_t total_len,size_t iter_len,size_t iter_advance)11087 wuffs_base__iterate_total_advance(size_t total_len,
11088 size_t iter_len,
11089 size_t iter_advance) {
11090 if (total_len >= iter_len) {
11091 size_t n = total_len - iter_len;
11092 return ((n / iter_advance) * iter_advance) + iter_advance;
11093 }
11094 return 0;
11095 }
11096
11097 // ---------------- Numeric Types
11098
11099 extern const uint8_t wuffs_base__low_bits_mask__u8[8];
11100 extern const uint16_t wuffs_base__low_bits_mask__u16[16];
11101 extern const uint32_t wuffs_base__low_bits_mask__u32[32];
11102 extern const uint64_t wuffs_base__low_bits_mask__u64[64];
11103
11104 #define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
11105 #define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
11106 #define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
11107 #define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
11108
11109 // --------
11110
11111 static inline void //
wuffs_base__u8__sat_add_indirect(uint8_t * x,uint8_t y)11112 wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
11113 *x = wuffs_base__u8__sat_add(*x, y);
11114 }
11115
11116 static inline void //
wuffs_base__u8__sat_sub_indirect(uint8_t * x,uint8_t y)11117 wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
11118 *x = wuffs_base__u8__sat_sub(*x, y);
11119 }
11120
11121 static inline void //
wuffs_base__u16__sat_add_indirect(uint16_t * x,uint16_t y)11122 wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
11123 *x = wuffs_base__u16__sat_add(*x, y);
11124 }
11125
11126 static inline void //
wuffs_base__u16__sat_sub_indirect(uint16_t * x,uint16_t y)11127 wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
11128 *x = wuffs_base__u16__sat_sub(*x, y);
11129 }
11130
11131 static inline void //
wuffs_base__u32__sat_add_indirect(uint32_t * x,uint32_t y)11132 wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
11133 *x = wuffs_base__u32__sat_add(*x, y);
11134 }
11135
11136 static inline void //
wuffs_base__u32__sat_sub_indirect(uint32_t * x,uint32_t y)11137 wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
11138 *x = wuffs_base__u32__sat_sub(*x, y);
11139 }
11140
11141 static inline void //
wuffs_base__u64__sat_add_indirect(uint64_t * x,uint64_t y)11142 wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
11143 *x = wuffs_base__u64__sat_add(*x, y);
11144 }
11145
11146 static inline void //
wuffs_base__u64__sat_sub_indirect(uint64_t * x,uint64_t y)11147 wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
11148 *x = wuffs_base__u64__sat_sub(*x, y);
11149 }
11150
11151 // ---------------- Slices and Tables
11152
11153 // wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
11154 static inline wuffs_base__slice_u8 //
wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s,uint64_t up_to)11155 wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
11156 if (((uint64_t)(s.len)) > up_to) {
11157 s.len = ((size_t)up_to);
11158 }
11159 return s;
11160 }
11161
11162 // wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
11163 static inline wuffs_base__slice_u8 //
wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s,uint64_t up_to)11164 wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
11165 if (((uint64_t)(s.len)) > up_to) {
11166 s.ptr += ((uint64_t)(s.len)) - up_to;
11167 s.len = ((size_t)up_to);
11168 }
11169 return s;
11170 }
11171
11172 // wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
11173 // where len is the minimum of dst.len and src.len.
11174 //
11175 // Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
11176 // slice) is valid and results in a no-op.
11177 static inline uint64_t //
wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src)11178 wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
11179 wuffs_base__slice_u8 src) {
11180 size_t len = dst.len < src.len ? dst.len : src.len;
11181 if (len > 0) {
11182 memmove(dst.ptr, src.ptr, len);
11183 }
11184 return len;
11185 }
11186
11187 // --------
11188
11189 static inline wuffs_base__slice_u8 //
wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t,uint32_t y)11190 wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) {
11191 if (y < t.height) {
11192 return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
11193 }
11194 return wuffs_base__make_slice_u8(NULL, 0);
11195 }
11196
11197 // ---------------- Slices and Tables (Utility)
11198
11199 #define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
11200
11201 // ---------------- Ranges and Rects
11202
11203 static inline uint32_t //
wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32 * r)11204 wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) {
11205 return r->min_incl;
11206 }
11207
11208 static inline uint32_t //
wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32 * r)11209 wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) {
11210 return r->max_incl;
11211 }
11212
11213 static inline uint32_t //
wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32 * r)11214 wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) {
11215 return r->min_incl;
11216 }
11217
11218 static inline uint32_t //
wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32 * r)11219 wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) {
11220 return r->max_excl;
11221 }
11222
11223 static inline uint64_t //
wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64 * r)11224 wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) {
11225 return r->min_incl;
11226 }
11227
11228 static inline uint64_t //
wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64 * r)11229 wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) {
11230 return r->max_incl;
11231 }
11232
11233 static inline uint64_t //
wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64 * r)11234 wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) {
11235 return r->min_incl;
11236 }
11237
11238 static inline uint64_t //
wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64 * r)11239 wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) {
11240 return r->max_excl;
11241 }
11242
11243 // ---------------- Ranges and Rects (Utility)
11244
11245 #define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32
11246 #define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32
11247 #define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64
11248 #define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64
11249 #define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32
11250 #define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32
11251 #define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
11252 #define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
11253 #define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
11254 #define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
11255 #define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
11256 #define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
11257
11258 // ---------------- I/O
11259
11260 static inline uint64_t //
wuffs_base__io__count_since(uint64_t mark,uint64_t index)11261 wuffs_base__io__count_since(uint64_t mark, uint64_t index) {
11262 if (index >= mark) {
11263 return index - mark;
11264 }
11265 return 0;
11266 }
11267
11268 // TODO: drop the "const" in "const uint8_t* ptr". Some though required about
11269 // the base.io_reader.since method returning a mutable "slice base.u8".
11270 #if defined(__GNUC__)
11271 #pragma GCC diagnostic push
11272 #pragma GCC diagnostic ignored "-Wcast-qual"
11273 #endif
11274 static inline wuffs_base__slice_u8 //
wuffs_base__io__since(uint64_t mark,uint64_t index,const uint8_t * ptr)11275 wuffs_base__io__since(uint64_t mark, uint64_t index, const uint8_t* ptr) {
11276 if (index >= mark) {
11277 return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark,
11278 ((size_t)(index - mark)));
11279 }
11280 return wuffs_base__make_slice_u8(NULL, 0);
11281 }
11282 #if defined(__GNUC__)
11283 #pragma GCC diagnostic pop
11284 #endif
11285
11286 // --------
11287
11288 static inline void //
wuffs_base__io_reader__limit(const uint8_t ** ptr_io2_r,const uint8_t * iop_r,uint64_t limit)11289 wuffs_base__io_reader__limit(const uint8_t** ptr_io2_r,
11290 const uint8_t* iop_r,
11291 uint64_t limit) {
11292 if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) {
11293 *ptr_io2_r = iop_r + limit;
11294 }
11295 }
11296
11297 static inline uint32_t //
wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t ** ptr_iop_r,const uint8_t * io2_r,uint32_t length,wuffs_base__slice_u8 dst)11298 wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r,
11299 const uint8_t* io2_r,
11300 uint32_t length,
11301 wuffs_base__slice_u8 dst) {
11302 const uint8_t* iop_r = *ptr_iop_r;
11303 size_t n = dst.len;
11304 if (n > length) {
11305 n = length;
11306 }
11307 if (n > ((size_t)(io2_r - iop_r))) {
11308 n = (size_t)(io2_r - iop_r);
11309 }
11310 if (n > 0) {
11311 memmove(dst.ptr, iop_r, n);
11312 *ptr_iop_r += n;
11313 }
11314 return (uint32_t)(n);
11315 }
11316
11317 // wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes
11318 // start with the given prefix (up to 7 bytes long). It is peek-like, not
11319 // read-like, in that there are no side-effects.
11320 //
11321 // The low 3 bits of a hold the prefix length, n.
11322 //
11323 // The high 56 bits of a hold the prefix itself, in little-endian order. The
11324 // first prefix byte is in bits 8..=15, the second prefix byte is in bits
11325 // 16..=23, etc. The high (8 * (7 - n)) bits are ignored.
11326 //
11327 // There are three possible return values:
11328 // - 0 means success.
11329 // - 1 means inconclusive, equivalent to "$short read".
11330 // - 2 means failure.
11331 static inline uint32_t //
wuffs_base__io_reader__match7(const uint8_t * iop_r,const uint8_t * io2_r,wuffs_base__io_buffer * r,uint64_t a)11332 wuffs_base__io_reader__match7(const uint8_t* iop_r,
11333 const uint8_t* io2_r,
11334 wuffs_base__io_buffer* r,
11335 uint64_t a) {
11336 uint32_t n = a & 7;
11337 a >>= 8;
11338 if ((io2_r - iop_r) >= 8) {
11339 uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r);
11340 uint32_t shift = 8 * (8 - n);
11341 return ((a << shift) == (x << shift)) ? 0 : 2;
11342 }
11343 for (; n > 0; n--) {
11344 if (iop_r >= io2_r) {
11345 return (r && r->meta.closed) ? 2 : 1;
11346 } else if (*iop_r != ((uint8_t)(a))) {
11347 return 2;
11348 }
11349 iop_r++;
11350 a >>= 8;
11351 }
11352 return 0;
11353 }
11354
11355 static inline wuffs_base__io_buffer* //
wuffs_base__io_reader__set(wuffs_base__io_buffer * b,const uint8_t ** ptr_iop_r,const uint8_t ** ptr_io0_r,const uint8_t ** ptr_io1_r,const uint8_t ** ptr_io2_r,wuffs_base__slice_u8 data,uint64_t history_position)11356 wuffs_base__io_reader__set(wuffs_base__io_buffer* b,
11357 const uint8_t** ptr_iop_r,
11358 const uint8_t** ptr_io0_r,
11359 const uint8_t** ptr_io1_r,
11360 const uint8_t** ptr_io2_r,
11361 wuffs_base__slice_u8 data,
11362 uint64_t history_position) {
11363 b->data = data;
11364 b->meta.wi = data.len;
11365 b->meta.ri = 0;
11366 b->meta.pos = history_position;
11367 b->meta.closed = false;
11368
11369 *ptr_iop_r = data.ptr;
11370 *ptr_io0_r = data.ptr;
11371 *ptr_io1_r = data.ptr;
11372 *ptr_io2_r = data.ptr + data.len;
11373
11374 return b;
11375 }
11376
11377 // --------
11378
11379 static inline uint64_t //
wuffs_base__io_writer__copy_from_slice(uint8_t ** ptr_iop_w,uint8_t * io2_w,wuffs_base__slice_u8 src)11380 wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
11381 uint8_t* io2_w,
11382 wuffs_base__slice_u8 src) {
11383 uint8_t* iop_w = *ptr_iop_w;
11384 size_t n = src.len;
11385 if (n > ((size_t)(io2_w - iop_w))) {
11386 n = (size_t)(io2_w - iop_w);
11387 }
11388 if (n > 0) {
11389 memmove(iop_w, src.ptr, n);
11390 *ptr_iop_w += n;
11391 }
11392 return (uint64_t)(n);
11393 }
11394
11395 static inline void //
wuffs_base__io_writer__limit(uint8_t ** ptr_io2_w,uint8_t * iop_w,uint64_t limit)11396 wuffs_base__io_writer__limit(uint8_t** ptr_io2_w,
11397 uint8_t* iop_w,
11398 uint64_t limit) {
11399 if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) {
11400 *ptr_io2_w = iop_w + limit;
11401 }
11402 }
11403
11404 static inline uint32_t //
wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11405 wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w,
11406 uint8_t* io0_w,
11407 uint8_t* io2_w,
11408 uint32_t length,
11409 uint32_t distance) {
11410 if (!distance) {
11411 return 0;
11412 }
11413 uint8_t* p = *ptr_iop_w;
11414 if ((size_t)(p - io0_w) < (size_t)(distance)) {
11415 return 0;
11416 }
11417 uint8_t* q = p - distance;
11418 size_t n = (size_t)(io2_w - p);
11419 if ((size_t)(length) > n) {
11420 length = (uint32_t)(n);
11421 } else {
11422 n = (size_t)(length);
11423 }
11424 // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
11425 // is mostly because 3 is the minimum length for the deflate format. This
11426 // function implementation shouldn't overfit to that one format. Perhaps the
11427 // limited_copy_u32_from_history Wuffs method should also take an unroll hint
11428 // argument, and the cgen can look if that argument is the constant
11429 // expression '3'.
11430 //
11431 // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below.
11432 for (; n >= 3; n -= 3) {
11433 *p++ = *q++;
11434 *p++ = *q++;
11435 *p++ = *q++;
11436 }
11437 for (; n; n--) {
11438 *p++ = *q++;
11439 }
11440 *ptr_iop_w = p;
11441 return length;
11442 }
11443
11444 // wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the
11445 // wuffs_base__io_writer__limited_copy_u32_from_history function above, but has
11446 // stronger pre-conditions.
11447 //
11448 // The caller needs to prove that:
11449 // - length <= (io2_w - *ptr_iop_w)
11450 // - distance >= 1
11451 // - distance <= (*ptr_iop_w - io0_w)
11452 static inline uint32_t //
wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11453 wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t** ptr_iop_w,
11454 uint8_t* io0_w,
11455 uint8_t* io2_w,
11456 uint32_t length,
11457 uint32_t distance) {
11458 uint8_t* p = *ptr_iop_w;
11459 uint8_t* q = p - distance;
11460 uint32_t n = length;
11461 for (; n >= 3; n -= 3) {
11462 *p++ = *q++;
11463 *p++ = *q++;
11464 *p++ = *q++;
11465 }
11466 for (; n; n--) {
11467 *p++ = *q++;
11468 }
11469 *ptr_iop_w = p;
11470 return length;
11471 }
11472
11473 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast
11474 // copies the previous byte (the one immediately before *ptr_iop_w), copying 8
11475 // byte chunks at a time. Each chunk contains 8 repetitions of the same byte.
11476 //
11477 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
11478 // As a special case, a zero length rounds up to 8 (even though 0 is already a
11479 // multiple of 8), since there is always at least one 8 byte chunk copied.
11480 //
11481 // In terms of advancing *ptr_iop_w, length is not rounded up.
11482 //
11483 // The caller needs to prove that:
11484 // - (length + 8) <= (io2_w - *ptr_iop_w)
11485 // - distance == 1
11486 // - distance <= (*ptr_iop_w - io0_w)
11487 static inline uint32_t //
wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11488 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
11489 uint8_t** ptr_iop_w,
11490 uint8_t* io0_w,
11491 uint8_t* io2_w,
11492 uint32_t length,
11493 uint32_t distance) {
11494 uint8_t* p = *ptr_iop_w;
11495 uint64_t x = p[-1];
11496 x |= x << 8;
11497 x |= x << 16;
11498 x |= x << 32;
11499 uint32_t n = length;
11500 while (1) {
11501 wuffs_base__poke_u64le__no_bounds_check(p, x);
11502 if (n <= 8) {
11503 p += n;
11504 break;
11505 }
11506 p += 8;
11507 n -= 8;
11508 }
11509 *ptr_iop_w = p;
11510 return length;
11511 }
11512
11513 // wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast is
11514 // like the wuffs_base__io_writer__limited_copy_u32_from_history_fast function
11515 // above, but copies 8 byte chunks at a time.
11516 //
11517 // In terms of number of bytes copied, length is rounded up to a multiple of 8.
11518 // As a special case, a zero length rounds up to 8 (even though 0 is already a
11519 // multiple of 8), since there is always at least one 8 byte chunk copied.
11520 //
11521 // In terms of advancing *ptr_iop_w, length is not rounded up.
11522 //
11523 // The caller needs to prove that:
11524 // - (length + 8) <= (io2_w - *ptr_iop_w)
11525 // - distance >= 8
11526 // - distance <= (*ptr_iop_w - io0_w)
11527 static inline uint32_t //
wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(uint8_t ** ptr_iop_w,uint8_t * io0_w,uint8_t * io2_w,uint32_t length,uint32_t distance)11528 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
11529 uint8_t** ptr_iop_w,
11530 uint8_t* io0_w,
11531 uint8_t* io2_w,
11532 uint32_t length,
11533 uint32_t distance) {
11534 uint8_t* p = *ptr_iop_w;
11535 uint8_t* q = p - distance;
11536 uint32_t n = length;
11537 while (1) {
11538 memcpy(p, q, 8);
11539 if (n <= 8) {
11540 p += n;
11541 break;
11542 }
11543 p += 8;
11544 q += 8;
11545 n -= 8;
11546 }
11547 *ptr_iop_w = p;
11548 return length;
11549 }
11550
11551 static inline uint32_t //
wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t ** ptr_iop_w,uint8_t * io2_w,uint32_t length,const uint8_t ** ptr_iop_r,const uint8_t * io2_r)11552 wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t** ptr_iop_w,
11553 uint8_t* io2_w,
11554 uint32_t length,
11555 const uint8_t** ptr_iop_r,
11556 const uint8_t* io2_r) {
11557 uint8_t* iop_w = *ptr_iop_w;
11558 size_t n = length;
11559 if (n > ((size_t)(io2_w - iop_w))) {
11560 n = (size_t)(io2_w - iop_w);
11561 }
11562 const uint8_t* iop_r = *ptr_iop_r;
11563 if (n > ((size_t)(io2_r - iop_r))) {
11564 n = (size_t)(io2_r - iop_r);
11565 }
11566 if (n > 0) {
11567 memmove(iop_w, iop_r, n);
11568 *ptr_iop_w += n;
11569 *ptr_iop_r += n;
11570 }
11571 return (uint32_t)(n);
11572 }
11573
11574 static inline uint32_t //
wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t ** ptr_iop_w,uint8_t * io2_w,uint32_t length,wuffs_base__slice_u8 src)11575 wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t** ptr_iop_w,
11576 uint8_t* io2_w,
11577 uint32_t length,
11578 wuffs_base__slice_u8 src) {
11579 uint8_t* iop_w = *ptr_iop_w;
11580 size_t n = src.len;
11581 if (n > length) {
11582 n = length;
11583 }
11584 if (n > ((size_t)(io2_w - iop_w))) {
11585 n = (size_t)(io2_w - iop_w);
11586 }
11587 if (n > 0) {
11588 memmove(iop_w, src.ptr, n);
11589 *ptr_iop_w += n;
11590 }
11591 return (uint32_t)(n);
11592 }
11593
11594 static inline wuffs_base__io_buffer* //
wuffs_base__io_writer__set(wuffs_base__io_buffer * b,uint8_t ** ptr_iop_w,uint8_t ** ptr_io0_w,uint8_t ** ptr_io1_w,uint8_t ** ptr_io2_w,wuffs_base__slice_u8 data,uint64_t history_position)11595 wuffs_base__io_writer__set(wuffs_base__io_buffer* b,
11596 uint8_t** ptr_iop_w,
11597 uint8_t** ptr_io0_w,
11598 uint8_t** ptr_io1_w,
11599 uint8_t** ptr_io2_w,
11600 wuffs_base__slice_u8 data,
11601 uint64_t history_position) {
11602 b->data = data;
11603 b->meta.wi = 0;
11604 b->meta.ri = 0;
11605 b->meta.pos = history_position;
11606 b->meta.closed = false;
11607
11608 *ptr_iop_w = data.ptr;
11609 *ptr_io0_w = data.ptr;
11610 *ptr_io1_w = data.ptr;
11611 *ptr_io2_w = data.ptr + data.len;
11612
11613 return b;
11614 }
11615
11616 // ---------------- I/O (Utility)
11617
11618 #define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader
11619 #define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer
11620
11621 // ---------------- Tokens
11622
11623 // ---------------- Tokens (Utility)
11624
11625 // ---------------- Memory Allocation
11626
11627 // ---------------- Images
11628
11629 WUFFS_BASE__MAYBE_STATIC uint64_t //
11630 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
11631 const wuffs_base__pixel_swizzler* p,
11632 uint32_t up_to_num_pixels,
11633 wuffs_base__slice_u8 dst,
11634 wuffs_base__slice_u8 dst_palette,
11635 const uint8_t** ptr_iop_r,
11636 const uint8_t* io2_r);
11637
11638 WUFFS_BASE__MAYBE_STATIC uint64_t //
11639 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
11640 const wuffs_base__pixel_swizzler* p,
11641 wuffs_base__slice_u8 dst,
11642 wuffs_base__slice_u8 dst_palette,
11643 const uint8_t** ptr_iop_r,
11644 const uint8_t* io2_r);
11645
11646 WUFFS_BASE__MAYBE_STATIC uint64_t //
11647 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
11648 const wuffs_base__pixel_swizzler* p,
11649 wuffs_base__slice_u8 dst,
11650 wuffs_base__slice_u8 dst_palette,
11651 uint64_t num_pixels);
11652
11653 // ---------------- Images (Utility)
11654
11655 #define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format
11656
11657 // ---------------- String Conversions
11658
11659 // ---------------- Unicode and UTF-8
11660
11661 // ----------------
11662
11663 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
11664 defined(WUFFS_CONFIG__MODULE__BASE__CORE)
11665
11666 const uint8_t wuffs_base__low_bits_mask__u8[8] = {
11667 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F,
11668 };
11669
11670 const uint16_t wuffs_base__low_bits_mask__u16[16] = {
11671 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F,
11672 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
11673 };
11674
11675 const uint32_t wuffs_base__low_bits_mask__u32[32] = {
11676 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
11677 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
11678 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
11679 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
11680 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
11681 0x3FFFFFFF, 0x7FFFFFFF,
11682 };
11683
11684 const uint64_t wuffs_base__low_bits_mask__u64[64] = {
11685 0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
11686 0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
11687 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
11688 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
11689 0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
11690 0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
11691 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
11692 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
11693 0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
11694 0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
11695 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
11696 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
11697 0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
11698 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
11699 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
11700 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
11701 0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
11702 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
11703 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
11704 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
11705 0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
11706 0x7FFFFFFFFFFFFFFF,
11707 };
11708
11709 const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
11710 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
11711 0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
11712 };
11713
11714 const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect";
11715 const char wuffs_base__note__end_of_data[] = "@base: end of data";
11716 const char wuffs_base__note__metadata_reported[] = "@base: metadata reported";
11717 const char wuffs_base__suspension__even_more_information[] = "$base: even more information";
11718 const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read";
11719 const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write";
11720 const char wuffs_base__suspension__short_read[] = "$base: short read";
11721 const char wuffs_base__suspension__short_write[] = "$base: short write";
11722 const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position";
11723 const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)";
11724 const char wuffs_base__error__bad_argument[] = "#base: bad argument";
11725 const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence";
11726 const char wuffs_base__error__bad_data[] = "#base: bad data";
11727 const char wuffs_base__error__bad_receiver[] = "#base: bad receiver";
11728 const char wuffs_base__error__bad_restart[] = "#base: bad restart";
11729 const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver";
11730 const char wuffs_base__error__bad_vtable[] = "#base: bad vtable";
11731 const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length";
11732 const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version";
11733 const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension";
11734 const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error";
11735 const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed";
11736 const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called";
11737 const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls";
11738 const char wuffs_base__error__no_more_information[] = "#base: no more information";
11739 const char wuffs_base__error__not_enough_data[] = "#base: not enough data";
11740 const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds";
11741 const char wuffs_base__error__unsupported_method[] = "#base: unsupported method";
11742 const char wuffs_base__error__unsupported_option[] = "#base: unsupported option";
11743 const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option";
11744 const char wuffs_base__error__too_much_data[] = "#base: too much data";
11745
11746 const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32";
11747 const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder";
11748 const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer";
11749 const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder";
11750
11751 #endif // !defined(WUFFS_CONFIG__MODULES) ||
11752 // defined(WUFFS_CONFIG__MODULE__BASE) ||
11753 // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
11754
11755 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
11756 defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
11757
11758 // ---------------- Interface Definitions.
11759
11760 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__hasher_u32__set_quirk_enabled(wuffs_base__hasher_u32 * self,uint32_t a_quirk,bool a_enabled)11761 wuffs_base__hasher_u32__set_quirk_enabled(
11762 wuffs_base__hasher_u32* self,
11763 uint32_t a_quirk,
11764 bool a_enabled) {
11765 if (!self) {
11766 return wuffs_base__make_empty_struct();
11767 }
11768 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11769 return wuffs_base__make_empty_struct();
11770 }
11771
11772 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11773 int i;
11774 for (i = 0; i < 63; i++) {
11775 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
11776 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
11777 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
11778 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
11779 } else if (v->vtable_name == NULL) {
11780 break;
11781 }
11782 v++;
11783 }
11784
11785 return wuffs_base__make_empty_struct();
11786 }
11787
11788 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__hasher_u32__update_u32(wuffs_base__hasher_u32 * self,wuffs_base__slice_u8 a_x)11789 wuffs_base__hasher_u32__update_u32(
11790 wuffs_base__hasher_u32* self,
11791 wuffs_base__slice_u8 a_x) {
11792 if (!self) {
11793 return 0;
11794 }
11795 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11796 return 0;
11797 }
11798
11799 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11800 int i;
11801 for (i = 0; i < 63; i++) {
11802 if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
11803 const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
11804 (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
11805 return (*func_ptrs->update_u32)(self, a_x);
11806 } else if (v->vtable_name == NULL) {
11807 break;
11808 }
11809 v++;
11810 }
11811
11812 return 0;
11813 }
11814
11815 // --------
11816
11817 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__decode_frame(wuffs_base__image_decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)11818 wuffs_base__image_decoder__decode_frame(
11819 wuffs_base__image_decoder* self,
11820 wuffs_base__pixel_buffer* a_dst,
11821 wuffs_base__io_buffer* a_src,
11822 wuffs_base__pixel_blend a_blend,
11823 wuffs_base__slice_u8 a_workbuf,
11824 wuffs_base__decode_frame_options* a_opts) {
11825 if (!self) {
11826 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11827 }
11828 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11829 return wuffs_base__make_status(
11830 (self->private_impl.magic == WUFFS_BASE__DISABLED)
11831 ? wuffs_base__error__disabled_by_previous_error
11832 : wuffs_base__error__initialize_not_called);
11833 }
11834
11835 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11836 int i;
11837 for (i = 0; i < 63; i++) {
11838 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11839 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11840 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11841 return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts);
11842 } else if (v->vtable_name == NULL) {
11843 break;
11844 }
11845 v++;
11846 }
11847
11848 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11849 }
11850
11851 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__decode_frame_config(wuffs_base__image_decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)11852 wuffs_base__image_decoder__decode_frame_config(
11853 wuffs_base__image_decoder* self,
11854 wuffs_base__frame_config* a_dst,
11855 wuffs_base__io_buffer* a_src) {
11856 if (!self) {
11857 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11858 }
11859 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11860 return wuffs_base__make_status(
11861 (self->private_impl.magic == WUFFS_BASE__DISABLED)
11862 ? wuffs_base__error__disabled_by_previous_error
11863 : wuffs_base__error__initialize_not_called);
11864 }
11865
11866 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11867 int i;
11868 for (i = 0; i < 63; i++) {
11869 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11870 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11871 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11872 return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
11873 } else if (v->vtable_name == NULL) {
11874 break;
11875 }
11876 v++;
11877 }
11878
11879 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11880 }
11881
11882 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__decode_image_config(wuffs_base__image_decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)11883 wuffs_base__image_decoder__decode_image_config(
11884 wuffs_base__image_decoder* self,
11885 wuffs_base__image_config* a_dst,
11886 wuffs_base__io_buffer* a_src) {
11887 if (!self) {
11888 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
11889 }
11890 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
11891 return wuffs_base__make_status(
11892 (self->private_impl.magic == WUFFS_BASE__DISABLED)
11893 ? wuffs_base__error__disabled_by_previous_error
11894 : wuffs_base__error__initialize_not_called);
11895 }
11896
11897 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11898 int i;
11899 for (i = 0; i < 63; i++) {
11900 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11901 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11902 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11903 return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
11904 } else if (v->vtable_name == NULL) {
11905 break;
11906 }
11907 v++;
11908 }
11909
11910 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
11911 }
11912
11913 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_base__image_decoder__frame_dirty_rect(const wuffs_base__image_decoder * self)11914 wuffs_base__image_decoder__frame_dirty_rect(
11915 const wuffs_base__image_decoder* self) {
11916 if (!self) {
11917 return wuffs_base__utility__empty_rect_ie_u32();
11918 }
11919 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11920 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11921 return wuffs_base__utility__empty_rect_ie_u32();
11922 }
11923
11924 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11925 int i;
11926 for (i = 0; i < 63; i++) {
11927 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11928 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11929 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11930 return (*func_ptrs->frame_dirty_rect)(self);
11931 } else if (v->vtable_name == NULL) {
11932 break;
11933 }
11934 v++;
11935 }
11936
11937 return wuffs_base__utility__empty_rect_ie_u32();
11938 }
11939
11940 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_base__image_decoder__num_animation_loops(const wuffs_base__image_decoder * self)11941 wuffs_base__image_decoder__num_animation_loops(
11942 const wuffs_base__image_decoder* self) {
11943 if (!self) {
11944 return 0;
11945 }
11946 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11947 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11948 return 0;
11949 }
11950
11951 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11952 int i;
11953 for (i = 0; i < 63; i++) {
11954 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11955 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11956 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11957 return (*func_ptrs->num_animation_loops)(self);
11958 } else if (v->vtable_name == NULL) {
11959 break;
11960 }
11961 v++;
11962 }
11963
11964 return 0;
11965 }
11966
11967 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frame_configs(const wuffs_base__image_decoder * self)11968 wuffs_base__image_decoder__num_decoded_frame_configs(
11969 const wuffs_base__image_decoder* self) {
11970 if (!self) {
11971 return 0;
11972 }
11973 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
11974 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
11975 return 0;
11976 }
11977
11978 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
11979 int i;
11980 for (i = 0; i < 63; i++) {
11981 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
11982 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
11983 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
11984 return (*func_ptrs->num_decoded_frame_configs)(self);
11985 } else if (v->vtable_name == NULL) {
11986 break;
11987 }
11988 v++;
11989 }
11990
11991 return 0;
11992 }
11993
11994 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_base__image_decoder__num_decoded_frames(const wuffs_base__image_decoder * self)11995 wuffs_base__image_decoder__num_decoded_frames(
11996 const wuffs_base__image_decoder* self) {
11997 if (!self) {
11998 return 0;
11999 }
12000 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12001 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12002 return 0;
12003 }
12004
12005 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12006 int i;
12007 for (i = 0; i < 63; i++) {
12008 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12009 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12010 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12011 return (*func_ptrs->num_decoded_frames)(self);
12012 } else if (v->vtable_name == NULL) {
12013 break;
12014 }
12015 v++;
12016 }
12017
12018 return 0;
12019 }
12020
12021 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__restart_frame(wuffs_base__image_decoder * self,uint64_t a_index,uint64_t a_io_position)12022 wuffs_base__image_decoder__restart_frame(
12023 wuffs_base__image_decoder* self,
12024 uint64_t a_index,
12025 uint64_t a_io_position) {
12026 if (!self) {
12027 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12028 }
12029 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12030 return wuffs_base__make_status(
12031 (self->private_impl.magic == WUFFS_BASE__DISABLED)
12032 ? wuffs_base__error__disabled_by_previous_error
12033 : wuffs_base__error__initialize_not_called);
12034 }
12035
12036 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12037 int i;
12038 for (i = 0; i < 63; i++) {
12039 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12040 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12041 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12042 return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
12043 } else if (v->vtable_name == NULL) {
12044 break;
12045 }
12046 v++;
12047 }
12048
12049 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12050 }
12051
12052 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__image_decoder__set_quirk_enabled(wuffs_base__image_decoder * self,uint32_t a_quirk,bool a_enabled)12053 wuffs_base__image_decoder__set_quirk_enabled(
12054 wuffs_base__image_decoder* self,
12055 uint32_t a_quirk,
12056 bool a_enabled) {
12057 if (!self) {
12058 return wuffs_base__make_empty_struct();
12059 }
12060 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12061 return wuffs_base__make_empty_struct();
12062 }
12063
12064 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12065 int i;
12066 for (i = 0; i < 63; i++) {
12067 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12068 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12069 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12070 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
12071 } else if (v->vtable_name == NULL) {
12072 break;
12073 }
12074 v++;
12075 }
12076
12077 return wuffs_base__make_empty_struct();
12078 }
12079
12080 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__image_decoder__set_report_metadata(wuffs_base__image_decoder * self,uint32_t a_fourcc,bool a_report)12081 wuffs_base__image_decoder__set_report_metadata(
12082 wuffs_base__image_decoder* self,
12083 uint32_t a_fourcc,
12084 bool a_report) {
12085 if (!self) {
12086 return wuffs_base__make_empty_struct();
12087 }
12088 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12089 return wuffs_base__make_empty_struct();
12090 }
12091
12092 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12093 int i;
12094 for (i = 0; i < 63; i++) {
12095 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12096 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12097 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12098 return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
12099 } else if (v->vtable_name == NULL) {
12100 break;
12101 }
12102 v++;
12103 }
12104
12105 return wuffs_base__make_empty_struct();
12106 }
12107
12108 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__image_decoder__tell_me_more(wuffs_base__image_decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)12109 wuffs_base__image_decoder__tell_me_more(
12110 wuffs_base__image_decoder* self,
12111 wuffs_base__io_buffer* a_dst,
12112 wuffs_base__more_information* a_minfo,
12113 wuffs_base__io_buffer* a_src) {
12114 if (!self) {
12115 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12116 }
12117 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12118 return wuffs_base__make_status(
12119 (self->private_impl.magic == WUFFS_BASE__DISABLED)
12120 ? wuffs_base__error__disabled_by_previous_error
12121 : wuffs_base__error__initialize_not_called);
12122 }
12123
12124 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12125 int i;
12126 for (i = 0; i < 63; i++) {
12127 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12128 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12129 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12130 return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
12131 } else if (v->vtable_name == NULL) {
12132 break;
12133 }
12134 v++;
12135 }
12136
12137 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12138 }
12139
12140 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__image_decoder__workbuf_len(const wuffs_base__image_decoder * self)12141 wuffs_base__image_decoder__workbuf_len(
12142 const wuffs_base__image_decoder* self) {
12143 if (!self) {
12144 return wuffs_base__utility__empty_range_ii_u64();
12145 }
12146 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12147 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12148 return wuffs_base__utility__empty_range_ii_u64();
12149 }
12150
12151 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12152 int i;
12153 for (i = 0; i < 63; i++) {
12154 if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
12155 const wuffs_base__image_decoder__func_ptrs* func_ptrs =
12156 (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
12157 return (*func_ptrs->workbuf_len)(self);
12158 } else if (v->vtable_name == NULL) {
12159 break;
12160 }
12161 v++;
12162 }
12163
12164 return wuffs_base__utility__empty_range_ii_u64();
12165 }
12166
12167 // --------
12168
12169 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__io_transformer__set_quirk_enabled(wuffs_base__io_transformer * self,uint32_t a_quirk,bool a_enabled)12170 wuffs_base__io_transformer__set_quirk_enabled(
12171 wuffs_base__io_transformer* self,
12172 uint32_t a_quirk,
12173 bool a_enabled) {
12174 if (!self) {
12175 return wuffs_base__make_empty_struct();
12176 }
12177 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12178 return wuffs_base__make_empty_struct();
12179 }
12180
12181 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12182 int i;
12183 for (i = 0; i < 63; i++) {
12184 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
12185 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
12186 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
12187 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
12188 } else if (v->vtable_name == NULL) {
12189 break;
12190 }
12191 v++;
12192 }
12193
12194 return wuffs_base__make_empty_struct();
12195 }
12196
12197 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__io_transformer__transform_io(wuffs_base__io_transformer * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)12198 wuffs_base__io_transformer__transform_io(
12199 wuffs_base__io_transformer* self,
12200 wuffs_base__io_buffer* a_dst,
12201 wuffs_base__io_buffer* a_src,
12202 wuffs_base__slice_u8 a_workbuf) {
12203 if (!self) {
12204 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12205 }
12206 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12207 return wuffs_base__make_status(
12208 (self->private_impl.magic == WUFFS_BASE__DISABLED)
12209 ? wuffs_base__error__disabled_by_previous_error
12210 : wuffs_base__error__initialize_not_called);
12211 }
12212
12213 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12214 int i;
12215 for (i = 0; i < 63; i++) {
12216 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
12217 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
12218 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
12219 return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
12220 } else if (v->vtable_name == NULL) {
12221 break;
12222 }
12223 v++;
12224 }
12225
12226 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12227 }
12228
12229 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__io_transformer__workbuf_len(const wuffs_base__io_transformer * self)12230 wuffs_base__io_transformer__workbuf_len(
12231 const wuffs_base__io_transformer* self) {
12232 if (!self) {
12233 return wuffs_base__utility__empty_range_ii_u64();
12234 }
12235 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12236 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12237 return wuffs_base__utility__empty_range_ii_u64();
12238 }
12239
12240 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12241 int i;
12242 for (i = 0; i < 63; i++) {
12243 if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
12244 const wuffs_base__io_transformer__func_ptrs* func_ptrs =
12245 (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
12246 return (*func_ptrs->workbuf_len)(self);
12247 } else if (v->vtable_name == NULL) {
12248 break;
12249 }
12250 v++;
12251 }
12252
12253 return wuffs_base__utility__empty_range_ii_u64();
12254 }
12255
12256 // --------
12257
12258 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_base__token_decoder__decode_tokens(wuffs_base__token_decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)12259 wuffs_base__token_decoder__decode_tokens(
12260 wuffs_base__token_decoder* self,
12261 wuffs_base__token_buffer* a_dst,
12262 wuffs_base__io_buffer* a_src,
12263 wuffs_base__slice_u8 a_workbuf) {
12264 if (!self) {
12265 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
12266 }
12267 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12268 return wuffs_base__make_status(
12269 (self->private_impl.magic == WUFFS_BASE__DISABLED)
12270 ? wuffs_base__error__disabled_by_previous_error
12271 : wuffs_base__error__initialize_not_called);
12272 }
12273
12274 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12275 int i;
12276 for (i = 0; i < 63; i++) {
12277 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
12278 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
12279 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
12280 return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
12281 } else if (v->vtable_name == NULL) {
12282 break;
12283 }
12284 v++;
12285 }
12286
12287 return wuffs_base__make_status(wuffs_base__error__bad_vtable);
12288 }
12289
12290 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_base__token_decoder__set_quirk_enabled(wuffs_base__token_decoder * self,uint32_t a_quirk,bool a_enabled)12291 wuffs_base__token_decoder__set_quirk_enabled(
12292 wuffs_base__token_decoder* self,
12293 uint32_t a_quirk,
12294 bool a_enabled) {
12295 if (!self) {
12296 return wuffs_base__make_empty_struct();
12297 }
12298 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
12299 return wuffs_base__make_empty_struct();
12300 }
12301
12302 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12303 int i;
12304 for (i = 0; i < 63; i++) {
12305 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
12306 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
12307 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
12308 return (*func_ptrs->set_quirk_enabled)(self, a_quirk, a_enabled);
12309 } else if (v->vtable_name == NULL) {
12310 break;
12311 }
12312 v++;
12313 }
12314
12315 return wuffs_base__make_empty_struct();
12316 }
12317
12318 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_base__token_decoder__workbuf_len(const wuffs_base__token_decoder * self)12319 wuffs_base__token_decoder__workbuf_len(
12320 const wuffs_base__token_decoder* self) {
12321 if (!self) {
12322 return wuffs_base__utility__empty_range_ii_u64();
12323 }
12324 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
12325 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
12326 return wuffs_base__utility__empty_range_ii_u64();
12327 }
12328
12329 const wuffs_base__vtable* v = &self->private_impl.first_vtable;
12330 int i;
12331 for (i = 0; i < 63; i++) {
12332 if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
12333 const wuffs_base__token_decoder__func_ptrs* func_ptrs =
12334 (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
12335 return (*func_ptrs->workbuf_len)(self);
12336 } else if (v->vtable_name == NULL) {
12337 break;
12338 }
12339 v++;
12340 }
12341
12342 return wuffs_base__utility__empty_range_ii_u64();
12343 }
12344
12345 #endif // !defined(WUFFS_CONFIG__MODULES) ||
12346 // defined(WUFFS_CONFIG__MODULE__BASE) ||
12347 // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
12348
12349 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
12350 defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
12351
12352 // ---------------- IEEE 754 Floating Point
12353
12354 // The etc__hpd_left_shift and etc__powers_of_5 tables were printed by
12355 // script/print-hpd-left-shift.go. That script has an optional -comments flag,
12356 // whose output is not copied here, which prints further detail.
12357 //
12358 // These tables are used in
12359 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits.
12360
12361 // wuffs_base__private_implementation__hpd_left_shift[i] encodes the number of
12362 // new digits created after multiplying a positive integer by (1 << i): the
12363 // additional length in the decimal representation. For example, shifting "234"
12364 // by 3 (equivalent to multiplying by 8) will produce "1872". Going from a
12365 // 3-length string to a 4-length string means that 1 new digit was added (and
12366 // existing digits may have changed).
12367 //
12368 // Shifting by i can add either N or N-1 new digits, depending on whether the
12369 // original positive integer compares >= or < to the i'th power of 5 (as 10
12370 // equals 2 * 5). Comparison is lexicographic, not numerical.
12371 //
12372 // For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new
12373 // digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625":
12374 // - ("1" << 4) is "16", which adds 1 new digit.
12375 // - ("5678" << 4) is "90848", which adds 1 new digit.
12376 // - ("624" << 4) is "9984", which adds 1 new digit.
12377 // - ("62498" << 4) is "999968", which adds 1 new digit.
12378 // - ("625" << 4) is "10000", which adds 2 new digits.
12379 // - ("625001" << 4) is "10000016", which adds 2 new digits.
12380 // - ("7008" << 4) is "112128", which adds 2 new digits.
12381 // - ("99" << 4) is "1584", which adds 2 new digits.
12382 //
12383 // Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift
12384 // array encodes this as:
12385 // - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006.
12386 // - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009.
12387 // where the ? isn't relevant for i == 4.
12388 //
12389 // The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two
12390 // possible number of new digits. The low 11 bits are an offset into the
12391 // etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i
12392 // is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9]
12393 // is the string "\x06\x02\x05", so the relevant power of 5 is "625".
12394 //
12395 // Thanks to Ken Thompson for the original idea.
12396 static const uint16_t wuffs_base__private_implementation__hpd_left_shift[65] = {
12397 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
12398 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
12399 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
12400 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
12401 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
12402 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
12403 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
12404 0x051C, 0x051C,
12405 };
12406
12407 // wuffs_base__private_implementation__powers_of_5 contains the powers of 5,
12408 // concatenated together: "5", "25", "125", "625", "3125", etc.
12409 static const uint8_t wuffs_base__private_implementation__powers_of_5[0x051C] = {
12410 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9,
12411 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2,
12412 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5,
12413 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8, 7, 8, 9, 0,
12414 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6, 9, 7, 2, 6, 5,
12415 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1,
12416 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4,
12417 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7,
12418 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0,
12419 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3,
12420 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1,
12421 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6,
12422 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5,
12423 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0,
12424 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6,
12425 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8,
12426 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7,
12427 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6,
12428 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8,
12429 0, 6, 6, 4, 0, 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9,
12430 0, 3, 3, 2, 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2,
12431 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8,
12432 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7,
12433 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5,
12434 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3,
12435 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2,
12436 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9,
12437 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8, 0, 1, 4, 8,
12438 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4,
12439 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0,
12440 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5,
12441 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1,
12442 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5,
12443 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3,
12444 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4,
12445 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3,
12446 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8,
12447 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2,
12448 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6,
12449 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2,
12450 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2,
12451 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5,
12452 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5,
12453 6, 2, 8, 9, 1, 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8,
12454 1, 2, 5, 1, 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9,
12455 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3,
12456 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6,
12457 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1,
12458 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1,
12459 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4,
12460 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7,
12461 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3,
12462 6, 9, 1, 4, 0, 6, 2, 5,
12463 };
12464
12465 // --------
12466
12467 // wuffs_base__private_implementation__powers_of_10 contains truncated
12468 // approximations to the powers of 10, ranging from 1e-307 to 1e+288 inclusive,
12469 // as 596 pairs of uint64_t values (a 128-bit mantissa).
12470 //
12471 // There's also an implicit third column (implied by a linear formula involving
12472 // the base-10 exponent) that is the base-2 exponent, biased by a magic
12473 // constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias
12474 // for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and
12475 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire works with
12476 // multiples-of-64-bit mantissas.
12477 //
12478 // For example, the third row holds the approximation to 1e-305:
12479 // 0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE))
12480 //
12481 // Similarly, 1e+4 is approximated by:
12482 // 0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE))
12483 //
12484 // Similarly, 1e+68 is approximated by:
12485 // 0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE))
12486 //
12487 // This table was generated by by script/print-mpb-powers-of-10.go
12488 static const uint64_t wuffs_base__private_implementation__powers_of_10[596][2] =
12489 {
12490 {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB}, // 1e-307
12491 {0x8F48A4899877186C, 0xB3C4F1BA87BC8696}, // 1e-306
12492 {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C}, // 1e-305
12493 {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925}, // 1e-304
12494 {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F}, // 1e-303
12495 {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A}, // 1e-302
12496 {0xBE311C083A225CD2, 0x892731AC9FAF056E}, // 1e-301
12497 {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA}, // 1e-300
12498 {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D}, // 1e-299
12499 {0x25BBF56008C58EA5, 0x85F0468293F0EB4E}, // 1e-298
12500 {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621}, // 1e-297
12501 {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA}, // 1e-296
12502 {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA}, // 1e-295
12503 {0xE50FF107BAB528A0, 0xA37FCE126597973C}, // 1e-294
12504 {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C}, // 1e-293
12505 {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F}, // 1e-292
12506 {0x77B191618C54E9AC, 0x9FAACF3DF73609B1}, // 1e-291
12507 {0xD59DF5B9EF6A2417, 0xC795830D75038C1D}, // 1e-290
12508 {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25}, // 1e-289
12509 {0x4EE367F9430AEC32, 0x9BECCE62836AC577}, // 1e-288
12510 {0x229C41F793CDA73F, 0xC2E801FB244576D5}, // 1e-287
12511 {0x6B43527578C1110F, 0xF3A20279ED56D48A}, // 1e-286
12512 {0x830A13896B78AAA9, 0x9845418C345644D6}, // 1e-285
12513 {0x23CC986BC656D553, 0xBE5691EF416BD60C}, // 1e-284
12514 {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F}, // 1e-283
12515 {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39}, // 1e-282
12516 {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07}, // 1e-281
12517 {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9}, // 1e-280
12518 {0x23100809B9C21FA1, 0x91376C36D99995BE}, // 1e-279
12519 {0xABD40A0C2832A78A, 0xB58547448FFFFB2D}, // 1e-278
12520 {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9}, // 1e-277
12521 {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B}, // 1e-276
12522 {0x99CD11CFDF41779C, 0xB1442798F49FFB4A}, // 1e-275
12523 {0x40405643D711D583, 0xDD95317F31C7FA1D}, // 1e-274
12524 {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52}, // 1e-273
12525 {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66}, // 1e-272
12526 {0x90BED43E40076A82, 0xD863B256369D4A40}, // 1e-271
12527 {0x5A7744A6E804A291, 0x873E4F75E2224E68}, // 1e-270
12528 {0x711515D0A205CB36, 0xA90DE3535AAAE202}, // 1e-269
12529 {0x0D5A5B44CA873E03, 0xD3515C2831559A83}, // 1e-268
12530 {0xE858790AFE9486C2, 0x8412D9991ED58091}, // 1e-267
12531 {0x626E974DBE39A872, 0xA5178FFF668AE0B6}, // 1e-266
12532 {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3}, // 1e-265
12533 {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E}, // 1e-264
12534 {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72}, // 1e-263
12535 {0xA327FFB266B56220, 0xC987434744AC874E}, // 1e-262
12536 {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922}, // 1e-261
12537 {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5}, // 1e-260
12538 {0xCB550FB4384D21D3, 0xC4CE17B399107C22}, // 1e-259
12539 {0x7E2A53A146606A48, 0xF6019DA07F549B2B}, // 1e-258
12540 {0x2EDA7444CBFC426D, 0x99C102844F94E0FB}, // 1e-257
12541 {0xFA911155FEFB5308, 0xC0314325637A1939}, // 1e-256
12542 {0x793555AB7EBA27CA, 0xF03D93EEBC589F88}, // 1e-255
12543 {0x4BC1558B2F3458DE, 0x96267C7535B763B5}, // 1e-254
12544 {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2}, // 1e-253
12545 {0x465E15A979C1CADC, 0xEA9C227723EE8BCB}, // 1e-252
12546 {0x0BFACD89EC191EC9, 0x92A1958A7675175F}, // 1e-251
12547 {0xCEF980EC671F667B, 0xB749FAED14125D36}, // 1e-250
12548 {0x82B7E12780E7401A, 0xE51C79A85916F484}, // 1e-249
12549 {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2}, // 1e-248
12550 {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07}, // 1e-247
12551 {0x67A791E093E1D49A, 0xDFBDCECE67006AC9}, // 1e-246
12552 {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD}, // 1e-245
12553 {0x58FAE9F773886E18, 0xAECC49914078536D}, // 1e-244
12554 {0xAF39A475506A899E, 0xDA7F5BF590966848}, // 1e-243
12555 {0x6D8406C952429603, 0x888F99797A5E012D}, // 1e-242
12556 {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178}, // 1e-241
12557 {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6}, // 1e-240
12558 {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26}, // 1e-239
12559 {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F}, // 1e-238
12560 {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B}, // 1e-237
12561 {0x76C53D08D6B70858, 0x823C12795DB6CE57}, // 1e-236
12562 {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED}, // 1e-235
12563 {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268}, // 1e-234
12564 {0xD3F93B35435D7C4C, 0xFE5D54150B090B02}, // 1e-233
12565 {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1}, // 1e-232
12566 {0x359AB6419CA1091B, 0xC6B8E9B0709F109A}, // 1e-231
12567 {0xC30163D203C94B62, 0xF867241C8CC6D4C0}, // 1e-230
12568 {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8}, // 1e-229
12569 {0x985915FC12F542E4, 0xC21094364DFB5636}, // 1e-228
12570 {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4}, // 1e-227
12571 {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A}, // 1e-226
12572 {0x50C6FF782A838353, 0xBD8430BD08277231}, // 1e-225
12573 {0xA4F8BF5635246428, 0xECE53CEC4A314EBD}, // 1e-224
12574 {0x871B7795E136BE99, 0x940F4613AE5ED136}, // 1e-223
12575 {0x28E2557B59846E3F, 0xB913179899F68584}, // 1e-222
12576 {0x331AEADA2FE589CF, 0xE757DD7EC07426E5}, // 1e-221
12577 {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F}, // 1e-220
12578 {0x0FED077A756B53A9, 0xB4BCA50B065ABE63}, // 1e-219
12579 {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB}, // 1e-218
12580 {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD}, // 1e-217
12581 {0xBD8D794D96AACFB3, 0xB080392CC4349DEC}, // 1e-216
12582 {0xECF0D7A0FC5583A0, 0xDCA04777F541C567}, // 1e-215
12583 {0xF41686C49DB57244, 0x89E42CAAF9491B60}, // 1e-214
12584 {0x311C2875C522CED5, 0xAC5D37D5B79B6239}, // 1e-213
12585 {0x7D633293366B828B, 0xD77485CB25823AC7}, // 1e-212
12586 {0xAE5DFF9C02033197, 0x86A8D39EF77164BC}, // 1e-211
12587 {0xD9F57F830283FDFC, 0xA8530886B54DBDEB}, // 1e-210
12588 {0xD072DF63C324FD7B, 0xD267CAA862A12D66}, // 1e-209
12589 {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60}, // 1e-208
12590 {0x52D9BE85F074E608, 0xA46116538D0DEB78}, // 1e-207
12591 {0x67902E276C921F8B, 0xCD795BE870516656}, // 1e-206
12592 {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6}, // 1e-205
12593 {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3}, // 1e-204
12594 {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0}, // 1e-203
12595 {0x796B805720085F81, 0xFAD2A4B13D1B5D6C}, // 1e-202
12596 {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63}, // 1e-201
12597 {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC}, // 1e-200
12598 {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B}, // 1e-199
12599 {0x751BDD152D4D1C4A, 0x991711052D8BF3C5}, // 1e-198
12600 {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6}, // 1e-197
12601 {0x86FB897116C87C34, 0xEF340A98172AACE4}, // 1e-196
12602 {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E}, // 1e-195
12603 {0x8974836059CCA109, 0xBAE0A846D2195712}, // 1e-194
12604 {0x2BD1A438703FC94B, 0xE998D258869FACD7}, // 1e-193
12605 {0x7B6306A34627DDCF, 0x91FF83775423CC06}, // 1e-192
12606 {0x1A3BC84C17B1D542, 0xB67F6455292CBF08}, // 1e-191
12607 {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA}, // 1e-190
12608 {0x547EB47B7282EE9C, 0x8E938662882AF53E}, // 1e-189
12609 {0xE99E619A4F23AA43, 0xB23867FB2A35B28D}, // 1e-188
12610 {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31}, // 1e-187
12611 {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E}, // 1e-186
12612 {0x9624AB50B148D445, 0xAE0B158B4738705E}, // 1e-185
12613 {0x3BADD624DD9B0957, 0xD98DDAEE19068C76}, // 1e-184
12614 {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9}, // 1e-183
12615 {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC}, // 1e-182
12616 {0x7647C3200069671F, 0xD47487CC8470652B}, // 1e-181
12617 {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B}, // 1e-180
12618 {0xF468107100525890, 0xA5FB0A17C777CF09}, // 1e-179
12619 {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC}, // 1e-178
12620 {0xC6F14CD848405530, 0x81AC1FE293D599BF}, // 1e-177
12621 {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F}, // 1e-176
12622 {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B}, // 1e-175
12623 {0x908F4A166D1DA663, 0xFD442E4688BD304A}, // 1e-174
12624 {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E}, // 1e-173
12625 {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA}, // 1e-172
12626 {0xD12BEE59E68EF47C, 0xF7549530E188C128}, // 1e-171
12627 {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9}, // 1e-170
12628 {0xE36A52363C1FAF01, 0xC13A148E3032D6E7}, // 1e-169
12629 {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1}, // 1e-168
12630 {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5}, // 1e-167
12631 {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE}, // 1e-166
12632 {0x111B495B3464AD21, 0xEBDF661791D60F56}, // 1e-165
12633 {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995}, // 1e-164
12634 {0x3D5D514F40EEA742, 0xB84687C269EF3BFB}, // 1e-163
12635 {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA}, // 1e-162
12636 {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC}, // 1e-161
12637 {0x59ED216765690F56, 0xB3F4E093DB73A093}, // 1e-160
12638 {0x306869C13EC3532C, 0xE0F218B8D25088B8}, // 1e-159
12639 {0x1E414218C73A13FB, 0x8C974F7383725573}, // 1e-158
12640 {0xE5D1929EF90898FA, 0xAFBD2350644EEACF}, // 1e-157
12641 {0xDF45F746B74ABF39, 0xDBAC6C247D62A583}, // 1e-156
12642 {0x6B8BBA8C328EB783, 0x894BC396CE5DA772}, // 1e-155
12643 {0x066EA92F3F326564, 0xAB9EB47C81F5114F}, // 1e-154
12644 {0xC80A537B0EFEFEBD, 0xD686619BA27255A2}, // 1e-153
12645 {0xBD06742CE95F5F36, 0x8613FD0145877585}, // 1e-152
12646 {0x2C48113823B73704, 0xA798FC4196E952E7}, // 1e-151
12647 {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0}, // 1e-150
12648 {0x9A984D73DBE722FB, 0x82EF85133DE648C4}, // 1e-149
12649 {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5}, // 1e-148
12650 {0x318DF905079926A8, 0xCC963FEE10B7D1B3}, // 1e-147
12651 {0xFDF17746497F7052, 0xFFBBCFE994E5C61F}, // 1e-146
12652 {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3}, // 1e-145
12653 {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8}, // 1e-144
12654 {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B}, // 1e-143
12655 {0x06BEA10CA65C084E, 0x9C1661A651213E2D}, // 1e-142
12656 {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8}, // 1e-141
12657 {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126}, // 1e-140
12658 {0xF89629465A75E01C, 0x986DDB5C6B3A76B7}, // 1e-139
12659 {0xF6BBB397F1135823, 0xBE89523386091465}, // 1e-138
12660 {0x746AA07DED582E2C, 0xEE2BA6C0678B597F}, // 1e-137
12661 {0xA8C2A44EB4571CDC, 0x94DB483840B717EF}, // 1e-136
12662 {0x92F34D62616CE413, 0xBA121A4650E4DDEB}, // 1e-135
12663 {0x77B020BAF9C81D17, 0xE896A0D7E51E1566}, // 1e-134
12664 {0x0ACE1474DC1D122E, 0x915E2486EF32CD60}, // 1e-133
12665 {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8}, // 1e-132
12666 {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6}, // 1e-131
12667 {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F}, // 1e-130
12668 {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3}, // 1e-129
12669 {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0}, // 1e-128
12670 {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4}, // 1e-127
12671 {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D}, // 1e-126
12672 {0xE871C7BF077BA8B7, 0xD89D64D57A607744}, // 1e-125
12673 {0x11471CD764AD4972, 0x87625F056C7C4A8B}, // 1e-124
12674 {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D}, // 1e-123
12675 {0x4AFF1D108D4EC2C3, 0xD389B47879823479}, // 1e-122
12676 {0xCEDF722A585139BA, 0x843610CB4BF160CB}, // 1e-121
12677 {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE}, // 1e-120
12678 {0x733D226229FEEA32, 0xCE947A3DA6A9273E}, // 1e-119
12679 {0x0806357D5A3F525F, 0x811CCC668829B887}, // 1e-118
12680 {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8}, // 1e-117
12681 {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052}, // 1e-116
12682 {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67}, // 1e-115
12683 {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0}, // 1e-114
12684 {0x0A9E795E65D4DF11, 0xC5029163F384A931}, // 1e-113
12685 {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D}, // 1e-112
12686 {0x504BCED1BF8E4E45, 0x99EA0196163FA42E}, // 1e-111
12687 {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39}, // 1e-110
12688 {0x5D767327BB4E5A4C, 0xF07DA27A82C37088}, // 1e-109
12689 {0x3A6A07F8D510F86F, 0x964E858C91BA2655}, // 1e-108
12690 {0x890489F70A55368B, 0xBBE226EFB628AFEA}, // 1e-107
12691 {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5}, // 1e-106
12692 {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F}, // 1e-105
12693 {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB}, // 1e-104
12694 {0xCC420A6A101D0515, 0xE55990879DDCAABD}, // 1e-103
12695 {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6}, // 1e-102
12696 {0x47939822DC96ABF9, 0xB32DF8E9F3546564}, // 1e-101
12697 {0x59787E2B93BC56F7, 0xDFF9772470297EBD}, // 1e-100
12698 {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36}, // 1e-99
12699 {0xEDE622920B6B23F1, 0xAEFAE51477A06B03}, // 1e-98
12700 {0xE95FAB368E45ECED, 0xDAB99E59958885C4}, // 1e-97
12701 {0x11DBCB0218EBB414, 0x88B402F7FD75539B}, // 1e-96
12702 {0xD652BDC29F26A119, 0xAAE103B5FCD2A881}, // 1e-95
12703 {0x4BE76D3346F0495F, 0xD59944A37C0752A2}, // 1e-94
12704 {0x6F70A4400C562DDB, 0x857FCAE62D8493A5}, // 1e-93
12705 {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E}, // 1e-92
12706 {0x7E2000A41346A7A7, 0xD097AD07A71F26B2}, // 1e-91
12707 {0x8ED400668C0C28C8, 0x825ECC24C873782F}, // 1e-90
12708 {0x728900802F0F32FA, 0xA2F67F2DFA90563B}, // 1e-89
12709 {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA}, // 1e-88
12710 {0xE2F610C84987BFA8, 0xFEA126B7D78186BC}, // 1e-87
12711 {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436}, // 1e-86
12712 {0x91503D1C79720DBB, 0xC6EDE63FA05D3143}, // 1e-85
12713 {0x75A44C6397CE912A, 0xF8A95FCF88747D94}, // 1e-84
12714 {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C}, // 1e-83
12715 {0xFBE85BADCE996168, 0xC24452DA229B021B}, // 1e-82
12716 {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2}, // 1e-81
12717 {0xDCCD879FC967D41A, 0x97C560BA6B0919A5}, // 1e-80
12718 {0x5400E987BBC1C920, 0xBDB6B8E905CB600F}, // 1e-79
12719 {0x290123E9AAB23B68, 0xED246723473E3813}, // 1e-78
12720 {0xF9A0B6720AAF6521, 0x9436C0760C86E30B}, // 1e-77
12721 {0xF808E40E8D5B3E69, 0xB94470938FA89BCE}, // 1e-76
12722 {0xB60B1D1230B20E04, 0xE7958CB87392C2C2}, // 1e-75
12723 {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9}, // 1e-74
12724 {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828}, // 1e-73
12725 {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232}, // 1e-72
12726 {0x579C487E5A38AD0E, 0x8D590723948A535F}, // 1e-71
12727 {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837}, // 1e-70
12728 {0xF8E431456CF88E65, 0xDCDB1B2798182244}, // 1e-69
12729 {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B}, // 1e-68
12730 {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5}, // 1e-67
12731 {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177}, // 1e-66
12732 {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA}, // 1e-65
12733 {0x3F2398D747B36224, 0xA87FEA27A539E9A5}, // 1e-64
12734 {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E}, // 1e-63
12735 {0x1953CF68300424AC, 0x83A3EEEEF9153E89}, // 1e-62
12736 {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B}, // 1e-61
12737 {0x3792F412CB06794D, 0xCDB02555653131B6}, // 1e-60
12738 {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11}, // 1e-59
12739 {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6}, // 1e-58
12740 {0xF245825A5A445275, 0xC8DE047564D20A8B}, // 1e-57
12741 {0xEED6E2F0F0D56712, 0xFB158592BE068D2E}, // 1e-56
12742 {0x55464DD69685606B, 0x9CED737BB6C4183D}, // 1e-55
12743 {0xAA97E14C3C26B886, 0xC428D05AA4751E4C}, // 1e-54
12744 {0xD53DD99F4B3066A8, 0xF53304714D9265DF}, // 1e-53
12745 {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB}, // 1e-52
12746 {0xDE98520472BDD033, 0xBF8FDB78849A5F96}, // 1e-51
12747 {0x963E66858F6D4440, 0xEF73D256A5C0F77C}, // 1e-50
12748 {0xDDE7001379A44AA8, 0x95A8637627989AAD}, // 1e-49
12749 {0x5560C018580D5D52, 0xBB127C53B17EC159}, // 1e-48
12750 {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF}, // 1e-47
12751 {0xCAB3961304CA70E8, 0x9226712162AB070D}, // 1e-46
12752 {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1}, // 1e-45
12753 {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05}, // 1e-44
12754 {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3}, // 1e-43
12755 {0x55F038B237591ED3, 0xB267ED1940F1C61C}, // 1e-42
12756 {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3}, // 1e-41
12757 {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6}, // 1e-40
12758 {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77}, // 1e-39
12759 {0x96E7BD358C904A21, 0xD9C7DCED53C72255}, // 1e-38
12760 {0x7E50D64177DA2E54, 0x881CEA14545C7575}, // 1e-37
12761 {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2}, // 1e-36
12762 {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787}, // 1e-35
12763 {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4}, // 1e-34
12764 {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61}, // 1e-33
12765 {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA}, // 1e-32
12766 {0x80EACF948770CED7, 0x81CEB32C4B43FCF4}, // 1e-31
12767 {0xA1258379A94D028D, 0xA2425FF75E14FC31}, // 1e-30
12768 {0x096EE45813A04330, 0xCAD2F7F5359A3B3E}, // 1e-29
12769 {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D}, // 1e-28
12770 {0x775EA264CF55347D, 0x9E74D1B791E07E48}, // 1e-27
12771 {0x95364AFE032A819D, 0xC612062576589DDA}, // 1e-26
12772 {0x3A83DDBD83F52204, 0xF79687AED3EEC551}, // 1e-25
12773 {0xC4926A9672793542, 0x9ABE14CD44753B52}, // 1e-24
12774 {0x75B7053C0F178293, 0xC16D9A0095928A27}, // 1e-23
12775 {0x5324C68B12DD6338, 0xF1C90080BAF72CB1}, // 1e-22
12776 {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE}, // 1e-21
12777 {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA}, // 1e-20
12778 {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5}, // 1e-19
12779 {0x3AFF322E62439FCF, 0x9392EE8E921D5D07}, // 1e-18
12780 {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449}, // 1e-17
12781 {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B}, // 1e-16
12782 {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9}, // 1e-15
12783 {0x538484C19EF38C94, 0xB424DC35095CD80F}, // 1e-14
12784 {0x2865A5F206B06FB9, 0xE12E13424BB40E13}, // 1e-13
12785 {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB}, // 1e-12
12786 {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE}, // 1e-11
12787 {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE}, // 1e-10
12788 {0x31680A88F8953030, 0x89705F4136B4A597}, // 1e-9
12789 {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC}, // 1e-8
12790 {0x3D32907604691B4C, 0xD6BF94D5E57A42BC}, // 1e-7
12791 {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5}, // 1e-6
12792 {0x0FCF80DC33721D53, 0xA7C5AC471B478423}, // 1e-5
12793 {0xD3C36113404EA4A8, 0xD1B71758E219652B}, // 1e-4
12794 {0x645A1CAC083126E9, 0x83126E978D4FDF3B}, // 1e-3
12795 {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A}, // 1e-2
12796 {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC}, // 1e-1
12797 {0x0000000000000000, 0x8000000000000000}, // 1e0
12798 {0x0000000000000000, 0xA000000000000000}, // 1e1
12799 {0x0000000000000000, 0xC800000000000000}, // 1e2
12800 {0x0000000000000000, 0xFA00000000000000}, // 1e3
12801 {0x0000000000000000, 0x9C40000000000000}, // 1e4
12802 {0x0000000000000000, 0xC350000000000000}, // 1e5
12803 {0x0000000000000000, 0xF424000000000000}, // 1e6
12804 {0x0000000000000000, 0x9896800000000000}, // 1e7
12805 {0x0000000000000000, 0xBEBC200000000000}, // 1e8
12806 {0x0000000000000000, 0xEE6B280000000000}, // 1e9
12807 {0x0000000000000000, 0x9502F90000000000}, // 1e10
12808 {0x0000000000000000, 0xBA43B74000000000}, // 1e11
12809 {0x0000000000000000, 0xE8D4A51000000000}, // 1e12
12810 {0x0000000000000000, 0x9184E72A00000000}, // 1e13
12811 {0x0000000000000000, 0xB5E620F480000000}, // 1e14
12812 {0x0000000000000000, 0xE35FA931A0000000}, // 1e15
12813 {0x0000000000000000, 0x8E1BC9BF04000000}, // 1e16
12814 {0x0000000000000000, 0xB1A2BC2EC5000000}, // 1e17
12815 {0x0000000000000000, 0xDE0B6B3A76400000}, // 1e18
12816 {0x0000000000000000, 0x8AC7230489E80000}, // 1e19
12817 {0x0000000000000000, 0xAD78EBC5AC620000}, // 1e20
12818 {0x0000000000000000, 0xD8D726B7177A8000}, // 1e21
12819 {0x0000000000000000, 0x878678326EAC9000}, // 1e22
12820 {0x0000000000000000, 0xA968163F0A57B400}, // 1e23
12821 {0x0000000000000000, 0xD3C21BCECCEDA100}, // 1e24
12822 {0x0000000000000000, 0x84595161401484A0}, // 1e25
12823 {0x0000000000000000, 0xA56FA5B99019A5C8}, // 1e26
12824 {0x0000000000000000, 0xCECB8F27F4200F3A}, // 1e27
12825 {0x4000000000000000, 0x813F3978F8940984}, // 1e28
12826 {0x5000000000000000, 0xA18F07D736B90BE5}, // 1e29
12827 {0xA400000000000000, 0xC9F2C9CD04674EDE}, // 1e30
12828 {0x4D00000000000000, 0xFC6F7C4045812296}, // 1e31
12829 {0xF020000000000000, 0x9DC5ADA82B70B59D}, // 1e32
12830 {0x6C28000000000000, 0xC5371912364CE305}, // 1e33
12831 {0xC732000000000000, 0xF684DF56C3E01BC6}, // 1e34
12832 {0x3C7F400000000000, 0x9A130B963A6C115C}, // 1e35
12833 {0x4B9F100000000000, 0xC097CE7BC90715B3}, // 1e36
12834 {0x1E86D40000000000, 0xF0BDC21ABB48DB20}, // 1e37
12835 {0x1314448000000000, 0x96769950B50D88F4}, // 1e38
12836 {0x17D955A000000000, 0xBC143FA4E250EB31}, // 1e39
12837 {0x5DCFAB0800000000, 0xEB194F8E1AE525FD}, // 1e40
12838 {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE}, // 1e41
12839 {0xF14A3D9E40000000, 0xB7ABC627050305AD}, // 1e42
12840 {0x6D9CCD05D0000000, 0xE596B7B0C643C719}, // 1e43
12841 {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F}, // 1e44
12842 {0xDDA2802C8A800000, 0xB35DBF821AE4F38B}, // 1e45
12843 {0xD50B2037AD200000, 0xE0352F62A19E306E}, // 1e46
12844 {0x4526F422CC340000, 0x8C213D9DA502DE45}, // 1e47
12845 {0x9670B12B7F410000, 0xAF298D050E4395D6}, // 1e48
12846 {0x3C0CDD765F114000, 0xDAF3F04651D47B4C}, // 1e49
12847 {0xA5880A69FB6AC800, 0x88D8762BF324CD0F}, // 1e50
12848 {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053}, // 1e51
12849 {0x72A4904598D6D880, 0xD5D238A4ABE98068}, // 1e52
12850 {0x47A6DA2B7F864750, 0x85A36366EB71F041}, // 1e53
12851 {0x999090B65F67D924, 0xA70C3C40A64E6C51}, // 1e54
12852 {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765}, // 1e55
12853 {0xBFF8F10E7A8921A4, 0x82818F1281ED449F}, // 1e56
12854 {0xAFF72D52192B6A0D, 0xA321F2D7226895C7}, // 1e57
12855 {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39}, // 1e58
12856 {0x02F236D04753D5B4, 0xFEE50B7025C36A08}, // 1e59
12857 {0x01D762422C946590, 0x9F4F2726179A2245}, // 1e60
12858 {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6}, // 1e61
12859 {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B}, // 1e62
12860 {0x63CC55F49F88EB2F, 0x9B934C3B330C8577}, // 1e63
12861 {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5}, // 1e64
12862 {0x8BEF464E3945EF7A, 0xF316271C7FC3908A}, // 1e65
12863 {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56}, // 1e66
12864 {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC}, // 1e67
12865 {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27}, // 1e68
12866 {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8}, // 1e69
12867 {0xB3E2FD538E122B44, 0xB975D6B6EE39E436}, // 1e70
12868 {0x60DBBCA87196B616, 0xE7D34C64A9C85D44}, // 1e71
12869 {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A}, // 1e72
12870 {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD}, // 1e73
12871 {0xC696963C7EED2DD1, 0xE264589A4DCDAB14}, // 1e74
12872 {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC}, // 1e75
12873 {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8}, // 1e76
12874 {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912}, // 1e77
12875 {0x6E3569326C784337, 0x8A2DBF142DFCC7AB}, // 1e78
12876 {0x49C2C37F07965404, 0xACB92ED9397BF996}, // 1e79
12877 {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB}, // 1e80
12878 {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD}, // 1e81
12879 {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC}, // 1e82
12880 {0xF50A3FA490C30190, 0xD2D80DB02AABD62B}, // 1e83
12881 {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB}, // 1e84
12882 {0x577001B891185938, 0xA4B8CAB1A1563F52}, // 1e85
12883 {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26}, // 1e86
12884 {0x544F8158315B05B4, 0x80B05E5AC60B6178}, // 1e87
12885 {0x696361AE3DB1C721, 0xA0DC75F1778E39D6}, // 1e88
12886 {0x03BC3A19CD1E38E9, 0xC913936DD571C84C}, // 1e89
12887 {0x04AB48A04065C723, 0xFB5878494ACE3A5F}, // 1e90
12888 {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B}, // 1e91
12889 {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A}, // 1e92
12890 {0xCA8F44EC7EE36479, 0xF5746577930D6500}, // 1e93
12891 {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20}, // 1e94
12892 {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8}, // 1e95
12893 {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2}, // 1e96
12894 {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5}, // 1e97
12895 {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F}, // 1e98
12896 {0xF52D09D71A3293BD, 0xEA1575143CF97226}, // 1e99
12897 {0x593C2626705F9C56, 0x924D692CA61BE758}, // 1e100
12898 {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E}, // 1e101
12899 {0x0B6DFB9C0F956447, 0xE498F455C38B997A}, // 1e102
12900 {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC}, // 1e103
12901 {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7}, // 1e104
12902 {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1}, // 1e105
12903 {0xBD79E0D20082EE74, 0x8B865B215899F46C}, // 1e106
12904 {0xECD8590680A3AA11, 0xAE67F1E9AEC07187}, // 1e107
12905 {0xE80E6F4820CC9495, 0xDA01EE641A708DE9}, // 1e108
12906 {0x3109058D147FDCDD, 0x884134FE908658B2}, // 1e109
12907 {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE}, // 1e110
12908 {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96}, // 1e111
12909 {0x03E2CF6BC604DDB0, 0x850FADC09923329E}, // 1e112
12910 {0x84DB8346B786151C, 0xA6539930BF6BFF45}, // 1e113
12911 {0xE612641865679A63, 0xCFE87F7CEF46FF16}, // 1e114
12912 {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E}, // 1e115
12913 {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749}, // 1e116
12914 {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C}, // 1e117
12915 {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63}, // 1e118
12916 {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E}, // 1e119
12917 {0xB281E1FD541501B8, 0xC646D63501A1511D}, // 1e120
12918 {0x1F225A7CA91A4226, 0xF7D88BC24209A565}, // 1e121
12919 {0x3375788DE9B06958, 0x9AE757596946075F}, // 1e122
12920 {0x0052D6B1641C83AE, 0xC1A12D2FC3978937}, // 1e123
12921 {0xC0678C5DBD23A49A, 0xF209787BB47D6B84}, // 1e124
12922 {0xF840B7BA963646E0, 0x9745EB4D50CE6332}, // 1e125
12923 {0xB650E5A93BC3D898, 0xBD176620A501FBFF}, // 1e126
12924 {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF}, // 1e127
12925 {0xC66F336C36B10137, 0x93BA47C980E98CDF}, // 1e128
12926 {0xB80B0047445D4184, 0xB8A8D9BBE123F017}, // 1e129
12927 {0xA60DC059157491E5, 0xE6D3102AD96CEC1D}, // 1e130
12928 {0x87C89837AD68DB2F, 0x9043EA1AC7E41392}, // 1e131
12929 {0x29BABE4598C311FB, 0xB454E4A179DD1877}, // 1e132
12930 {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94}, // 1e133
12931 {0x1899E4A65F58660C, 0x8CE2529E2734BB1D}, // 1e134
12932 {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4}, // 1e135
12933 {0x76707543F4FA1F73, 0xDC21A1171D42645D}, // 1e136
12934 {0x6A06494A791C53A8, 0x899504AE72497EBA}, // 1e137
12935 {0x0487DB9D17636892, 0xABFA45DA0EDBDE69}, // 1e138
12936 {0x45A9D2845D3C42B6, 0xD6F8D7509292D603}, // 1e139
12937 {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2}, // 1e140
12938 {0x8E6CAC7768D7141E, 0xA7F26836F282B732}, // 1e141
12939 {0x3207D795430CD926, 0xD1EF0244AF2364FF}, // 1e142
12940 {0x7F44E6BD49E807B8, 0x8335616AED761F1F}, // 1e143
12941 {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7}, // 1e144
12942 {0x36DBA887C37A8C0F, 0xCD036837130890A1}, // 1e145
12943 {0xC2494954DA2C9789, 0x802221226BE55A64}, // 1e146
12944 {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD}, // 1e147
12945 {0x6F92829494E5ACC7, 0xC83553C5C8965D3D}, // 1e148
12946 {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C}, // 1e149
12947 {0xFF2A760414536EFB, 0x9C69A97284B578D7}, // 1e150
12948 {0xFEF5138519684ABA, 0xC38413CF25E2D70D}, // 1e151
12949 {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1}, // 1e152
12950 {0xEF2F773FFBD97A61, 0x98BF2F79D5993802}, // 1e153
12951 {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603}, // 1e154
12952 {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784}, // 1e155
12953 {0xDD945A747BF26183, 0x952AB45CFA97A0B2}, // 1e156
12954 {0x94F971119AEEF9E4, 0xBA756174393D88DF}, // 1e157
12955 {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17}, // 1e158
12956 {0xAC62E055C10AB33A, 0x91ABB422CCB812EE}, // 1e159
12957 {0x577B986B314D6009, 0xB616A12B7FE617AA}, // 1e160
12958 {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94}, // 1e161
12959 {0x14588F13BE847307, 0x8E41ADE9FBEBC27D}, // 1e162
12960 {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C}, // 1e163
12961 {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3}, // 1e164
12962 {0x25DE7BB9480D5854, 0x8AEC23D680043BEE}, // 1e165
12963 {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9}, // 1e166
12964 {0x1B2BA1518094DA04, 0xD910F7FF28069DA4}, // 1e167
12965 {0x90FB44D2F05D0842, 0x87AA9AFF79042286}, // 1e168
12966 {0x353A1607AC744A53, 0xA99541BF57452B28}, // 1e169
12967 {0x42889B8997915CE8, 0xD3FA922F2D1675F2}, // 1e170
12968 {0x69956135FEBADA11, 0x847C9B5D7C2E09B7}, // 1e171
12969 {0x43FAB9837E699095, 0xA59BC234DB398C25}, // 1e172
12970 {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E}, // 1e173
12971 {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D}, // 1e174
12972 {0x6462D92A69731732, 0xA1BA1BA79E1632DC}, // 1e175
12973 {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93}, // 1e176
12974 {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78}, // 1e177
12975 {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB}, // 1e178
12976 {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916}, // 1e179
12977 {0x8AAD549E57273D45, 0xF6C69A72A3989F5B}, // 1e180
12978 {0x36AC54E2F678864B, 0x9A3C2087A63F6399}, // 1e181
12979 {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F}, // 1e182
12980 {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F}, // 1e183
12981 {0x9F644AE5A4B1B325, 0x969EB7C47859E743}, // 1e184
12982 {0x873D5D9F0DDE1FEE, 0xBC4665B596706114}, // 1e185
12983 {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959}, // 1e186
12984 {0x09A7F12442D588F2, 0x9316FF75DD87CBD8}, // 1e187
12985 {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE}, // 1e188
12986 {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81}, // 1e189
12987 {0xF96E017D694487BC, 0x8FA475791A569D10}, // 1e190
12988 {0x37C981DCC395A9AC, 0xB38D92D760EC4455}, // 1e191
12989 {0x85BBE253F47B1417, 0xE070F78D3927556A}, // 1e192
12990 {0x93956D7478CCEC8E, 0x8C469AB843B89562}, // 1e193
12991 {0x387AC8D1970027B2, 0xAF58416654A6BABB}, // 1e194
12992 {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A}, // 1e195
12993 {0x441FECE3BDF81F03, 0x88FCF317F22241E2}, // 1e196
12994 {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A}, // 1e197
12995 {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1}, // 1e198
12996 {0xF6872D5667844E49, 0x85C7056562757456}, // 1e199
12997 {0xB428F8AC016561DB, 0xA738C6BEBB12D16C}, // 1e200
12998 {0xE13336D701BEBA52, 0xD106F86E69D785C7}, // 1e201
12999 {0xECC0024661173473, 0x82A45B450226B39C}, // 1e202
13000 {0x27F002D7F95D0190, 0xA34D721642B06084}, // 1e203
13001 {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5}, // 1e204
13002 {0x7E67047175A15271, 0xFF290242C83396CE}, // 1e205
13003 {0x0F0062C6E984D386, 0x9F79A169BD203E41}, // 1e206
13004 {0x52C07B78A3E60868, 0xC75809C42C684DD1}, // 1e207
13005 {0xA7709A56CCDF8A82, 0xF92E0C3537826145}, // 1e208
13006 {0x88A66076400BB691, 0x9BBCC7A142B17CCB}, // 1e209
13007 {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE}, // 1e210
13008 {0x0583F6B8C4124D43, 0xF356F7EBF83552FE}, // 1e211
13009 {0xC3727A337A8B704A, 0x98165AF37B2153DE}, // 1e212
13010 {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6}, // 1e213
13011 {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C}, // 1e214
13012 {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7}, // 1e215
13013 {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1}, // 1e216
13014 {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99}, // 1e217
13015 {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0}, // 1e218
13016 {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8}, // 1e219
13017 {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A}, // 1e220
13018 {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24}, // 1e221
13019 {0x7425A83E872C5F47, 0xB10D8E1456105DAD}, // 1e222
13020 {0xD12F124E28F77719, 0xDD50F1996B947518}, // 1e223
13021 {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F}, // 1e224
13022 {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B}, // 1e225
13023 {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A}, // 1e226
13024 {0x65ACFAEC34810A71, 0x8714A775E3E95C78}, // 1e227
13025 {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396}, // 1e228
13026 {0x1EDE48111209A050, 0xD31045A8341CA07C}, // 1e229
13027 {0x934AED0AAB460432, 0x83EA2B892091E44D}, // 1e230
13028 {0xF81DA84D5617853F, 0xA4E4B66B68B65D60}, // 1e231
13029 {0x36251260AB9D668E, 0xCE1DE40642E3F4B9}, // 1e232
13030 {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3}, // 1e233
13031 {0xB24CF65B8612F81F, 0xA1075A24E4421730}, // 1e234
13032 {0xDEE033F26797B627, 0xC94930AE1D529CFC}, // 1e235
13033 {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C}, // 1e236
13034 {0x8E1F289560EE864E, 0x9D412E0806E88AA5}, // 1e237
13035 {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E}, // 1e238
13036 {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2}, // 1e239
13037 {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765}, // 1e240
13038 {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F}, // 1e241
13039 {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E}, // 1e242
13040 {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9}, // 1e243
13041 {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F}, // 1e244
13042 {0x84C86189216DC5ED, 0xEA53DF5FD18D5513}, // 1e245
13043 {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C}, // 1e246
13044 {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77}, // 1e247
13045 {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515}, // 1e248
13046 {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D}, // 1e249
13047 {0x743E20E9EF511012, 0xB2C71D5BCA9023F8}, // 1e250
13048 {0x914DA9246B255416, 0xDF78E4B2BD342CF6}, // 1e251
13049 {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A}, // 1e252
13050 {0xA184AC2473B529B1, 0xAE9672ABA3D0C320}, // 1e253
13051 {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8}, // 1e254
13052 {0x7E2FA67C7A658892, 0x8865899617FB1871}, // 1e255
13053 {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D}, // 1e256
13054 {0x552A74227F3EA565, 0xD51EA6FA85785631}, // 1e257
13055 {0xD53A88958F87275F, 0x8533285C936B35DE}, // 1e258
13056 {0x8A892ABAF368F137, 0xA67FF273B8460356}, // 1e259
13057 {0x2D2B7569B0432D85, 0xD01FEF10A657842C}, // 1e260
13058 {0x9C3B29620E29FC73, 0x8213F56A67F6B29B}, // 1e261
13059 {0x8349F3BA91B47B8F, 0xA298F2C501F45F42}, // 1e262
13060 {0x241C70A936219A73, 0xCB3F2F7642717713}, // 1e263
13061 {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7}, // 1e264
13062 {0xF4363804324A40AA, 0x9EC95D1463E8A506}, // 1e265
13063 {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48}, // 1e266
13064 {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA}, // 1e267
13065 {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128}, // 1e268
13066 {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72}, // 1e269
13067 {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF}, // 1e270
13068 {0xD5BE0503E085D813, 0x976E41088617CA01}, // 1e271
13069 {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82}, // 1e272
13070 {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2}, // 1e273
13071 {0xCABB90E5C942B503, 0x93E1AB8252F33B45}, // 1e274
13072 {0x3D6A751F3B936243, 0xB8DA1662E7B00A17}, // 1e275
13073 {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D}, // 1e276
13074 {0x27FB2B80668B24C5, 0x906A617D450187E2}, // 1e277
13075 {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA}, // 1e278
13076 {0x5E7873F8A0396973, 0xE1A63853BBD26451}, // 1e279
13077 {0xDB0B487B6423E1E8, 0x8D07E33455637EB2}, // 1e280
13078 {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F}, // 1e281
13079 {0x7641A140CC7810FB, 0xDC5C5301C56B75F7}, // 1e282
13080 {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA}, // 1e283
13081 {0x546345FA9FBDCD44, 0xAC2820D9623BF429}, // 1e284
13082 {0xA97C177947AD4095, 0xD732290FBACAF133}, // 1e285
13083 {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0}, // 1e286
13084 {0x5C68F256BFFF5A74, 0xA81F301449EE8C70}, // 1e287
13085 {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C}, // 1e288
13086 };
13087
13088 // wuffs_base__private_implementation__f64_powers_of_10 holds powers of 10 that
13089 // can be exactly represented by a float64 (what C calls a double).
13090 static const double wuffs_base__private_implementation__f64_powers_of_10[23] = {
13091 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
13092 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
13093 };
13094
13095 // ---------------- IEEE 754 Floating Point
13096
13097 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 //
wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f)13098 wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) {
13099 uint64_t u = 0;
13100 if (sizeof(uint64_t) == sizeof(double)) {
13101 memcpy(&u, &f, sizeof(uint64_t));
13102 }
13103 uint16_t neg = ((uint16_t)((u >> 63) << 15));
13104 u &= 0x7FFFFFFFFFFFFFFF;
13105 uint64_t exp = u >> 52;
13106 uint64_t man = u & 0x000FFFFFFFFFFFFF;
13107
13108 if (exp == 0x7FF) {
13109 if (man == 0) { // Infinity.
13110 wuffs_base__lossy_value_u16 ret;
13111 ret.value = neg | 0x7C00;
13112 ret.lossy = false;
13113 return ret;
13114 }
13115 // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most
13116 // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9
13117 // bits of ret.value so that the 10-bit mantissa is non-zero.
13118 wuffs_base__lossy_value_u16 ret;
13119 ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42));
13120 ret.lossy = false;
13121 return ret;
13122
13123 } else if (exp > 0x40E) { // Truncate to the largest finite f16.
13124 wuffs_base__lossy_value_u16 ret;
13125 ret.value = neg | 0x7BFF;
13126 ret.lossy = true;
13127 return ret;
13128
13129 } else if (exp <= 0x3E6) { // Truncate to zero.
13130 wuffs_base__lossy_value_u16 ret;
13131 ret.value = neg;
13132 ret.lossy = (u != 0);
13133 return ret;
13134
13135 } else if (exp <= 0x3F0) { // Normal f64, subnormal f16.
13136 // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
13137 // 10-bit mantissa and then adjust for the exponent.
13138 man |= 0x0010000000000000;
13139 uint32_t shift = ((uint32_t)(1051 - exp)); // 1051 = 0x3F0 + 53 - 10.
13140 uint64_t shifted_man = man >> shift;
13141 wuffs_base__lossy_value_u16 ret;
13142 ret.value = neg | ((uint16_t)shifted_man);
13143 ret.lossy = (shifted_man << shift) != man;
13144 return ret;
13145 }
13146
13147 // Normal f64, normal f16.
13148
13149 // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits.
13150 exp = (exp - 1008) << 10; // 1008 = 1023 - 15 = 0x3FF - 0xF.
13151
13152 // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit
13153 // mantissa (again excluding the implicit bit). We lose some information if
13154 // any of the bottom 42 bits are non-zero.
13155 wuffs_base__lossy_value_u16 ret;
13156 ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42));
13157 ret.lossy = (man << 22) != 0;
13158 return ret;
13159 }
13160
13161 WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 //
wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f)13162 wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) {
13163 uint64_t u = 0;
13164 if (sizeof(uint64_t) == sizeof(double)) {
13165 memcpy(&u, &f, sizeof(uint64_t));
13166 }
13167 uint32_t neg = ((uint32_t)(u >> 63)) << 31;
13168 u &= 0x7FFFFFFFFFFFFFFF;
13169 uint64_t exp = u >> 52;
13170 uint64_t man = u & 0x000FFFFFFFFFFFFF;
13171
13172 if (exp == 0x7FF) {
13173 if (man == 0) { // Infinity.
13174 wuffs_base__lossy_value_u32 ret;
13175 ret.value = neg | 0x7F800000;
13176 ret.lossy = false;
13177 return ret;
13178 }
13179 // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most
13180 // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22
13181 // bits of ret.value so that the 23-bit mantissa is non-zero.
13182 wuffs_base__lossy_value_u32 ret;
13183 ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29));
13184 ret.lossy = false;
13185 return ret;
13186
13187 } else if (exp > 0x47E) { // Truncate to the largest finite f32.
13188 wuffs_base__lossy_value_u32 ret;
13189 ret.value = neg | 0x7F7FFFFF;
13190 ret.lossy = true;
13191 return ret;
13192
13193 } else if (exp <= 0x369) { // Truncate to zero.
13194 wuffs_base__lossy_value_u32 ret;
13195 ret.value = neg;
13196 ret.lossy = (u != 0);
13197 return ret;
13198
13199 } else if (exp <= 0x380) { // Normal f64, subnormal f32.
13200 // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
13201 // 23-bit mantissa and then adjust for the exponent.
13202 man |= 0x0010000000000000;
13203 uint32_t shift = ((uint32_t)(926 - exp)); // 926 = 0x380 + 53 - 23.
13204 uint64_t shifted_man = man >> shift;
13205 wuffs_base__lossy_value_u32 ret;
13206 ret.value = neg | ((uint32_t)shifted_man);
13207 ret.lossy = (shifted_man << shift) != man;
13208 return ret;
13209 }
13210
13211 // Normal f64, normal f32.
13212
13213 // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits.
13214 exp = (exp - 896) << 23; // 896 = 1023 - 127 = 0x3FF - 0x7F.
13215
13216 // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit
13217 // mantissa (again excluding the implicit bit). We lose some information if
13218 // any of the bottom 29 bits are non-zero.
13219 wuffs_base__lossy_value_u32 ret;
13220 ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29));
13221 ret.lossy = (man << 35) != 0;
13222 return ret;
13223 }
13224
13225 // --------
13226
13227 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE 2047
13228 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION 800
13229
13230 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL is the largest N
13231 // such that ((10 << N) < (1 << 64)).
13232 #define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL 60
13233
13234 // wuffs_base__private_implementation__high_prec_dec (abbreviated as HPD) is a
13235 // fixed precision floating point decimal number, augmented with ±infinity
13236 // values, but it cannot represent NaN (Not a Number).
13237 //
13238 // "High precision" means that the mantissa holds 800 decimal digits. 800 is
13239 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION.
13240 //
13241 // An HPD isn't for general purpose arithmetic, only for conversions to and
13242 // from IEEE 754 double-precision floating point, where the largest and
13243 // smallest positive, finite values are approximately 1.8e+308 and 4.9e-324.
13244 // HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047
13245 // bounds are further away from zero than ±(324 + 800), where 800 and 2047 is
13246 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION and
13247 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13248 //
13249 // digits[.. num_digits] are the number's digits in big-endian order. The
13250 // uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7'
13251 // is the ASCII value 0x37.
13252 //
13253 // decimal_point is the index (within digits) of the decimal point. It may be
13254 // negative or be larger than num_digits, in which case the explicit digits are
13255 // padded with implicit zeroes.
13256 //
13257 // For example, if num_digits is 3 and digits is "\x07\x08\x09":
13258 // - A decimal_point of -2 means ".00789"
13259 // - A decimal_point of -1 means ".0789"
13260 // - A decimal_point of +0 means ".789"
13261 // - A decimal_point of +1 means "7.89"
13262 // - A decimal_point of +2 means "78.9"
13263 // - A decimal_point of +3 means "789."
13264 // - A decimal_point of +4 means "7890."
13265 // - A decimal_point of +5 means "78900."
13266 //
13267 // As above, a decimal_point higher than +2047 means that the overall value is
13268 // infinity, lower than -2047 means zero.
13269 //
13270 // negative is a sign bit. An HPD can distinguish positive and negative zero.
13271 //
13272 // truncated is whether there are more than
13273 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION digits, and at
13274 // least one of those extra digits are non-zero. The existence of long-tail
13275 // digits can affect rounding.
13276 //
13277 // The "all fields are zero" value is valid, and represents the number +0.
13278 typedef struct wuffs_base__private_implementation__high_prec_dec__struct {
13279 uint32_t num_digits;
13280 int32_t decimal_point;
13281 bool negative;
13282 bool truncated;
13283 uint8_t digits[WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION];
13284 } wuffs_base__private_implementation__high_prec_dec;
13285
13286 // wuffs_base__private_implementation__high_prec_dec__trim trims trailing
13287 // zeroes from the h->digits[.. h->num_digits] slice. They have no benefit,
13288 // since we explicitly track h->decimal_point.
13289 //
13290 // Preconditions:
13291 // - h is non-NULL.
13292 static inline void //
wuffs_base__private_implementation__high_prec_dec__trim(wuffs_base__private_implementation__high_prec_dec * h)13293 wuffs_base__private_implementation__high_prec_dec__trim(
13294 wuffs_base__private_implementation__high_prec_dec* h) {
13295 while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) {
13296 h->num_digits--;
13297 }
13298 }
13299
13300 // wuffs_base__private_implementation__high_prec_dec__assign sets h to
13301 // represent the number x.
13302 //
13303 // Preconditions:
13304 // - h is non-NULL.
13305 static void //
wuffs_base__private_implementation__high_prec_dec__assign(wuffs_base__private_implementation__high_prec_dec * h,uint64_t x,bool negative)13306 wuffs_base__private_implementation__high_prec_dec__assign(
13307 wuffs_base__private_implementation__high_prec_dec* h,
13308 uint64_t x,
13309 bool negative) {
13310 uint32_t n = 0;
13311
13312 // Set h->digits.
13313 if (x > 0) {
13314 // Calculate the digits, working right-to-left. After we determine n (how
13315 // many digits there are), copy from buf to h->digits.
13316 //
13317 // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to
13318 // copy a constant number of bytes than a variable number (20 instead of
13319 // n). Make buf large enough (and start writing to it from the middle) so
13320 // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)].
13321 uint8_t buf[40] = {0};
13322 uint8_t* ptr = &buf[20];
13323 do {
13324 uint64_t remaining = x / 10;
13325 x -= remaining * 10;
13326 ptr--;
13327 *ptr = (uint8_t)x;
13328 n++;
13329 x = remaining;
13330 } while (x > 0);
13331 memcpy(h->digits, ptr, 20);
13332 }
13333
13334 // Set h's other fields.
13335 h->num_digits = n;
13336 h->decimal_point = (int32_t)n;
13337 h->negative = negative;
13338 h->truncated = false;
13339 wuffs_base__private_implementation__high_prec_dec__trim(h);
13340 }
13341
13342 static wuffs_base__status //
wuffs_base__private_implementation__high_prec_dec__parse(wuffs_base__private_implementation__high_prec_dec * h,wuffs_base__slice_u8 s,uint32_t options)13343 wuffs_base__private_implementation__high_prec_dec__parse(
13344 wuffs_base__private_implementation__high_prec_dec* h,
13345 wuffs_base__slice_u8 s,
13346 uint32_t options) {
13347 if (!h) {
13348 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
13349 }
13350 h->num_digits = 0;
13351 h->decimal_point = 0;
13352 h->negative = false;
13353 h->truncated = false;
13354
13355 uint8_t* p = s.ptr;
13356 uint8_t* q = s.ptr + s.len;
13357
13358 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13359 for (;; p++) {
13360 if (p >= q) {
13361 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13362 } else if (*p != '_') {
13363 break;
13364 }
13365 }
13366 }
13367
13368 // Parse sign.
13369 do {
13370 if (*p == '+') {
13371 p++;
13372 } else if (*p == '-') {
13373 h->negative = true;
13374 p++;
13375 } else {
13376 break;
13377 }
13378 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13379 for (;; p++) {
13380 if (p >= q) {
13381 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13382 } else if (*p != '_') {
13383 break;
13384 }
13385 }
13386 }
13387 } while (0);
13388
13389 // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each
13390 // limb in this if-else chain:
13391 // - "0.789"
13392 // - "1002.789"
13393 // - ".789"
13394 // - Other (invalid input).
13395 uint32_t nd = 0;
13396 int32_t dp = 0;
13397 bool no_digits_before_separator = false;
13398 if (('0' == *p) &&
13399 !(options &
13400 WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) {
13401 p++;
13402 for (;; p++) {
13403 if (p >= q) {
13404 goto after_all;
13405 } else if (*p ==
13406 ((options &
13407 WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13408 ? ','
13409 : '.')) {
13410 p++;
13411 goto after_sep;
13412 } else if ((*p == 'E') || (*p == 'e')) {
13413 p++;
13414 goto after_exp;
13415 } else if ((*p != '_') ||
13416 !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13417 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13418 }
13419 }
13420
13421 } else if (('0' <= *p) && (*p <= '9')) {
13422 if (*p == '0') {
13423 for (; (p < q) && (*p == '0'); p++) {
13424 }
13425 } else {
13426 h->digits[nd++] = (uint8_t)(*p - '0');
13427 dp = (int32_t)nd;
13428 p++;
13429 }
13430
13431 for (;; p++) {
13432 if (p >= q) {
13433 goto after_all;
13434 } else if (('0' <= *p) && (*p <= '9')) {
13435 if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13436 h->digits[nd++] = (uint8_t)(*p - '0');
13437 dp = (int32_t)nd;
13438 } else if ('0' != *p) {
13439 // Long-tail non-zeroes set the truncated bit.
13440 h->truncated = true;
13441 }
13442 } else if (*p ==
13443 ((options &
13444 WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13445 ? ','
13446 : '.')) {
13447 p++;
13448 goto after_sep;
13449 } else if ((*p == 'E') || (*p == 'e')) {
13450 p++;
13451 goto after_exp;
13452 } else if ((*p != '_') ||
13453 !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13454 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13455 }
13456 }
13457
13458 } else if (*p == ((options &
13459 WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
13460 ? ','
13461 : '.')) {
13462 p++;
13463 no_digits_before_separator = true;
13464
13465 } else {
13466 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13467 }
13468
13469 after_sep:
13470 for (;; p++) {
13471 if (p >= q) {
13472 goto after_all;
13473 } else if ('0' == *p) {
13474 if (nd == 0) {
13475 // Track leading zeroes implicitly.
13476 dp--;
13477 } else if (nd <
13478 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13479 h->digits[nd++] = (uint8_t)(*p - '0');
13480 }
13481 } else if (('0' < *p) && (*p <= '9')) {
13482 if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13483 h->digits[nd++] = (uint8_t)(*p - '0');
13484 } else {
13485 // Long-tail non-zeroes set the truncated bit.
13486 h->truncated = true;
13487 }
13488 } else if ((*p == 'E') || (*p == 'e')) {
13489 p++;
13490 goto after_exp;
13491 } else if ((*p != '_') ||
13492 !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13493 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13494 }
13495 }
13496
13497 after_exp:
13498 do {
13499 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
13500 for (;; p++) {
13501 if (p >= q) {
13502 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13503 } else if (*p != '_') {
13504 break;
13505 }
13506 }
13507 }
13508
13509 int32_t exp_sign = +1;
13510 if (*p == '+') {
13511 p++;
13512 } else if (*p == '-') {
13513 exp_sign = -1;
13514 p++;
13515 }
13516
13517 int32_t exp = 0;
13518 const int32_t exp_large =
13519 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE +
13520 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
13521 bool saw_exp_digits = false;
13522 for (; p < q; p++) {
13523 if ((*p == '_') &&
13524 (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
13525 // No-op.
13526 } else if (('0' <= *p) && (*p <= '9')) {
13527 saw_exp_digits = true;
13528 if (exp < exp_large) {
13529 exp = (10 * exp) + ((int32_t)(*p - '0'));
13530 }
13531 } else {
13532 break;
13533 }
13534 }
13535 if (!saw_exp_digits) {
13536 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13537 }
13538 dp += exp_sign * exp;
13539 } while (0);
13540
13541 after_all:
13542 if (p != q) {
13543 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13544 }
13545 h->num_digits = nd;
13546 if (nd == 0) {
13547 if (no_digits_before_separator) {
13548 return wuffs_base__make_status(wuffs_base__error__bad_argument);
13549 }
13550 h->decimal_point = 0;
13551 } else if (dp <
13552 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13553 h->decimal_point =
13554 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE - 1;
13555 } else if (dp >
13556 +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13557 h->decimal_point =
13558 +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + 1;
13559 } else {
13560 h->decimal_point = dp;
13561 }
13562 wuffs_base__private_implementation__high_prec_dec__trim(h);
13563 return wuffs_base__make_status(NULL);
13564 }
13565
13566 // --------
13567
13568 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
13569 // returns the number of additional decimal digits when left-shifting by shift.
13570 //
13571 // See below for preconditions.
13572 static uint32_t //
wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)13573 wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
13574 wuffs_base__private_implementation__high_prec_dec* h,
13575 uint32_t shift) {
13576 // Masking with 0x3F should be unnecessary (assuming the preconditions) but
13577 // it's cheap and ensures that we don't overflow the
13578 // wuffs_base__private_implementation__hpd_left_shift array.
13579 shift &= 63;
13580
13581 uint32_t x_a = wuffs_base__private_implementation__hpd_left_shift[shift];
13582 uint32_t x_b = wuffs_base__private_implementation__hpd_left_shift[shift + 1];
13583 uint32_t num_new_digits = x_a >> 11;
13584 uint32_t pow5_a = 0x7FF & x_a;
13585 uint32_t pow5_b = 0x7FF & x_b;
13586
13587 const uint8_t* pow5 =
13588 &wuffs_base__private_implementation__powers_of_5[pow5_a];
13589 uint32_t i = 0;
13590 uint32_t n = pow5_b - pow5_a;
13591 for (; i < n; i++) {
13592 if (i >= h->num_digits) {
13593 return num_new_digits - 1;
13594 } else if (h->digits[i] == pow5[i]) {
13595 continue;
13596 } else if (h->digits[i] < pow5[i]) {
13597 return num_new_digits - 1;
13598 } else {
13599 return num_new_digits;
13600 }
13601 }
13602 return num_new_digits;
13603 }
13604
13605 // --------
13606
13607 // wuffs_base__private_implementation__high_prec_dec__rounded_integer returns
13608 // the integral (non-fractional) part of h, provided that it is 18 or fewer
13609 // decimal digits. For 19 or more digits, it returns UINT64_MAX. Note that:
13610 // - (1 << 53) is 9007199254740992, which has 16 decimal digits.
13611 // - (1 << 56) is 72057594037927936, which has 17 decimal digits.
13612 // - (1 << 59) is 576460752303423488, which has 18 decimal digits.
13613 // - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
13614 // and that IEEE 754 double precision has 52 mantissa bits.
13615 //
13616 // That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8.
13617 //
13618 // h's negative bit is ignored: rounding -8.6 returns 9.
13619 //
13620 // See below for preconditions.
13621 static uint64_t //
wuffs_base__private_implementation__high_prec_dec__rounded_integer(wuffs_base__private_implementation__high_prec_dec * h)13622 wuffs_base__private_implementation__high_prec_dec__rounded_integer(
13623 wuffs_base__private_implementation__high_prec_dec* h) {
13624 if ((h->num_digits == 0) || (h->decimal_point < 0)) {
13625 return 0;
13626 } else if (h->decimal_point > 18) {
13627 return UINT64_MAX;
13628 }
13629
13630 uint32_t dp = (uint32_t)(h->decimal_point);
13631 uint64_t n = 0;
13632 uint32_t i = 0;
13633 for (; i < dp; i++) {
13634 n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);
13635 }
13636
13637 bool round_up = false;
13638 if (dp < h->num_digits) {
13639 round_up = h->digits[dp] >= 5;
13640 if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {
13641 // We are exactly halfway. If we're truncated, round up, otherwise round
13642 // to even.
13643 round_up = h->truncated || //
13644 ((dp > 0) && (1 & h->digits[dp - 1]));
13645 }
13646 }
13647 if (round_up) {
13648 n++;
13649 }
13650
13651 return n;
13652 }
13653
13654 // wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's
13655 // number (where 'x' is 'l' or 'r' for left or right) by a small shift value.
13656 //
13657 // Preconditions:
13658 // - h is non-NULL.
13659 // - h->decimal_point is "not extreme".
13660 // - shift is non-zero.
13661 // - shift is "a small shift".
13662 //
13663 // "Not extreme" means within
13664 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13665 //
13666 // "A small shift" means not more than
13667 // WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
13668 //
13669 // wuffs_base__private_implementation__high_prec_dec__rounded_integer and
13670 // wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
13671 // have the same preconditions.
13672 //
13673 // wuffs_base__private_implementation__high_prec_dec__lshift keeps the first
13674 // two preconditions but not the last two. Its shift argument is signed and
13675 // does not need to be "small": zero is a no-op, positive means left shift and
13676 // negative means right shift.
13677
13678 static void //
wuffs_base__private_implementation__high_prec_dec__small_lshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)13679 wuffs_base__private_implementation__high_prec_dec__small_lshift(
13680 wuffs_base__private_implementation__high_prec_dec* h,
13681 uint32_t shift) {
13682 if (h->num_digits == 0) {
13683 return;
13684 }
13685 uint32_t num_new_digits =
13686 wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
13687 h, shift);
13688 uint32_t rx = h->num_digits - 1; // Read index.
13689 uint32_t wx = h->num_digits - 1 + num_new_digits; // Write index.
13690 uint64_t n = 0;
13691
13692 // Repeat: pick up a digit, put down a digit, right to left.
13693 while (((int32_t)rx) >= 0) {
13694 n += ((uint64_t)(h->digits[rx])) << shift;
13695 uint64_t quo = n / 10;
13696 uint64_t rem = n - (10 * quo);
13697 if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13698 h->digits[wx] = (uint8_t)rem;
13699 } else if (rem > 0) {
13700 h->truncated = true;
13701 }
13702 n = quo;
13703 wx--;
13704 rx--;
13705 }
13706
13707 // Put down leading digits, right to left.
13708 while (n > 0) {
13709 uint64_t quo = n / 10;
13710 uint64_t rem = n - (10 * quo);
13711 if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13712 h->digits[wx] = (uint8_t)rem;
13713 } else if (rem > 0) {
13714 h->truncated = true;
13715 }
13716 n = quo;
13717 wx--;
13718 }
13719
13720 // Finish.
13721 h->num_digits += num_new_digits;
13722 if (h->num_digits >
13723 WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13724 h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
13725 }
13726 h->decimal_point += (int32_t)num_new_digits;
13727 wuffs_base__private_implementation__high_prec_dec__trim(h);
13728 }
13729
13730 static void //
wuffs_base__private_implementation__high_prec_dec__small_rshift(wuffs_base__private_implementation__high_prec_dec * h,uint32_t shift)13731 wuffs_base__private_implementation__high_prec_dec__small_rshift(
13732 wuffs_base__private_implementation__high_prec_dec* h,
13733 uint32_t shift) {
13734 uint32_t rx = 0; // Read index.
13735 uint32_t wx = 0; // Write index.
13736 uint64_t n = 0;
13737
13738 // Pick up enough leading digits to cover the first shift.
13739 while ((n >> shift) == 0) {
13740 if (rx < h->num_digits) {
13741 // Read a digit.
13742 n = (10 * n) + h->digits[rx++];
13743 } else if (n == 0) {
13744 // h's number used to be zero and remains zero.
13745 return;
13746 } else {
13747 // Read sufficient implicit trailing zeroes.
13748 while ((n >> shift) == 0) {
13749 n = 10 * n;
13750 rx++;
13751 }
13752 break;
13753 }
13754 }
13755 h->decimal_point -= ((int32_t)(rx - 1));
13756 if (h->decimal_point <
13757 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
13758 // After the shift, h's number is effectively zero.
13759 h->num_digits = 0;
13760 h->decimal_point = 0;
13761 h->truncated = false;
13762 return;
13763 }
13764
13765 // Repeat: pick up a digit, put down a digit, left to right.
13766 uint64_t mask = (((uint64_t)(1)) << shift) - 1;
13767 while (rx < h->num_digits) {
13768 uint8_t new_digit = ((uint8_t)(n >> shift));
13769 n = (10 * (n & mask)) + h->digits[rx++];
13770 h->digits[wx++] = new_digit;
13771 }
13772
13773 // Put down trailing digits, left to right.
13774 while (n > 0) {
13775 uint8_t new_digit = ((uint8_t)(n >> shift));
13776 n = 10 * (n & mask);
13777 if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
13778 h->digits[wx++] = new_digit;
13779 } else if (new_digit > 0) {
13780 h->truncated = true;
13781 }
13782 }
13783
13784 // Finish.
13785 h->num_digits = wx;
13786 wuffs_base__private_implementation__high_prec_dec__trim(h);
13787 }
13788
13789 static void //
wuffs_base__private_implementation__high_prec_dec__lshift(wuffs_base__private_implementation__high_prec_dec * h,int32_t shift)13790 wuffs_base__private_implementation__high_prec_dec__lshift(
13791 wuffs_base__private_implementation__high_prec_dec* h,
13792 int32_t shift) {
13793 if (shift > 0) {
13794 while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
13795 wuffs_base__private_implementation__high_prec_dec__small_lshift(
13796 h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
13797 shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
13798 }
13799 wuffs_base__private_implementation__high_prec_dec__small_lshift(
13800 h, ((uint32_t)(+shift)));
13801 } else if (shift < 0) {
13802 while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
13803 wuffs_base__private_implementation__high_prec_dec__small_rshift(
13804 h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
13805 shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
13806 }
13807 wuffs_base__private_implementation__high_prec_dec__small_rshift(
13808 h, ((uint32_t)(-shift)));
13809 }
13810 }
13811
13812 // --------
13813
13814 // wuffs_base__private_implementation__high_prec_dec__round_etc rounds h's
13815 // number. For those functions that take an n argument, rounding produces at
13816 // most n digits (which is not necessarily at most n decimal places). Negative
13817 // n values are ignored, as well as any n greater than or equal to h's number
13818 // of digits. The etc__round_just_enough function implicitly chooses an n to
13819 // implement WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION.
13820 //
13821 // Preconditions:
13822 // - h is non-NULL.
13823 // - h->decimal_point is "not extreme".
13824 //
13825 // "Not extreme" means within
13826 // ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
13827
13828 static void //
wuffs_base__private_implementation__high_prec_dec__round_down(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13829 wuffs_base__private_implementation__high_prec_dec__round_down(
13830 wuffs_base__private_implementation__high_prec_dec* h,
13831 int32_t n) {
13832 if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13833 return;
13834 }
13835 h->num_digits = (uint32_t)(n);
13836 wuffs_base__private_implementation__high_prec_dec__trim(h);
13837 }
13838
13839 static void //
wuffs_base__private_implementation__high_prec_dec__round_up(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13840 wuffs_base__private_implementation__high_prec_dec__round_up(
13841 wuffs_base__private_implementation__high_prec_dec* h,
13842 int32_t n) {
13843 if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13844 return;
13845 }
13846
13847 for (n--; n >= 0; n--) {
13848 if (h->digits[n] < 9) {
13849 h->digits[n]++;
13850 h->num_digits = (uint32_t)(n + 1);
13851 return;
13852 }
13853 }
13854
13855 // The number is all 9s. Change to a single 1 and adjust the decimal point.
13856 h->digits[0] = 1;
13857 h->num_digits = 1;
13858 h->decimal_point++;
13859 }
13860
13861 static void //
wuffs_base__private_implementation__high_prec_dec__round_nearest(wuffs_base__private_implementation__high_prec_dec * h,int32_t n)13862 wuffs_base__private_implementation__high_prec_dec__round_nearest(
13863 wuffs_base__private_implementation__high_prec_dec* h,
13864 int32_t n) {
13865 if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
13866 return;
13867 }
13868 bool up = h->digits[n] >= 5;
13869 if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) {
13870 up = h->truncated || //
13871 ((n > 0) && ((h->digits[n - 1] & 1) != 0));
13872 }
13873
13874 if (up) {
13875 wuffs_base__private_implementation__high_prec_dec__round_up(h, n);
13876 } else {
13877 wuffs_base__private_implementation__high_prec_dec__round_down(h, n);
13878 }
13879 }
13880
13881 static void //
wuffs_base__private_implementation__high_prec_dec__round_just_enough(wuffs_base__private_implementation__high_prec_dec * h,int32_t exp2,uint64_t mantissa)13882 wuffs_base__private_implementation__high_prec_dec__round_just_enough(
13883 wuffs_base__private_implementation__high_prec_dec* h,
13884 int32_t exp2,
13885 uint64_t mantissa) {
13886 // The magic numbers 52 and 53 in this function are because IEEE 754 double
13887 // precision has 52 mantissa bits.
13888 //
13889 // Let f be the floating point number represented by exp2 and mantissa (and
13890 // also the number in h): the number (mantissa * (2 ** (exp2 - 52))).
13891 //
13892 // If f is zero or a small integer, we can return early.
13893 if ((mantissa == 0) ||
13894 ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) {
13895 return;
13896 }
13897
13898 // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52).
13899 // Subnormal numbers have the same exp2 but a smaller mantissa.
13900 static const int32_t min_incl_normal_exp2 = -1022;
13901 static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul;
13902
13903 // Compute lower and upper bounds such that any number between them (possibly
13904 // inclusive) will round to f. First, the lower bound. Our number f is:
13905 // ((mantissa + 0) * (2 ** ( exp2 - 52)))
13906 //
13907 // The next lowest floating point number is:
13908 // ((mantissa - 1) * (2 ** ( exp2 - 52)))
13909 // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the
13910 // min_incl_normal_exp2. Either way, call it:
13911 // ((l_mantissa) * (2 ** (l_exp2 - 52)))
13912 //
13913 // The lower bound is halfway between them (noting that 52 became 53):
13914 // (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53)))
13915 int32_t l_exp2 = exp2;
13916 uint64_t l_mantissa = mantissa - 1;
13917 if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) {
13918 l_exp2 = exp2 - 1;
13919 l_mantissa = (2 * mantissa) - 1;
13920 }
13921 wuffs_base__private_implementation__high_prec_dec lower;
13922 wuffs_base__private_implementation__high_prec_dec__assign(
13923 &lower, (2 * l_mantissa) + 1, false);
13924 wuffs_base__private_implementation__high_prec_dec__lshift(&lower,
13925 l_exp2 - 53);
13926
13927 // Next, the upper bound. Our number f is:
13928 // ((mantissa + 0) * (2 ** (exp2 - 52)))
13929 //
13930 // The next highest floating point number is:
13931 // ((mantissa + 1) * (2 ** (exp2 - 52)))
13932 //
13933 // The upper bound is halfway between them (noting that 52 became 53):
13934 // (((2 * mantissa) + 1) * (2 ** (exp2 - 53)))
13935 wuffs_base__private_implementation__high_prec_dec upper;
13936 wuffs_base__private_implementation__high_prec_dec__assign(
13937 &upper, (2 * mantissa) + 1, false);
13938 wuffs_base__private_implementation__high_prec_dec__lshift(&upper, exp2 - 53);
13939
13940 // The lower and upper bounds are possible outputs only if the original
13941 // mantissa is even, so that IEEE round-to-even would round to the original
13942 // mantissa and not its neighbors.
13943 bool inclusive = (mantissa & 1) == 0;
13944
13945 // As we walk the digits, we want to know whether rounding up would fall
13946 // within the upper bound. This is tracked by upper_delta:
13947 // - When -1, the digits of h and upper are the same so far.
13948 // - When +0, we saw a difference of 1 between h and upper on a previous
13949 // digit and subsequently only 9s for h and 0s for upper. Thus, rounding
13950 // up may fall outside of the bound if !inclusive.
13951 // - When +1, the difference is greater than 1 and we know that rounding up
13952 // falls within the bound.
13953 //
13954 // This is a state machine with three states. The numerical value for each
13955 // state (-1, +0 or +1) isn't important, other than their order.
13956 int upper_delta = -1;
13957
13958 // We can now figure out the shortest number of digits required. Walk the
13959 // digits until h has distinguished itself from lower or upper.
13960 //
13961 // The zi and zd variables are indexes and digits, for z in l (lower), h (the
13962 // number) and u (upper).
13963 //
13964 // The lower, h and upper numbers may have their decimal points at different
13965 // places. In this case, upper is the longest, so we iterate ui starting from
13966 // 0 and iterate li and hi starting from either 0 or -1.
13967 int32_t ui = 0;
13968 for (;; ui++) {
13969 // Calculate hd, the middle number's digit.
13970 int32_t hi = ui - upper.decimal_point + h->decimal_point;
13971 if (hi >= ((int32_t)(h->num_digits))) {
13972 break;
13973 }
13974 uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0;
13975
13976 // Calculate ld, the lower bound's digit.
13977 int32_t li = ui - upper.decimal_point + lower.decimal_point;
13978 uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0;
13979
13980 // We can round down (truncate) if lower has a different digit than h or if
13981 // lower is inclusive and is exactly the result of rounding down (i.e. we
13982 // have reached the final digit of lower).
13983 bool can_round_down =
13984 (ld != hd) || //
13985 (inclusive && ((li + 1) == ((int32_t)(lower.num_digits))));
13986
13987 // Calculate ud, the upper bound's digit, and update upper_delta.
13988 uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0;
13989 if (upper_delta < 0) {
13990 if ((hd + 1) < ud) {
13991 // For example:
13992 // h = 12345???
13993 // upper = 12347???
13994 upper_delta = +1;
13995 } else if (hd != ud) {
13996 // For example:
13997 // h = 12345???
13998 // upper = 12346???
13999 upper_delta = +0;
14000 }
14001 } else if (upper_delta == 0) {
14002 if ((hd != 9) || (ud != 0)) {
14003 // For example:
14004 // h = 1234598?
14005 // upper = 1234600?
14006 upper_delta = +1;
14007 }
14008 }
14009
14010 // We can round up if upper has a different digit than h and either upper
14011 // is inclusive or upper is bigger than the result of rounding up.
14012 bool can_round_up =
14013 (upper_delta > 0) || //
14014 ((upper_delta == 0) && //
14015 (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits)))));
14016
14017 // If we can round either way, round to nearest. If we can round only one
14018 // way, do it. If we can't round, continue the loop.
14019 if (can_round_down) {
14020 if (can_round_up) {
14021 wuffs_base__private_implementation__high_prec_dec__round_nearest(
14022 h, hi + 1);
14023 return;
14024 } else {
14025 wuffs_base__private_implementation__high_prec_dec__round_down(h,
14026 hi + 1);
14027 return;
14028 }
14029 } else {
14030 if (can_round_up) {
14031 wuffs_base__private_implementation__high_prec_dec__round_up(h, hi + 1);
14032 return;
14033 }
14034 }
14035 }
14036 }
14037
14038 // --------
14039
14040 // wuffs_base__private_implementation__parse_number_f64_eisel_lemire produces
14041 // the IEEE 754 double-precision value for an exact mantissa and base-10
14042 // exponent. For example:
14043 // - when parsing "12345.678e+02", man is 12345678 and exp10 is -1.
14044 // - when parsing "-12", man is 12 and exp10 is 0. Processing the leading
14045 // minus sign is the responsibility of the caller, not this function.
14046 //
14047 // On success, it returns a non-negative int64_t such that the low 63 bits hold
14048 // the 11-bit exponent and 52-bit mantissa.
14049 //
14050 // On failure, it returns a negative value.
14051 //
14052 // The algorithm is based on an original idea by Michael Eisel that was refined
14053 // by Daniel Lemire. See
14054 // https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/
14055 // and
14056 // https://nigeltao.github.io/blog/2020/eisel-lemire.html
14057 //
14058 // Preconditions:
14059 // - man is non-zero.
14060 // - exp10 is in the range [-307 ..= 288], the same range of the
14061 // wuffs_base__private_implementation__powers_of_10 array.
14062 //
14063 // The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX],
14064 // approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the
14065 // range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal
14066 // (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are
14067 // approximately 2.23e–308 and 1.80e+308.
14068 static int64_t //
wuffs_base__private_implementation__parse_number_f64_eisel_lemire(uint64_t man,int32_t exp10)14069 wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14070 uint64_t man,
14071 int32_t exp10) {
14072 // Look up the (possibly truncated) base-2 representation of (10 ** exp10).
14073 // The look-up table was constructed so that it is already normalized: the
14074 // table entry's mantissa's MSB (most significant bit) is on.
14075 const uint64_t* po10 =
14076 &wuffs_base__private_implementation__powers_of_10[exp10 + 307][0];
14077
14078 // Normalize the man argument. The (man != 0) precondition means that a
14079 // non-zero bit exists.
14080 uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
14081 man <<= clz;
14082
14083 // Calculate the return value's base-2 exponent. We might tweak it by ±1
14084 // later, but its initial value comes from a linear scaling of exp10,
14085 // converting from power-of-10 to power-of-2, and adjusting by clz.
14086 //
14087 // The magic constants are:
14088 // - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because
14089 // the look-up table uses 64-bit mantissas.
14090 // - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough
14091 // (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928.
14092 // - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift.
14093 //
14094 // Equality of the linearly-scaled value and the actual power-of-2, over the
14095 // range of exp10 arguments that this function accepts, is confirmed by
14096 // script/print-mpb-powers-of-10.go
14097 uint64_t ret_exp2 =
14098 ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz);
14099
14100 // Multiply the two mantissas. Normalization means that both mantissas are at
14101 // least (1<<63), so the 128-bit product must be at least (1<<126). The high
14102 // 64 bits of the product, x_hi, must therefore be at least (1<<62).
14103 //
14104 // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi
14105 // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore
14106 // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on.
14107 wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]);
14108 uint64_t x_hi = x.hi;
14109 uint64_t x_lo = x.lo;
14110
14111 // Before we shift right by at least 9 bits, recall that the look-up table
14112 // entry was possibly truncated. We have so far only calculated a lower bound
14113 // for the product (man * e), where e is (10 ** exp10). The upper bound would
14114 // add a further (man * 1) to the 128-bit product, which overflows the lower
14115 // 64-bit limb if ((x_lo + man) < man).
14116 //
14117 // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right
14118 // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit
14119 // limb's low 9 bits are all on.
14120 //
14121 // For example, parsing "9999999999999999999" will take the if-true branch
14122 // here, since:
14123 // - x_hi = 0x4563918244F3FFFF
14124 // - x_lo = 0x8000000000000000
14125 // - man = 0x8AC7230489E7FFFF
14126 if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) {
14127 // Refine our calculation of (man * e). Before, our approximation of e used
14128 // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit
14129 // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e).
14130 // Now calculate y = (man * bits_64_to_127_incl_of_e).
14131 wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]);
14132 uint64_t y_hi = y.hi;
14133 uint64_t y_lo = y.lo;
14134
14135 // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to
14136 // calculate the 192-bit product of the 64-bit man by the 128-bit e.
14137 // As we exit this if-block, we only care about the high 128 bits
14138 // (merged_hi and merged_lo) of that 192-bit product.
14139 //
14140 // For example, parsing "1.234e-45" will take the if-true branch here,
14141 // since:
14142 // - x_hi = 0x70B7E3696DB29FFF
14143 // - x_lo = 0xE040000000000000
14144 // - y_hi = 0x33718BBEAB0E0D7A
14145 // - y_lo = 0xA880000000000000
14146 uint64_t merged_hi = x_hi;
14147 uint64_t merged_lo = x_lo + y_hi;
14148 if (merged_lo < x_lo) {
14149 merged_hi++; // Carry the overflow bit.
14150 }
14151
14152 // The "high resolution" approximation of e is still a lower bound. Once
14153 // again, see if the upper bound is large enough to produce a different
14154 // result. This time, if it does, give up instead of reaching for an even
14155 // more precise approximation to e.
14156 //
14157 // This three-part check is similar to the two-part check that guarded the
14158 // if block that we're now in, but it has an extra term for the middle 64
14159 // bits (checking that adding 1 to merged_lo would overflow).
14160 //
14161 // For example, parsing "5.9604644775390625e-8" will take the if-true
14162 // branch here, since:
14163 // - merged_hi = 0x7FFFFFFFFFFFFFFF
14164 // - merged_lo = 0xFFFFFFFFFFFFFFFF
14165 // - y_lo = 0x4DB3FFC120988200
14166 // - man = 0xD3C21BCECCEDA100
14167 if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) &&
14168 (y_lo + man < man)) {
14169 return -1;
14170 }
14171
14172 // Replace the 128-bit x with merged.
14173 x_hi = merged_hi;
14174 x_lo = merged_lo;
14175 }
14176
14177 // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave
14178 // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the
14179 // MSB (before shifting) was on, adjust ret_exp2 for the larger shift.
14180 //
14181 // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit
14182 // number.
14183 uint64_t msb = x_hi >> 63;
14184 uint64_t ret_mantissa = x_hi >> (msb + 9);
14185 ret_exp2 -= 1 ^ msb;
14186
14187 // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can
14188 // be tricky. If we're half-way between two exactly representable numbers
14189 // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give
14190 // up instead of trying to pick the winner.
14191 //
14192 // Technically, we could tighten the condition by changing "73" to "73 or 74,
14193 // depending on msb", but a flat "73" is simpler.
14194 //
14195 // For example, parsing "1e+23" will take the if-true branch here, since:
14196 // - x_hi = 0x54B40B1F852BDA00
14197 // - ret_mantissa = 0x002A5A058FC295ED
14198 if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) {
14199 return -1;
14200 }
14201
14202 // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit
14203 // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether
14204 // it was on or off, shifting right by one then produces a 53-bit number. If
14205 // carrying up overflowed, shift again.
14206 ret_mantissa += ret_mantissa & 1;
14207 ret_mantissa >>= 1;
14208 // This if block is equivalent to (but benchmarks slightly faster than) the
14209 // following branchless form:
14210 // uint64_t overflow_adjustment = ret_mantissa >> 53;
14211 // ret_mantissa >>= overflow_adjustment;
14212 // ret_exp2 += overflow_adjustment;
14213 //
14214 // For example, parsing "7.2057594037927933e+16" will take the if-true
14215 // branch here, since:
14216 // - x_hi = 0x7FFFFFFFFFFFFE80
14217 // - ret_mantissa = 0x0020000000000000
14218 if ((ret_mantissa >> 53) > 0) {
14219 ret_mantissa >>= 1;
14220 ret_exp2++;
14221 }
14222
14223 // Starting with a 53-bit number, IEEE 754 double-precision normal numbers
14224 // have an implicit mantissa bit. Mask that away and keep the low 52 bits.
14225 ret_mantissa &= 0x000FFFFFFFFFFFFF;
14226
14227 // Pack the bits and return.
14228 return ((int64_t)(ret_mantissa | (ret_exp2 << 52)));
14229 }
14230
14231 // --------
14232
14233 static wuffs_base__result_f64 //
wuffs_base__private_implementation__parse_number_f64_special(wuffs_base__slice_u8 s,uint32_t options)14234 wuffs_base__private_implementation__parse_number_f64_special(
14235 wuffs_base__slice_u8 s,
14236 uint32_t options) {
14237 do {
14238 if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
14239 goto fail;
14240 }
14241
14242 uint8_t* p = s.ptr;
14243 uint8_t* q = s.ptr + s.len;
14244
14245 for (; (p < q) && (*p == '_'); p++) {
14246 }
14247 if (p >= q) {
14248 goto fail;
14249 }
14250
14251 // Parse sign.
14252 bool negative = false;
14253 do {
14254 if (*p == '+') {
14255 p++;
14256 } else if (*p == '-') {
14257 negative = true;
14258 p++;
14259 } else {
14260 break;
14261 }
14262 for (; (p < q) && (*p == '_'); p++) {
14263 }
14264 } while (0);
14265 if (p >= q) {
14266 goto fail;
14267 }
14268
14269 bool nan = false;
14270 switch (p[0]) {
14271 case 'I':
14272 case 'i':
14273 if (((q - p) < 3) || //
14274 ((p[1] != 'N') && (p[1] != 'n')) || //
14275 ((p[2] != 'F') && (p[2] != 'f'))) {
14276 goto fail;
14277 }
14278 p += 3;
14279
14280 if ((p >= q) || (*p == '_')) {
14281 break;
14282 } else if (((q - p) < 5) || //
14283 ((p[0] != 'I') && (p[0] != 'i')) || //
14284 ((p[1] != 'N') && (p[1] != 'n')) || //
14285 ((p[2] != 'I') && (p[2] != 'i')) || //
14286 ((p[3] != 'T') && (p[3] != 't')) || //
14287 ((p[4] != 'Y') && (p[4] != 'y'))) {
14288 goto fail;
14289 }
14290 p += 5;
14291
14292 if ((p >= q) || (*p == '_')) {
14293 break;
14294 }
14295 goto fail;
14296
14297 case 'N':
14298 case 'n':
14299 if (((q - p) < 3) || //
14300 ((p[1] != 'A') && (p[1] != 'a')) || //
14301 ((p[2] != 'N') && (p[2] != 'n'))) {
14302 goto fail;
14303 }
14304 p += 3;
14305
14306 if ((p >= q) || (*p == '_')) {
14307 nan = true;
14308 break;
14309 }
14310 goto fail;
14311
14312 default:
14313 goto fail;
14314 }
14315
14316 // Finish.
14317 for (; (p < q) && (*p == '_'); p++) {
14318 }
14319 if (p != q) {
14320 goto fail;
14321 }
14322 wuffs_base__result_f64 ret;
14323 ret.status.repr = NULL;
14324 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14325 (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |
14326 (negative ? 0x8000000000000000 : 0));
14327 return ret;
14328 } while (0);
14329
14330 fail:
14331 do {
14332 wuffs_base__result_f64 ret;
14333 ret.status.repr = wuffs_base__error__bad_argument;
14334 ret.value = 0;
14335 return ret;
14336 } while (0);
14337 }
14338
14339 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
wuffs_base__private_implementation__high_prec_dec__to_f64(wuffs_base__private_implementation__high_prec_dec * h,uint32_t options)14340 wuffs_base__private_implementation__high_prec_dec__to_f64(
14341 wuffs_base__private_implementation__high_prec_dec* h,
14342 uint32_t options) {
14343 do {
14344 // powers converts decimal powers of 10 to binary powers of 2. For example,
14345 // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
14346 // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
14347 static const uint32_t num_powers = 19;
14348 static const uint8_t powers[19] = {
14349 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, //
14350 33, 36, 39, 43, 46, 49, 53, 56, 59, //
14351 };
14352
14353 // Handle zero and obvious extremes. The largest and smallest positive
14354 // finite f64 values are approximately 1.8e+308 and 4.9e-324.
14355 if ((h->num_digits == 0) || (h->decimal_point < -326)) {
14356 goto zero;
14357 } else if (h->decimal_point > 310) {
14358 goto infinity;
14359 }
14360
14361 // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10)
14362 // pair from the high_prec_dec h is more correct but slower than the
14363 // approach taken in wuffs_base__parse_number_f64. The latter is optimized
14364 // for the common cases (e.g. assuming no underscores or a leading '+'
14365 // sign) rather than the full set of cases allowed by the Wuffs API.
14366 if (h->num_digits <= 19) {
14367 uint64_t man = 0;
14368 uint32_t i;
14369 for (i = 0; i < h->num_digits; i++) {
14370 man = (10 * man) + h->digits[i];
14371 }
14372 int32_t exp10 = h->decimal_point - ((int32_t)(h->num_digits));
14373 if ((man != 0) && (-307 <= exp10) && (exp10 <= 288)) {
14374 int64_t r =
14375 wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14376 man, exp10);
14377 if (r >= 0) {
14378 wuffs_base__result_f64 ret;
14379 ret.status.repr = NULL;
14380 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14381 ((uint64_t)r) | (((uint64_t)(h->negative)) << 63));
14382 return ret;
14383 }
14384 }
14385 }
14386
14387 // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
14388 // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
14389 //
14390 // Scale by powers of 2 until we're in the range [½ .. 1], which gives us
14391 // our exponent (in base-2). First we shift right, possibly a little too
14392 // far, ending with a value certainly below 1 and possibly below ½...
14393 const int32_t f64_bias = -1023;
14394 int32_t exp2 = 0;
14395 while (h->decimal_point > 0) {
14396 uint32_t n = (uint32_t)(+h->decimal_point);
14397 uint32_t shift =
14398 (n < num_powers)
14399 ? powers[n]
14400 : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14401
14402 wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
14403 if (h->decimal_point <
14404 -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
14405 goto zero;
14406 }
14407 exp2 += (int32_t)shift;
14408 }
14409 // ...then we shift left, putting us in [½ .. 1].
14410 while (h->decimal_point <= 0) {
14411 uint32_t shift;
14412 if (h->decimal_point == 0) {
14413 if (h->digits[0] >= 5) {
14414 break;
14415 }
14416 shift = (h->digits[0] < 2) ? 2 : 1;
14417 } else {
14418 uint32_t n = (uint32_t)(-h->decimal_point);
14419 shift = (n < num_powers)
14420 ? powers[n]
14421 : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14422 }
14423
14424 wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
14425 if (h->decimal_point >
14426 +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
14427 goto infinity;
14428 }
14429 exp2 -= (int32_t)shift;
14430 }
14431
14432 // We're in the range [½ .. 1] but f64 uses [1 .. 2].
14433 exp2--;
14434
14435 // The minimum normal exponent is (f64_bias + 1).
14436 while ((f64_bias + 1) > exp2) {
14437 uint32_t n = (uint32_t)((f64_bias + 1) - exp2);
14438 if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
14439 n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
14440 }
14441 wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
14442 exp2 += (int32_t)n;
14443 }
14444
14445 // Check for overflow.
14446 if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
14447 goto infinity;
14448 }
14449
14450 // Extract 53 bits for the mantissa (in base-2).
14451 wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);
14452 uint64_t man2 =
14453 wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
14454
14455 // Rounding might have added one bit. If so, shift and re-check overflow.
14456 if ((man2 >> 53) != 0) {
14457 man2 >>= 1;
14458 exp2++;
14459 if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
14460 goto infinity;
14461 }
14462 }
14463
14464 // Handle subnormal numbers.
14465 if ((man2 >> 52) == 0) {
14466 exp2 = f64_bias;
14467 }
14468
14469 // Pack the bits and return.
14470 uint64_t exp2_bits =
14471 (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
14472 uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
14473 (exp2_bits << 52) | //
14474 (h->negative ? 0x8000000000000000 : 0); // (1 << 63).
14475
14476 wuffs_base__result_f64 ret;
14477 ret.status.repr = NULL;
14478 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14479 return ret;
14480 } while (0);
14481
14482 zero:
14483 do {
14484 uint64_t bits = h->negative ? 0x8000000000000000 : 0;
14485
14486 wuffs_base__result_f64 ret;
14487 ret.status.repr = NULL;
14488 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14489 return ret;
14490 } while (0);
14491
14492 infinity:
14493 do {
14494 if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
14495 wuffs_base__result_f64 ret;
14496 ret.status.repr = wuffs_base__error__bad_argument;
14497 ret.value = 0;
14498 return ret;
14499 }
14500
14501 uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
14502
14503 wuffs_base__result_f64 ret;
14504 ret.status.repr = NULL;
14505 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
14506 return ret;
14507 } while (0);
14508 }
14509
14510 static inline bool //
wuffs_base__private_implementation__is_decimal_digit(uint8_t c)14511 wuffs_base__private_implementation__is_decimal_digit(uint8_t c) {
14512 return ('0' <= c) && (c <= '9');
14513 }
14514
14515 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
wuffs_base__parse_number_f64(wuffs_base__slice_u8 s,uint32_t options)14516 wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {
14517 // In practice, almost all "dd.ddddE±xxx" numbers can be represented
14518 // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10
14519 // exponent, adjusting "xxx" for the position (if present) of the decimal
14520 // separator '.' or ','.
14521 //
14522 // This (u64 man, i32 exp10) data structure is superficially similar to the
14523 // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent
14524 // here is base-10, not base-2.
14525 //
14526 // If s's number fits in a (man, exp10), parse that pair with the
14527 // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with
14528 // the fallback algorithm is slower but comprehensive.
14529 //
14530 // † "Printing Floating-Point Numbers Quickly and Accurately with Integers"
14531 // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).
14532 // Florian Loitsch is also the primary contributor to
14533 // https://github.com/google/double-conversion
14534 do {
14535 // Calculating that (man, exp10) pair needs to stay within s's bounds.
14536 // Provided that s isn't extremely long, work on a NUL-terminated copy of
14537 // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx".
14538 //
14539 // As the pointer p walks the contents, it's faster to repeatedly check "is
14540 // *p a valid digit" than "is p within bounds and *p a valid digit".
14541 if (s.len >= 256) {
14542 goto fallback;
14543 }
14544 uint8_t z[256];
14545 memcpy(&z[0], s.ptr, s.len);
14546 z[s.len] = 0;
14547 const uint8_t* p = &z[0];
14548
14549 // Look for a leading minus sign. Technically, we could also look for an
14550 // optional plus sign, but the "script/process-json-numbers.c with -p"
14551 // benchmark is noticably slower if we do. It's optional and, in practice,
14552 // usually absent. Let the fallback catch it.
14553 bool negative = (*p == '-');
14554 if (negative) {
14555 p++;
14556 }
14557
14558 // After walking "dd.dddd", comparing p later with p now will produce the
14559 // number of "d"s and "."s.
14560 const uint8_t* const start_of_digits_ptr = p;
14561
14562 // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0',
14563 // it must be a single '0'. If it starts with a non-zero decimal digit, it
14564 // can be a sequence of decimal digits.
14565 //
14566 // Update the man variable during the walk. It's OK if man overflows now.
14567 // We'll detect that later.
14568 uint64_t man;
14569 if (*p == '0') {
14570 man = 0;
14571 p++;
14572 if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14573 goto fallback;
14574 }
14575 } else if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14576 man = ((uint8_t)(*p - '0'));
14577 p++;
14578 for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
14579 man = (10 * man) + ((uint8_t)(*p - '0'));
14580 }
14581 } else {
14582 goto fallback;
14583 }
14584
14585 // Walk the "d"s after the optional decimal separator ('.' or ','),
14586 // updating the man and exp10 variables.
14587 int32_t exp10 = 0;
14588 if (*p ==
14589 ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14590 ? ','
14591 : '.')) {
14592 p++;
14593 const uint8_t* first_after_separator_ptr = p;
14594 if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
14595 goto fallback;
14596 }
14597 man = (10 * man) + ((uint8_t)(*p - '0'));
14598 p++;
14599 for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
14600 man = (10 * man) + ((uint8_t)(*p - '0'));
14601 }
14602 exp10 = ((int32_t)(first_after_separator_ptr - p));
14603 }
14604
14605 // Count the number of digits:
14606 // - for an input of "314159", digit_count is 6.
14607 // - for an input of "3.14159", digit_count is 7.
14608 //
14609 // This is off-by-one if there is a decimal separator. That's OK for now.
14610 // We'll correct for that later. The "script/process-json-numbers.c with
14611 // -p" benchmark is noticably slower if we try to correct for that now.
14612 uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);
14613
14614 // Update exp10 for the optional exponent, starting with 'E' or 'e'.
14615 if ((*p | 0x20) == 'e') {
14616 p++;
14617 int32_t exp_sign = +1;
14618 if (*p == '-') {
14619 p++;
14620 exp_sign = -1;
14621 } else if (*p == '+') {
14622 p++;
14623 }
14624 if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
14625 goto fallback;
14626 }
14627 int32_t exp_num = ((uint8_t)(*p - '0'));
14628 p++;
14629 // The rest of the exp_num walking has a peculiar control flow but, once
14630 // again, the "script/process-json-numbers.c with -p" benchmark is
14631 // sensitive to alternative formulations.
14632 if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14633 exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14634 p++;
14635 }
14636 if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14637 exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14638 p++;
14639 }
14640 while (wuffs_base__private_implementation__is_decimal_digit(*p)) {
14641 if (exp_num > 0x1000000) {
14642 goto fallback;
14643 }
14644 exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
14645 p++;
14646 }
14647 exp10 += exp_sign * exp_num;
14648 }
14649
14650 // The Wuffs API is that the original slice has no trailing data. It also
14651 // allows underscores, which we don't catch here but the fallback should.
14652 if (p != &z[s.len]) {
14653 goto fallback;
14654 }
14655
14656 // Check that the uint64_t typed man variable has not overflowed, based on
14657 // digit_count.
14658 //
14659 // For reference:
14660 // - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
14661 // - (1 << 64) is 18446744073709551616, which has 20 decimal digits.
14662 // - 19 nines, 9999999999999999999, is 0x8AC7230489E7FFFF, which has 64
14663 // bits and 16 hexadecimal digits.
14664 // - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67
14665 // bits and 17 hexadecimal digits.
14666 if (digit_count > 19) {
14667 // Even if we have more than 19 pseudo-digits, it's not yet definitely an
14668 // overflow. Recall that digit_count might be off-by-one (too large) if
14669 // there's a decimal separator. It will also over-report the number of
14670 // meaningful digits if the input looks something like "0.000dddExxx".
14671 //
14672 // We adjust by the number of leading '0's and '.'s and re-compare to 19.
14673 // Once again, technically, we could skip ','s too, but that perturbs the
14674 // "script/process-json-numbers.c with -p" benchmark.
14675 const uint8_t* q = start_of_digits_ptr;
14676 for (; (*q == '0') || (*q == '.'); q++) {
14677 }
14678 digit_count -= (uint32_t)(q - start_of_digits_ptr);
14679 if (digit_count > 19) {
14680 goto fallback;
14681 }
14682 }
14683
14684 // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
14685 // preconditions include that exp10 is in the range [-307 ..= 288].
14686 if ((exp10 < -307) || (288 < exp10)) {
14687 goto fallback;
14688 }
14689
14690 // If both man and (10 ** exp10) are exactly representable by a double, we
14691 // don't need to run the Eisel-Lemire algorithm.
14692 if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {
14693 double d = (double)man;
14694 if (exp10 >= 0) {
14695 d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10];
14696 } else {
14697 d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];
14698 }
14699 wuffs_base__result_f64 ret;
14700 ret.status.repr = NULL;
14701 ret.value = negative ? -d : +d;
14702 return ret;
14703 }
14704
14705 // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
14706 // preconditions include that man is non-zero. Parsing "0" should be caught
14707 // by the "If both man and (10 ** exp10)" above, but "0e99" might not.
14708 if (man == 0) {
14709 goto fallback;
14710 }
14711
14712 // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.
14713 int64_t r =
14714 wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
14715 man, exp10);
14716 if (r < 0) {
14717 goto fallback;
14718 }
14719 wuffs_base__result_f64 ret;
14720 ret.status.repr = NULL;
14721 ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
14722 ((uint64_t)r) | (((uint64_t)negative) << 63));
14723 return ret;
14724 } while (0);
14725
14726 fallback:
14727 do {
14728 wuffs_base__private_implementation__high_prec_dec h;
14729 wuffs_base__status status =
14730 wuffs_base__private_implementation__high_prec_dec__parse(&h, s,
14731 options);
14732 if (status.repr) {
14733 return wuffs_base__private_implementation__parse_number_f64_special(
14734 s, options);
14735 }
14736 return wuffs_base__private_implementation__high_prec_dec__to_f64(&h,
14737 options);
14738 } while (0);
14739 }
14740
14741 // --------
14742
14743 static inline size_t //
wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,bool neg,uint32_t options)14744 wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,
14745 bool neg,
14746 uint32_t options) {
14747 if (neg) {
14748 if (dst.len < 4) {
14749 return 0;
14750 }
14751 wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D); // '-Inf'le.
14752 return 4;
14753 }
14754
14755 if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14756 if (dst.len < 4) {
14757 return 0;
14758 }
14759 wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B); // '+Inf'le.
14760 return 4;
14761 }
14762
14763 if (dst.len < 3) {
14764 return 0;
14765 }
14766 wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49); // 'Inf'le.
14767 return 3;
14768 }
14769
14770 static inline size_t //
wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst)14771 wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) {
14772 if (dst.len < 3) {
14773 return 0;
14774 }
14775 wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E); // 'NaN'le.
14776 return 3;
14777 }
14778
14779 static size_t //
wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(wuffs_base__slice_u8 dst,wuffs_base__private_implementation__high_prec_dec * h,uint32_t precision,uint32_t options)14780 wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
14781 wuffs_base__slice_u8 dst,
14782 wuffs_base__private_implementation__high_prec_dec* h,
14783 uint32_t precision,
14784 uint32_t options) {
14785 size_t n = (h->negative ||
14786 (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
14787 ? 1
14788 : 0;
14789 if (h->decimal_point <= 0) {
14790 n += 1;
14791 } else {
14792 n += (size_t)(h->decimal_point);
14793 }
14794 if (precision > 0) {
14795 n += precision + 1; // +1 for the '.'.
14796 }
14797
14798 // Don't modify dst if the formatted number won't fit.
14799 if (n > dst.len) {
14800 return 0;
14801 }
14802
14803 // Align-left or align-right.
14804 uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
14805 ? &dst.ptr[dst.len - n]
14806 : &dst.ptr[0];
14807
14808 // Leading "±".
14809 if (h->negative) {
14810 *ptr++ = '-';
14811 } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14812 *ptr++ = '+';
14813 }
14814
14815 // Integral digits.
14816 if (h->decimal_point <= 0) {
14817 *ptr++ = '0';
14818 } else {
14819 uint32_t m =
14820 wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point));
14821 uint32_t i = 0;
14822 for (; i < m; i++) {
14823 *ptr++ = (uint8_t)('0' | h->digits[i]);
14824 }
14825 for (; i < (uint32_t)(h->decimal_point); i++) {
14826 *ptr++ = '0';
14827 }
14828 }
14829
14830 // Separator and then fractional digits.
14831 if (precision > 0) {
14832 *ptr++ =
14833 (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14834 ? ','
14835 : '.';
14836 uint32_t i = 0;
14837 for (; i < precision; i++) {
14838 uint32_t j = ((uint32_t)(h->decimal_point)) + i;
14839 *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0));
14840 }
14841 }
14842
14843 return n;
14844 }
14845
14846 static size_t //
wuffs_base__private_implementation__high_prec_dec__render_exponent_present(wuffs_base__slice_u8 dst,wuffs_base__private_implementation__high_prec_dec * h,uint32_t precision,uint32_t options)14847 wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
14848 wuffs_base__slice_u8 dst,
14849 wuffs_base__private_implementation__high_prec_dec* h,
14850 uint32_t precision,
14851 uint32_t options) {
14852 int32_t exp = 0;
14853 if (h->num_digits > 0) {
14854 exp = h->decimal_point - 1;
14855 }
14856 bool negative_exp = exp < 0;
14857 if (negative_exp) {
14858 exp = -exp;
14859 }
14860
14861 size_t n = (h->negative ||
14862 (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
14863 ? 4
14864 : 3; // Mininum 3 bytes: first digit and then "e±".
14865 if (precision > 0) {
14866 n += precision + 1; // +1 for the '.'.
14867 }
14868 n += (exp < 100) ? 2 : 3;
14869
14870 // Don't modify dst if the formatted number won't fit.
14871 if (n > dst.len) {
14872 return 0;
14873 }
14874
14875 // Align-left or align-right.
14876 uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
14877 ? &dst.ptr[dst.len - n]
14878 : &dst.ptr[0];
14879
14880 // Leading "±".
14881 if (h->negative) {
14882 *ptr++ = '-';
14883 } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
14884 *ptr++ = '+';
14885 }
14886
14887 // Integral digit.
14888 if (h->num_digits > 0) {
14889 *ptr++ = (uint8_t)('0' | h->digits[0]);
14890 } else {
14891 *ptr++ = '0';
14892 }
14893
14894 // Separator and then fractional digits.
14895 if (precision > 0) {
14896 *ptr++ =
14897 (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
14898 ? ','
14899 : '.';
14900 uint32_t i = 1;
14901 uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1);
14902 for (; i < j; i++) {
14903 *ptr++ = (uint8_t)('0' | h->digits[i]);
14904 }
14905 for (; i <= precision; i++) {
14906 *ptr++ = '0';
14907 }
14908 }
14909
14910 // Exponent: "e±" and then 2 or 3 digits.
14911 *ptr++ = 'e';
14912 *ptr++ = negative_exp ? '-' : '+';
14913 if (exp < 10) {
14914 *ptr++ = '0';
14915 *ptr++ = (uint8_t)('0' | exp);
14916 } else if (exp < 100) {
14917 *ptr++ = (uint8_t)('0' | (exp / 10));
14918 *ptr++ = (uint8_t)('0' | (exp % 10));
14919 } else {
14920 int32_t e = exp / 100;
14921 exp -= e * 100;
14922 *ptr++ = (uint8_t)('0' | e);
14923 *ptr++ = (uint8_t)('0' | (exp / 10));
14924 *ptr++ = (uint8_t)('0' | (exp % 10));
14925 }
14926
14927 return n;
14928 }
14929
14930 WUFFS_BASE__MAYBE_STATIC size_t //
wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,double x,uint32_t precision,uint32_t options)14931 wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
14932 double x,
14933 uint32_t precision,
14934 uint32_t options) {
14935 // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits
14936 // with a -1023 bias) and mantissa (52 bits).
14937 uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x);
14938 bool neg = (bits >> 63) != 0;
14939 int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF;
14940 uint64_t man = bits & 0x000FFFFFFFFFFFFFul;
14941
14942 // Apply the exponent bias and set the implicit top bit of the mantissa,
14943 // unless x is subnormal. Also take care of Inf and NaN.
14944 if (exp2 == 0x7FF) {
14945 if (man != 0) {
14946 return wuffs_base__private_implementation__render_nan(dst);
14947 }
14948 return wuffs_base__private_implementation__render_inf(dst, neg, options);
14949 } else if (exp2 == 0) {
14950 exp2 = -1022;
14951 } else {
14952 exp2 -= 1023;
14953 man |= 0x0010000000000000ul;
14954 }
14955
14956 // Ensure that precision isn't too large.
14957 if (precision > 4095) {
14958 precision = 4095;
14959 }
14960
14961 // Convert from the (neg, exp2, man) tuple to an HPD.
14962 wuffs_base__private_implementation__high_prec_dec h;
14963 wuffs_base__private_implementation__high_prec_dec__assign(&h, man, neg);
14964 if (h.num_digits > 0) {
14965 wuffs_base__private_implementation__high_prec_dec__lshift(
14966 &h, exp2 - 52); // 52 mantissa bits.
14967 }
14968
14969 // Handle the "%e" and "%f" formats.
14970 switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT |
14971 WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) {
14972 case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT: // The "%"f" format.
14973 if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
14974 wuffs_base__private_implementation__high_prec_dec__round_just_enough(
14975 &h, exp2, man);
14976 int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point;
14977 precision = ((uint32_t)(wuffs_base__i32__max(0, p)));
14978 } else {
14979 wuffs_base__private_implementation__high_prec_dec__round_nearest(
14980 &h, ((int32_t)precision) + h.decimal_point);
14981 }
14982 return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
14983 dst, &h, precision, options);
14984
14985 case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT: // The "%e" format.
14986 if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
14987 wuffs_base__private_implementation__high_prec_dec__round_just_enough(
14988 &h, exp2, man);
14989 precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0;
14990 } else {
14991 wuffs_base__private_implementation__high_prec_dec__round_nearest(
14992 &h, ((int32_t)precision) + 1);
14993 }
14994 return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
14995 dst, &h, precision, options);
14996 }
14997
14998 // We have the "%g" format and so precision means the number of significant
14999 // digits, not the number of digits after the decimal separator. Perform
15000 // rounding and determine whether to use "%e" or "%f".
15001 int32_t e_threshold = 0;
15002 if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
15003 wuffs_base__private_implementation__high_prec_dec__round_just_enough(
15004 &h, exp2, man);
15005 precision = h.num_digits;
15006 e_threshold = 6;
15007 } else {
15008 if (precision == 0) {
15009 precision = 1;
15010 }
15011 wuffs_base__private_implementation__high_prec_dec__round_nearest(
15012 &h, ((int32_t)precision));
15013 e_threshold = ((int32_t)precision);
15014 int32_t nd = ((int32_t)(h.num_digits));
15015 if ((e_threshold > nd) && (nd >= h.decimal_point)) {
15016 e_threshold = nd;
15017 }
15018 }
15019
15020 // Use the "%e" format if the exponent is large.
15021 int32_t e = h.decimal_point - 1;
15022 if ((e < -4) || (e_threshold <= e)) {
15023 uint32_t p = wuffs_base__u32__min(precision, h.num_digits);
15024 return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
15025 dst, &h, (p > 0) ? (p - 1) : 0, options);
15026 }
15027
15028 // Use the "%f" format otherwise.
15029 int32_t p = ((int32_t)precision);
15030 if (p > h.decimal_point) {
15031 p = ((int32_t)(h.num_digits));
15032 }
15033 precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point)));
15034 return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
15035 dst, &h, precision, options);
15036 }
15037
15038 #endif // !defined(WUFFS_CONFIG__MODULES) ||
15039 // defined(WUFFS_CONFIG__MODULE__BASE) ||
15040 // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
15041
15042 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
15043 defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
15044
15045 // ---------------- Integer
15046
15047 // wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits,
15048 // and (0x80 | v) for valid digits, where v is the 4 bit value.
15049
15050 static const uint8_t wuffs_base__parse_number__decimal_digits[256] = {
15051 // 0 1 2 3 4 5 6 7
15052 // 8 9 A B C D E F
15053 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
15054 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
15055 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
15056 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
15057 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
15058 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
15059 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
15060 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
15061
15062 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
15063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
15064 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
15065 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
15066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
15067 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
15068 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
15069 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
15070
15071 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
15072 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
15073 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
15074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
15075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
15076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
15077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
15078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
15079
15080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
15081 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
15082 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
15083 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
15084 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
15085 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
15086 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
15087 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
15088 // 0 1 2 3 4 5 6 7
15089 // 8 9 A B C D E F
15090 };
15091
15092 static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = {
15093 // 0 1 2 3 4 5 6 7
15094 // 8 9 A B C D E F
15095 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
15096 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
15097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
15098 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
15099 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
15100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
15101 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
15102 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
15103
15104 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x40 ..= 0x47. 'A'-'F'.
15105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
15106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
15107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
15108 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x60 ..= 0x67. 'a'-'f'.
15109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
15110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
15111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
15112
15113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
15114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
15115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
15116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
15117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
15118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
15119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
15120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
15121
15122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
15123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
15124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
15125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
15126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
15127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
15128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
15129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
15130 // 0 1 2 3 4 5 6 7
15131 // 8 9 A B C D E F
15132 };
15133
15134 static const uint8_t wuffs_base__private_implementation__encode_base16[16] = {
15135 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x00 ..= 0x07.
15136 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, // 0x08 ..= 0x0F.
15137 };
15138
15139 // --------
15140
15141 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
wuffs_base__parse_number_i64(wuffs_base__slice_u8 s,uint32_t options)15142 wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) {
15143 uint8_t* p = s.ptr;
15144 uint8_t* q = s.ptr + s.len;
15145
15146 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15147 for (; (p < q) && (*p == '_'); p++) {
15148 }
15149 }
15150
15151 bool negative = false;
15152 if (p >= q) {
15153 goto fail_bad_argument;
15154 } else if (*p == '-') {
15155 p++;
15156 negative = true;
15157 } else if (*p == '+') {
15158 p++;
15159 }
15160
15161 do {
15162 wuffs_base__result_u64 r = wuffs_base__parse_number_u64(
15163 wuffs_base__make_slice_u8(p, (size_t)(q - p)), options);
15164 if (r.status.repr != NULL) {
15165 wuffs_base__result_i64 ret;
15166 ret.status.repr = r.status.repr;
15167 ret.value = 0;
15168 return ret;
15169 } else if (negative) {
15170 if (r.value < 0x8000000000000000) {
15171 wuffs_base__result_i64 ret;
15172 ret.status.repr = NULL;
15173 ret.value = -(int64_t)(r.value);
15174 return ret;
15175 } else if (r.value == 0x8000000000000000) {
15176 wuffs_base__result_i64 ret;
15177 ret.status.repr = NULL;
15178 ret.value = INT64_MIN;
15179 return ret;
15180 }
15181 goto fail_out_of_bounds;
15182 } else if (r.value > 0x7FFFFFFFFFFFFFFF) {
15183 goto fail_out_of_bounds;
15184 } else {
15185 wuffs_base__result_i64 ret;
15186 ret.status.repr = NULL;
15187 ret.value = +(int64_t)(r.value);
15188 return ret;
15189 }
15190 } while (0);
15191
15192 fail_bad_argument:
15193 do {
15194 wuffs_base__result_i64 ret;
15195 ret.status.repr = wuffs_base__error__bad_argument;
15196 ret.value = 0;
15197 return ret;
15198 } while (0);
15199
15200 fail_out_of_bounds:
15201 do {
15202 wuffs_base__result_i64 ret;
15203 ret.status.repr = wuffs_base__error__out_of_bounds;
15204 ret.value = 0;
15205 return ret;
15206 } while (0);
15207 }
15208
15209 WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
wuffs_base__parse_number_u64(wuffs_base__slice_u8 s,uint32_t options)15210 wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) {
15211 uint8_t* p = s.ptr;
15212 uint8_t* q = s.ptr + s.len;
15213
15214 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15215 for (; (p < q) && (*p == '_'); p++) {
15216 }
15217 }
15218
15219 if (p >= q) {
15220 goto fail_bad_argument;
15221
15222 } else if (*p == '0') {
15223 p++;
15224 if (p >= q) {
15225 goto ok_zero;
15226 }
15227 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15228 if (*p == '_') {
15229 p++;
15230 for (; p < q; p++) {
15231 if (*p != '_') {
15232 if (options &
15233 WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
15234 goto decimal;
15235 }
15236 goto fail_bad_argument;
15237 }
15238 }
15239 goto ok_zero;
15240 }
15241 }
15242
15243 if ((*p == 'x') || (*p == 'X')) {
15244 p++;
15245 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15246 for (; (p < q) && (*p == '_'); p++) {
15247 }
15248 }
15249 if (p < q) {
15250 goto hexadecimal;
15251 }
15252
15253 } else if ((*p == 'd') || (*p == 'D')) {
15254 p++;
15255 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
15256 for (; (p < q) && (*p == '_'); p++) {
15257 }
15258 }
15259 if (p < q) {
15260 goto decimal;
15261 }
15262 }
15263
15264 if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
15265 goto decimal;
15266 }
15267 goto fail_bad_argument;
15268 }
15269
15270 decimal:
15271 do {
15272 uint64_t v = wuffs_base__parse_number__decimal_digits[*p++];
15273 if (v == 0) {
15274 goto fail_bad_argument;
15275 }
15276 v &= 0x0F;
15277
15278 // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1).
15279 const uint64_t max10 = 1844674407370955161u;
15280 const uint8_t max1 = 5;
15281
15282 for (; p < q; p++) {
15283 if ((*p == '_') &&
15284 (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
15285 continue;
15286 }
15287 uint8_t digit = wuffs_base__parse_number__decimal_digits[*p];
15288 if (digit == 0) {
15289 goto fail_bad_argument;
15290 }
15291 digit &= 0x0F;
15292 if ((v > max10) || ((v == max10) && (digit > max1))) {
15293 goto fail_out_of_bounds;
15294 }
15295 v = (10 * v) + ((uint64_t)(digit));
15296 }
15297
15298 wuffs_base__result_u64 ret;
15299 ret.status.repr = NULL;
15300 ret.value = v;
15301 return ret;
15302 } while (0);
15303
15304 hexadecimal:
15305 do {
15306 uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++];
15307 if (v == 0) {
15308 goto fail_bad_argument;
15309 }
15310 v &= 0x0F;
15311
15312 for (; p < q; p++) {
15313 if ((*p == '_') &&
15314 (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
15315 continue;
15316 }
15317 uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p];
15318 if (digit == 0) {
15319 goto fail_bad_argument;
15320 }
15321 digit &= 0x0F;
15322 if ((v >> 60) != 0) {
15323 goto fail_out_of_bounds;
15324 }
15325 v = (v << 4) | ((uint64_t)(digit));
15326 }
15327
15328 wuffs_base__result_u64 ret;
15329 ret.status.repr = NULL;
15330 ret.value = v;
15331 return ret;
15332 } while (0);
15333
15334 ok_zero:
15335 do {
15336 wuffs_base__result_u64 ret;
15337 ret.status.repr = NULL;
15338 ret.value = 0;
15339 return ret;
15340 } while (0);
15341
15342 fail_bad_argument:
15343 do {
15344 wuffs_base__result_u64 ret;
15345 ret.status.repr = wuffs_base__error__bad_argument;
15346 ret.value = 0;
15347 return ret;
15348 } while (0);
15349
15350 fail_out_of_bounds:
15351 do {
15352 wuffs_base__result_u64 ret;
15353 ret.status.repr = wuffs_base__error__out_of_bounds;
15354 ret.value = 0;
15355 return ret;
15356 } while (0);
15357 }
15358
15359 // --------
15360
15361 // wuffs_base__render_number__first_hundred contains the decimal encodings of
15362 // the first one hundred numbers [0 ..= 99].
15363 static const uint8_t wuffs_base__render_number__first_hundred[200] = {
15364 '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', //
15365 '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', //
15366 '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', //
15367 '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', //
15368 '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', //
15369 '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', //
15370 '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', //
15371 '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', //
15372 '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', //
15373 '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', //
15374 '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', //
15375 '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', //
15376 '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', //
15377 '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', //
15378 '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', //
15379 '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', //
15380 '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', //
15381 '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', //
15382 '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', //
15383 '9', '5', '9', '6', '9', '7', '9', '8', '9', '9', //
15384 };
15385
15386 static size_t //
wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options,bool neg)15387 wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,
15388 uint64_t x,
15389 uint32_t options,
15390 bool neg) {
15391 uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL];
15392 uint8_t* ptr = &buf[0] + sizeof(buf);
15393
15394 while (x >= 100) {
15395 size_t index = ((size_t)((x % 100) * 2));
15396 x /= 100;
15397 uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
15398 uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
15399 ptr -= 2;
15400 ptr[0] = s0;
15401 ptr[1] = s1;
15402 }
15403
15404 if (x < 10) {
15405 ptr -= 1;
15406 ptr[0] = (uint8_t)('0' + x);
15407 } else {
15408 size_t index = ((size_t)(x * 2));
15409 uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
15410 uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
15411 ptr -= 2;
15412 ptr[0] = s0;
15413 ptr[1] = s1;
15414 }
15415
15416 if (neg) {
15417 ptr -= 1;
15418 ptr[0] = '-';
15419 } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
15420 ptr -= 1;
15421 ptr[0] = '+';
15422 }
15423
15424 size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0]));
15425 if (n > dst.len) {
15426 return 0;
15427 }
15428 memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
15429 ? (dst.len - n)
15430 : 0),
15431 ptr, n);
15432 return n;
15433 }
15434
15435 WUFFS_BASE__MAYBE_STATIC size_t //
wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,int64_t x,uint32_t options)15436 wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
15437 int64_t x,
15438 uint32_t options) {
15439 uint64_t u = (uint64_t)x;
15440 bool neg = x < 0;
15441 if (neg) {
15442 u = 1 + ~u;
15443 }
15444 return wuffs_base__private_implementation__render_number_u64(dst, u, options,
15445 neg);
15446 }
15447
15448 WUFFS_BASE__MAYBE_STATIC size_t //
wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,uint64_t x,uint32_t options)15449 wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
15450 uint64_t x,
15451 uint32_t options) {
15452 return wuffs_base__private_implementation__render_number_u64(dst, x, options,
15453 false);
15454 }
15455
15456 // ---------------- Base-16
15457
15458 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)15459 wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
15460 wuffs_base__slice_u8 src,
15461 bool src_closed,
15462 uint32_t options) {
15463 wuffs_base__transform__output o;
15464 size_t src_len2 = src.len / 2;
15465 size_t len;
15466 if (dst.len < src_len2) {
15467 len = dst.len;
15468 o.status.repr = wuffs_base__suspension__short_write;
15469 } else {
15470 len = src_len2;
15471 if (!src_closed) {
15472 o.status.repr = wuffs_base__suspension__short_read;
15473 } else if (src.len & 1) {
15474 o.status.repr = wuffs_base__error__bad_data;
15475 } else {
15476 o.status.repr = NULL;
15477 }
15478 }
15479
15480 uint8_t* d = dst.ptr;
15481 uint8_t* s = src.ptr;
15482 size_t n = len;
15483
15484 while (n--) {
15485 *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
15486 (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F));
15487 d += 1;
15488 s += 2;
15489 }
15490
15491 o.num_dst = len;
15492 o.num_src = len * 2;
15493 return o;
15494 }
15495
15496 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)15497 wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
15498 wuffs_base__slice_u8 src,
15499 bool src_closed,
15500 uint32_t options) {
15501 wuffs_base__transform__output o;
15502 size_t src_len4 = src.len / 4;
15503 size_t len = dst.len < src_len4 ? dst.len : src_len4;
15504 if (dst.len < src_len4) {
15505 len = dst.len;
15506 o.status.repr = wuffs_base__suspension__short_write;
15507 } else {
15508 len = src_len4;
15509 if (!src_closed) {
15510 o.status.repr = wuffs_base__suspension__short_read;
15511 } else if (src.len & 1) {
15512 o.status.repr = wuffs_base__error__bad_data;
15513 } else {
15514 o.status.repr = NULL;
15515 }
15516 }
15517
15518 uint8_t* d = dst.ptr;
15519 uint8_t* s = src.ptr;
15520 size_t n = len;
15521
15522 while (n--) {
15523 *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
15524 (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F));
15525 d += 1;
15526 s += 4;
15527 }
15528
15529 o.num_dst = len;
15530 o.num_src = len * 4;
15531 return o;
15532 }
15533
15534 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)15535 wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
15536 wuffs_base__slice_u8 src,
15537 bool src_closed,
15538 uint32_t options) {
15539 wuffs_base__transform__output o;
15540 size_t dst_len2 = dst.len / 2;
15541 size_t len;
15542 if (dst_len2 < src.len) {
15543 len = dst_len2;
15544 o.status.repr = wuffs_base__suspension__short_write;
15545 } else {
15546 len = src.len;
15547 if (!src_closed) {
15548 o.status.repr = wuffs_base__suspension__short_read;
15549 } else {
15550 o.status.repr = NULL;
15551 }
15552 }
15553
15554 uint8_t* d = dst.ptr;
15555 uint8_t* s = src.ptr;
15556 size_t n = len;
15557
15558 while (n--) {
15559 uint8_t c = *s;
15560 d[0] = wuffs_base__private_implementation__encode_base16[c >> 4];
15561 d[1] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
15562 d += 2;
15563 s += 1;
15564 }
15565
15566 o.num_dst = len * 2;
15567 o.num_src = len;
15568 return o;
15569 }
15570
15571 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)15572 wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
15573 wuffs_base__slice_u8 src,
15574 bool src_closed,
15575 uint32_t options) {
15576 wuffs_base__transform__output o;
15577 size_t dst_len4 = dst.len / 4;
15578 size_t len;
15579 if (dst_len4 < src.len) {
15580 len = dst_len4;
15581 o.status.repr = wuffs_base__suspension__short_write;
15582 } else {
15583 len = src.len;
15584 if (!src_closed) {
15585 o.status.repr = wuffs_base__suspension__short_read;
15586 } else {
15587 o.status.repr = NULL;
15588 }
15589 }
15590
15591 uint8_t* d = dst.ptr;
15592 uint8_t* s = src.ptr;
15593 size_t n = len;
15594
15595 while (n--) {
15596 uint8_t c = *s;
15597 d[0] = '\\';
15598 d[1] = 'x';
15599 d[2] = wuffs_base__private_implementation__encode_base16[c >> 4];
15600 d[3] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
15601 d += 4;
15602 s += 1;
15603 }
15604
15605 o.num_dst = len * 4;
15606 o.num_src = len;
15607 return o;
15608 }
15609
15610 // ---------------- Base-64
15611
15612 // The two base-64 alphabets, std and url, differ only in the last two codes.
15613 // - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
15614 // - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
15615
15616 static const uint8_t wuffs_base__base_64__decode_std[256] = {
15617 // 0 1 2 3 4 5 6 7
15618 // 8 9 A B C D E F
15619 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07.
15620 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F.
15621 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17.
15622 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F.
15623 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27.
15624 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, // 0x28 ..= 0x2F.
15625 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37.
15626 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F.
15627
15628 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47.
15629 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F.
15630 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57.
15631 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x58 ..= 0x5F.
15632 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67.
15633 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F.
15634 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77.
15635 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F.
15636
15637 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87.
15638 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F.
15639 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97.
15640 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F.
15641 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7.
15642 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF.
15643 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7.
15644 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF.
15645
15646 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7.
15647 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF.
15648 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7.
15649 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF.
15650 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7.
15651 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF.
15652 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
15653 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
15654 // 0 1 2 3 4 5 6 7
15655 // 8 9 A B C D E F
15656 };
15657
15658 static const uint8_t wuffs_base__base_64__decode_url[256] = {
15659 // 0 1 2 3 4 5 6 7
15660 // 8 9 A B C D E F
15661 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07.
15662 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F.
15663 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17.
15664 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F.
15665 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27.
15666 0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, // 0x28 ..= 0x2F.
15667 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37.
15668 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F.
15669
15670 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47.
15671 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F.
15672 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57.
15673 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F, // 0x58 ..= 0x5F.
15674 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67.
15675 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F.
15676 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77.
15677 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F.
15678
15679 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87.
15680 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F.
15681 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97.
15682 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F.
15683 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7.
15684 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF.
15685 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7.
15686 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF.
15687
15688 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7.
15689 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF.
15690 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7.
15691 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF.
15692 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7.
15693 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF.
15694 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
15695 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
15696 // 0 1 2 3 4 5 6 7
15697 // 8 9 A B C D E F
15698 };
15699
15700 static const uint8_t wuffs_base__base_64__encode_std[64] = {
15701 // 0 1 2 3 4 5 6 7
15702 // 8 9 A B C D E F
15703 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07.
15704 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F.
15705 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17.
15706 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F.
15707 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27.
15708 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F.
15709 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37.
15710 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F, // 0x38 ..= 0x3F.
15711 };
15712
15713 static const uint8_t wuffs_base__base_64__encode_url[64] = {
15714 // 0 1 2 3 4 5 6 7
15715 // 8 9 A B C D E F
15716 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07.
15717 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F.
15718 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17.
15719 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F.
15720 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27.
15721 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F.
15722 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37.
15723 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F, // 0x38 ..= 0x3F.
15724 };
15725
15726 // --------
15727
15728 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)15729 wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
15730 wuffs_base__slice_u8 src,
15731 bool src_closed,
15732 uint32_t options) {
15733 const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
15734 ? wuffs_base__base_64__decode_url
15735 : wuffs_base__base_64__decode_std;
15736 wuffs_base__transform__output o;
15737 uint8_t* d_ptr = dst.ptr;
15738 size_t d_len = dst.len;
15739 const uint8_t* s_ptr = src.ptr;
15740 size_t s_len = src.len;
15741 bool pad = false;
15742
15743 while (s_len >= 4) {
15744 uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
15745 uint32_t s0 = alphabet[0xFF & (s >> 0)];
15746 uint32_t s1 = alphabet[0xFF & (s >> 8)];
15747 uint32_t s2 = alphabet[0xFF & (s >> 16)];
15748 uint32_t s3 = alphabet[0xFF & (s >> 24)];
15749
15750 if (((s0 | s1 | s2 | s3) & 0xC0) != 0) {
15751 if (s_len > 4) {
15752 o.status.repr = wuffs_base__error__bad_data;
15753 goto done;
15754 } else if (!src_closed) {
15755 o.status.repr = wuffs_base__suspension__short_read;
15756 goto done;
15757 } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) &&
15758 (s_ptr[3] == '=')) {
15759 pad = true;
15760 if (s_ptr[2] == '=') {
15761 goto src2;
15762 }
15763 goto src3;
15764 }
15765 o.status.repr = wuffs_base__error__bad_data;
15766 goto done;
15767 }
15768
15769 if (d_len < 3) {
15770 o.status.repr = wuffs_base__suspension__short_write;
15771 goto done;
15772 }
15773
15774 s_ptr += 4;
15775 s_len -= 4;
15776 s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0);
15777 *d_ptr++ = (uint8_t)(s >> 16);
15778 *d_ptr++ = (uint8_t)(s >> 8);
15779 *d_ptr++ = (uint8_t)(s >> 0);
15780 d_len -= 3;
15781 }
15782
15783 if (!src_closed) {
15784 o.status.repr = wuffs_base__suspension__short_read;
15785 goto done;
15786 }
15787
15788 if (s_len == 0) {
15789 o.status.repr = NULL;
15790 goto done;
15791 } else if (s_len == 1) {
15792 o.status.repr = wuffs_base__error__bad_data;
15793 goto done;
15794 } else if (s_len == 2) {
15795 goto src2;
15796 }
15797
15798 src3:
15799 do {
15800 uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
15801 uint32_t s0 = alphabet[0xFF & (s >> 0)];
15802 uint32_t s1 = alphabet[0xFF & (s >> 8)];
15803 uint32_t s2 = alphabet[0xFF & (s >> 16)];
15804 if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) {
15805 o.status.repr = wuffs_base__error__bad_data;
15806 goto done;
15807 }
15808 if (d_len < 2) {
15809 o.status.repr = wuffs_base__suspension__short_write;
15810 goto done;
15811 }
15812 s_ptr += pad ? 4 : 3;
15813 s = (s0 << 18) | (s1 << 12) | (s2 << 6);
15814 *d_ptr++ = (uint8_t)(s >> 16);
15815 *d_ptr++ = (uint8_t)(s >> 8);
15816 o.status.repr = NULL;
15817 goto done;
15818 } while (0);
15819
15820 src2:
15821 do {
15822 uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
15823 uint32_t s0 = alphabet[0xFF & (s >> 0)];
15824 uint32_t s1 = alphabet[0xFF & (s >> 8)];
15825 if ((s0 & 0xC0) || (s1 & 0xCF)) {
15826 o.status.repr = wuffs_base__error__bad_data;
15827 goto done;
15828 }
15829 if (d_len < 1) {
15830 o.status.repr = wuffs_base__suspension__short_write;
15831 goto done;
15832 }
15833 s_ptr += pad ? 4 : 2;
15834 s = (s0 << 18) | (s1 << 12);
15835 *d_ptr++ = (uint8_t)(s >> 16);
15836 o.status.repr = NULL;
15837 goto done;
15838 } while (0);
15839
15840 done:
15841 o.num_dst = (size_t)(d_ptr - dst.ptr);
15842 o.num_src = (size_t)(s_ptr - src.ptr);
15843 return o;
15844 }
15845
15846 WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,wuffs_base__slice_u8 src,bool src_closed,uint32_t options)15847 wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
15848 wuffs_base__slice_u8 src,
15849 bool src_closed,
15850 uint32_t options) {
15851 const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
15852 ? wuffs_base__base_64__encode_url
15853 : wuffs_base__base_64__encode_std;
15854 wuffs_base__transform__output o;
15855 uint8_t* d_ptr = dst.ptr;
15856 size_t d_len = dst.len;
15857 const uint8_t* s_ptr = src.ptr;
15858 size_t s_len = src.len;
15859
15860 do {
15861 while (s_len >= 3) {
15862 if (d_len < 4) {
15863 o.status.repr = wuffs_base__suspension__short_write;
15864 goto done;
15865 }
15866 uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr);
15867 s_ptr += 3;
15868 s_len -= 3;
15869 *d_ptr++ = alphabet[0x3F & (s >> 18)];
15870 *d_ptr++ = alphabet[0x3F & (s >> 12)];
15871 *d_ptr++ = alphabet[0x3F & (s >> 6)];
15872 *d_ptr++ = alphabet[0x3F & (s >> 0)];
15873 d_len -= 4;
15874 }
15875
15876 if (!src_closed) {
15877 o.status.repr = wuffs_base__suspension__short_read;
15878 goto done;
15879 }
15880
15881 if (s_len == 2) {
15882 if (d_len <
15883 ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) {
15884 o.status.repr = wuffs_base__suspension__short_write;
15885 goto done;
15886 }
15887 uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr)))
15888 << 8;
15889 s_ptr += 2;
15890 *d_ptr++ = alphabet[0x3F & (s >> 18)];
15891 *d_ptr++ = alphabet[0x3F & (s >> 12)];
15892 *d_ptr++ = alphabet[0x3F & (s >> 6)];
15893 if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
15894 *d_ptr++ = '=';
15895 }
15896 o.status.repr = NULL;
15897 goto done;
15898
15899 } else if (s_len == 1) {
15900 if (d_len <
15901 ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) {
15902 o.status.repr = wuffs_base__suspension__short_write;
15903 goto done;
15904 }
15905 uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr)))
15906 << 16;
15907 s_ptr += 1;
15908 *d_ptr++ = alphabet[0x3F & (s >> 18)];
15909 *d_ptr++ = alphabet[0x3F & (s >> 12)];
15910 if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
15911 *d_ptr++ = '=';
15912 *d_ptr++ = '=';
15913 }
15914 o.status.repr = NULL;
15915 goto done;
15916
15917 } else {
15918 o.status.repr = NULL;
15919 goto done;
15920 }
15921 } while (0);
15922
15923 done:
15924 o.num_dst = (size_t)(d_ptr - dst.ptr);
15925 o.num_src = (size_t)(s_ptr - src.ptr);
15926 return o;
15927 }
15928
15929 #endif // !defined(WUFFS_CONFIG__MODULES) ||
15930 // defined(WUFFS_CONFIG__MODULE__BASE) ||
15931 // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
15932
15933 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
15934 defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
15935
15936 // ---------------- Magic Numbers
15937
15938 // ICO doesn't start with a magic identifier. Instead, see if the opening bytes
15939 // are plausibly ICO.
15940 //
15941 // Callers should have already verified that (prefix_data.len >= 2) and the
15942 // first two bytes are 0x00.
15943 //
15944 // See:
15945 // - https://docs.fileformat.com/image/ico/
15946 static int32_t //
wuffs_base__magic_number_guess_fourcc__maybe_ico(wuffs_base__slice_u8 prefix_data,bool prefix_closed)15947 wuffs_base__magic_number_guess_fourcc__maybe_ico(
15948 wuffs_base__slice_u8 prefix_data,
15949 bool prefix_closed) {
15950 // Allow-list for the Image Type field.
15951 if (prefix_data.len < 4) {
15952 return prefix_closed ? 0 : -1;
15953 } else if (prefix_data.ptr[3] != 0) {
15954 return 0;
15955 }
15956 switch (prefix_data.ptr[2]) {
15957 case 0x01: // ICO
15958 case 0x02: // CUR
15959 break;
15960 default:
15961 return 0;
15962 }
15963
15964 // The Number Of Images should be positive.
15965 if (prefix_data.len < 6) {
15966 return prefix_closed ? 0 : -1;
15967 } else if ((prefix_data.ptr[4] == 0) && (prefix_data.ptr[5] == 0)) {
15968 return 0;
15969 }
15970
15971 // The first ICONDIRENTRY's fourth byte should be zero.
15972 if (prefix_data.len < 10) {
15973 return prefix_closed ? 0 : -1;
15974 } else if (prefix_data.ptr[9] != 0) {
15975 return 0;
15976 }
15977
15978 // TODO: have a separate FourCC for CUR?
15979 return 0x49434F20; // 'ICO 'be
15980 }
15981
15982 // TGA doesn't start with a magic identifier. Instead, see if the opening bytes
15983 // are plausibly TGA.
15984 //
15985 // Callers should have already verified that (prefix_data.len >= 2) and the
15986 // second byte (prefix_data.ptr[1], the Color Map Type byte), is either 0x00 or
15987 // 0x01.
15988 //
15989 // See:
15990 // - https://docs.fileformat.com/image/tga/
15991 // - https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
15992 static int32_t //
wuffs_base__magic_number_guess_fourcc__maybe_tga(wuffs_base__slice_u8 prefix_data,bool prefix_closed)15993 wuffs_base__magic_number_guess_fourcc__maybe_tga(
15994 wuffs_base__slice_u8 prefix_data,
15995 bool prefix_closed) {
15996 // Allow-list for the Image Type field.
15997 if (prefix_data.len < 3) {
15998 return prefix_closed ? 0 : -1;
15999 }
16000 switch (prefix_data.ptr[2]) {
16001 case 0x01:
16002 case 0x02:
16003 case 0x03:
16004 case 0x09:
16005 case 0x0A:
16006 case 0x0B:
16007 break;
16008 default:
16009 // TODO: 0x20 and 0x21 are invalid, according to the spec, but are
16010 // apparently unofficial extensions.
16011 return 0;
16012 }
16013
16014 // Allow-list for the Color Map Entry Size field (if the Color Map Type field
16015 // is non-zero) or else all the Color Map fields should be zero.
16016 if (prefix_data.len < 8) {
16017 return prefix_closed ? 0 : -1;
16018 } else if (prefix_data.ptr[1] != 0x00) {
16019 switch (prefix_data.ptr[7]) {
16020 case 0x0F:
16021 case 0x10:
16022 case 0x18:
16023 case 0x20:
16024 break;
16025 default:
16026 return 0;
16027 }
16028 } else if ((prefix_data.ptr[3] | prefix_data.ptr[4] | prefix_data.ptr[5] |
16029 prefix_data.ptr[6] | prefix_data.ptr[7]) != 0x00) {
16030 return 0;
16031 }
16032
16033 // Allow-list for the Pixel Depth field.
16034 if (prefix_data.len < 17) {
16035 return prefix_closed ? 0 : -1;
16036 }
16037 switch (prefix_data.ptr[16]) {
16038 case 0x01:
16039 case 0x08:
16040 case 0x0F:
16041 case 0x10:
16042 case 0x18:
16043 case 0x20:
16044 break;
16045 default:
16046 return 0;
16047 }
16048
16049 return 0x54474120; // 'TGA 'be
16050 }
16051
16052 WUFFS_BASE__MAYBE_STATIC int32_t //
wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,bool prefix_closed)16053 wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
16054 bool prefix_closed) {
16055 // This is similar to (but different from):
16056 // - the magic/Magdir tables under https://github.com/file/file
16057 // - the MIME Sniffing algorithm at https://mimesniff.spec.whatwg.org/
16058
16059 // table holds the 'magic numbers' (which are actually variable length
16060 // strings). The strings may contain NUL bytes, so the "const char* magic"
16061 // value starts with the length-minus-1 of the 'magic number'.
16062 //
16063 // Keep it sorted by magic[1], then magic[0] descending and finally by
16064 // magic[2:]. When multiple entries match, the longest one wins.
16065 //
16066 // The fourcc field might be negated, in which case there's further
16067 // specialization (see § below).
16068 static struct {
16069 int32_t fourcc;
16070 const char* magic;
16071 } table[] = {
16072 {-0x30302020, "\x01\x00\x00"}, // '00 'be
16073 {+0x424D5020, "\x01\x42\x4D"}, // BMP
16074 {+0x47494620, "\x03\x47\x49\x46\x38"}, // GIF
16075 {+0x54494646, "\x03\x49\x49\x2A\x00"}, // TIFF (little-endian)
16076 {+0x54494646, "\x03\x4D\x4D\x00\x2A"}, // TIFF (big-endian)
16077 {-0x52494646, "\x03\x52\x49\x46\x46"}, // RIFF
16078 {+0x4E494520, "\x02\x6E\xC3\xAF"}, // NIE
16079 {+0x514F4920, "\x03\x71\x6F\x69\x66"}, // QOI
16080 {+0x504E4720, "\x03\x89\x50\x4E\x47"}, // PNG
16081 {+0x4A504547, "\x01\xFF\xD8"}, // JPEG
16082 };
16083 static const size_t table_len = sizeof(table) / sizeof(table[0]);
16084
16085 if (prefix_data.len == 0) {
16086 return prefix_closed ? 0 : -1;
16087 }
16088 uint8_t pre_first_byte = prefix_data.ptr[0];
16089
16090 int32_t fourcc = 0;
16091 size_t i;
16092 for (i = 0; i < table_len; i++) {
16093 uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1]));
16094 if (pre_first_byte < mag_first_byte) {
16095 break;
16096 } else if (pre_first_byte > mag_first_byte) {
16097 continue;
16098 }
16099 fourcc = table[i].fourcc;
16100
16101 uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0]));
16102 if (mag_remaining_len == 0) {
16103 goto match;
16104 }
16105
16106 const char* mag_remaining_ptr = table[i].magic + 2;
16107 uint8_t* pre_remaining_ptr = prefix_data.ptr + 1;
16108 size_t pre_remaining_len = prefix_data.len - 1;
16109 if (pre_remaining_len < mag_remaining_len) {
16110 if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) {
16111 return prefix_closed ? 0 : -1;
16112 }
16113 } else {
16114 if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) {
16115 goto match;
16116 }
16117 }
16118 }
16119
16120 if (prefix_data.len < 2) {
16121 return prefix_closed ? 0 : -1;
16122 } else if ((prefix_data.ptr[1] == 0x00) || (prefix_data.ptr[1] == 0x01)) {
16123 return wuffs_base__magic_number_guess_fourcc__maybe_tga(prefix_data,
16124 prefix_closed);
16125 }
16126
16127 return 0;
16128
16129 match:
16130 // Negative FourCC values (see § above) are further specialized.
16131 if (fourcc < 0) {
16132 fourcc = -fourcc;
16133
16134 if (fourcc == 0x52494646) { // 'RIFF'be
16135 if (prefix_data.len < 12) {
16136 return prefix_closed ? 0 : -1;
16137 }
16138 uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix_data.ptr + 8);
16139 if (x == 0x57454250) { // 'WEBP'be
16140 return 0x57454250; // 'WEBP'be
16141 }
16142
16143 } else if (fourcc == 0x30302020) { // '00 'be
16144 // Binary data starting with multiple 0x00 NUL bytes is quite common.
16145 // Unfortunately, some file formats also don't start with a magic
16146 // identifier, so we have to use heuristics (where the order matters, the
16147 // same as /usr/bin/file's magic/Magdir tables) as best we can. Maybe
16148 // it's TGA, ICO/CUR, etc. Maybe it's something else.
16149 int32_t tga = wuffs_base__magic_number_guess_fourcc__maybe_tga(
16150 prefix_data, prefix_closed);
16151 if (tga != 0) {
16152 return tga;
16153 }
16154 int32_t ico = wuffs_base__magic_number_guess_fourcc__maybe_ico(
16155 prefix_data, prefix_closed);
16156 if (ico != 0) {
16157 return ico;
16158 }
16159 if (prefix_data.len < 4) {
16160 return prefix_closed ? 0 : -1;
16161 } else if ((prefix_data.ptr[2] != 0x00) &&
16162 ((prefix_data.ptr[2] >= 0x80) ||
16163 (prefix_data.ptr[3] != 0x00))) {
16164 // Roughly speaking, this could be a non-degenerate (non-0-width and
16165 // non-0-height) WBMP image.
16166 return 0x57424D50; // 'WBMP'be
16167 }
16168 return 0;
16169 }
16170 }
16171 return fourcc;
16172 }
16173
16174 #endif // !defined(WUFFS_CONFIG__MODULES) ||
16175 // defined(WUFFS_CONFIG__MODULE__BASE) ||
16176 // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
16177
16178 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
16179 defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
16180
16181 // ---------------- Pixel Swizzler
16182
16183 static inline uint32_t //
wuffs_base__swap_u32_argb_abgr(uint32_t u)16184 wuffs_base__swap_u32_argb_abgr(uint32_t u) {
16185 uint32_t o = u & 0xFF00FF00ul;
16186 uint32_t r = u & 0x00FF0000ul;
16187 uint32_t b = u & 0x000000FFul;
16188 return o | (r >> 16) | (b << 16);
16189 }
16190
16191 static inline uint64_t //
wuffs_base__swap_u64_argb_abgr(uint64_t u)16192 wuffs_base__swap_u64_argb_abgr(uint64_t u) {
16193 uint64_t o = u & 0xFFFF0000FFFF0000ull;
16194 uint64_t r = u & 0x0000FFFF00000000ull;
16195 uint64_t b = u & 0x000000000000FFFFull;
16196 return o | (r >> 32) | (b << 32);
16197 }
16198
16199 static inline uint32_t //
wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c)16200 wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) {
16201 uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
16202 uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
16203 uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
16204 uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
16205 return (a << 24) | (b << 16) | (g << 8) | (r << 0);
16206 }
16207
16208 // --------
16209
16210 WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer * pb,uint32_t x,uint32_t y)16211 wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
16212 uint32_t x,
16213 uint32_t y) {
16214 if (!pb || (x >= pb->pixcfg.private_impl.width) ||
16215 (y >= pb->pixcfg.private_impl.height)) {
16216 return 0;
16217 }
16218
16219 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
16220 // TODO: support planar formats.
16221 return 0;
16222 }
16223
16224 size_t stride = pb->private_impl.planes[0].stride;
16225 const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
16226
16227 switch (pb->pixcfg.private_impl.pixfmt.repr) {
16228 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
16229 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
16230 return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
16231
16232 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
16233 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
16234 uint8_t* palette = pb->private_impl.planes[3].ptr;
16235 return wuffs_base__peek_u32le__no_bounds_check(palette +
16236 (4 * ((size_t)row[x])));
16237 }
16238
16239 // Common formats above. Rarer formats below.
16240
16241 case WUFFS_BASE__PIXEL_FORMAT__Y:
16242 return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x])));
16243 case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
16244 return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1])));
16245 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
16246 return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0])));
16247
16248 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: {
16249 uint8_t* palette = pb->private_impl.planes[3].ptr;
16250 return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
16251 wuffs_base__peek_u32le__no_bounds_check(palette +
16252 (4 * ((size_t)row[x]))));
16253 }
16254
16255 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
16256 return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
16257 wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x))));
16258 case WUFFS_BASE__PIXEL_FORMAT__BGR:
16259 return 0xFF000000 |
16260 wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)));
16261 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
16262 return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
16263 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
16264 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
16265 return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
16266 wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x))));
16267 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
16268 return 0xFF000000 |
16269 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
16270
16271 case WUFFS_BASE__PIXEL_FORMAT__RGB:
16272 return wuffs_base__swap_u32_argb_abgr(
16273 0xFF000000 |
16274 wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))));
16275 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
16276 return wuffs_base__swap_u32_argb_abgr(
16277 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
16278 wuffs_base__peek_u32le__no_bounds_check(row +
16279 (4 * ((size_t)x)))));
16280 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
16281 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
16282 return wuffs_base__swap_u32_argb_abgr(
16283 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
16284 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
16285 return wuffs_base__swap_u32_argb_abgr(
16286 0xFF000000 |
16287 wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
16288
16289 default:
16290 // TODO: support more formats.
16291 break;
16292 }
16293
16294 return 0;
16295 }
16296
16297 // --------
16298
16299 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
wuffs_base__pixel_buffer__set_color_u32_at(wuffs_base__pixel_buffer * pb,uint32_t x,uint32_t y,wuffs_base__color_u32_argb_premul color)16300 wuffs_base__pixel_buffer__set_color_u32_at(
16301 wuffs_base__pixel_buffer* pb,
16302 uint32_t x,
16303 uint32_t y,
16304 wuffs_base__color_u32_argb_premul color) {
16305 if (!pb) {
16306 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16307 }
16308 if ((x >= pb->pixcfg.private_impl.width) ||
16309 (y >= pb->pixcfg.private_impl.height)) {
16310 return wuffs_base__make_status(wuffs_base__error__bad_argument);
16311 }
16312
16313 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
16314 // TODO: support planar formats.
16315 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
16316 }
16317
16318 size_t stride = pb->private_impl.planes[0].stride;
16319 uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
16320
16321 switch (pb->pixcfg.private_impl.pixfmt.repr) {
16322 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
16323 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
16324 wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color);
16325 break;
16326
16327 // Common formats above. Rarer formats below.
16328
16329 case WUFFS_BASE__PIXEL_FORMAT__Y:
16330 wuffs_base__poke_u8__no_bounds_check(
16331 row + ((size_t)x),
16332 wuffs_base__color_u32_argb_premul__as__color_u8_gray(color));
16333 break;
16334 case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
16335 wuffs_base__poke_u16le__no_bounds_check(
16336 row + (2 * ((size_t)x)),
16337 wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
16338 break;
16339 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
16340 wuffs_base__poke_u16be__no_bounds_check(
16341 row + (2 * ((size_t)x)),
16342 wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
16343 break;
16344
16345 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
16346 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
16347 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
16348 wuffs_base__poke_u8__no_bounds_check(
16349 row + ((size_t)x), wuffs_base__pixel_palette__closest_element(
16350 wuffs_base__pixel_buffer__palette(pb),
16351 pb->pixcfg.private_impl.pixfmt, color));
16352 break;
16353
16354 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
16355 wuffs_base__poke_u16le__no_bounds_check(
16356 row + (2 * ((size_t)x)),
16357 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
16358 break;
16359 case WUFFS_BASE__PIXEL_FORMAT__BGR:
16360 wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color);
16361 break;
16362 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
16363 wuffs_base__poke_u32le__no_bounds_check(
16364 row + (4 * ((size_t)x)),
16365 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16366 color));
16367 break;
16368 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
16369 wuffs_base__poke_u64le__no_bounds_check(
16370 row + (8 * ((size_t)x)),
16371 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
16372 color));
16373 break;
16374
16375 case WUFFS_BASE__PIXEL_FORMAT__RGB:
16376 wuffs_base__poke_u24le__no_bounds_check(
16377 row + (3 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
16378 break;
16379 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
16380 wuffs_base__poke_u32le__no_bounds_check(
16381 row + (4 * ((size_t)x)),
16382 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16383 wuffs_base__swap_u32_argb_abgr(color)));
16384 break;
16385 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
16386 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
16387 wuffs_base__poke_u32le__no_bounds_check(
16388 row + (4 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
16389 break;
16390
16391 default:
16392 // TODO: support more formats.
16393 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
16394 }
16395
16396 return wuffs_base__make_status(NULL);
16397 }
16398
16399 // --------
16400
16401 static inline void //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint16_t color)16402 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
16403 wuffs_base__pixel_buffer* pb,
16404 wuffs_base__rect_ie_u32 rect,
16405 uint16_t color) {
16406 size_t stride = pb->private_impl.planes[0].stride;
16407 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16408 if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16409 uint8_t* ptr =
16410 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16411 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16412 size_t n;
16413 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16414 wuffs_base__poke_u16le__no_bounds_check(ptr, color);
16415 ptr += 2;
16416 }
16417 return;
16418 }
16419
16420 uint32_t y;
16421 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16422 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16423 (2 * ((size_t)rect.min_incl_x));
16424 uint32_t n;
16425 for (n = width; n > 0; n--) {
16426 wuffs_base__poke_u16le__no_bounds_check(ptr, color);
16427 ptr += 2;
16428 }
16429 }
16430 }
16431
16432 static inline void //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint32_t color)16433 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(
16434 wuffs_base__pixel_buffer* pb,
16435 wuffs_base__rect_ie_u32 rect,
16436 uint32_t color) {
16437 size_t stride = pb->private_impl.planes[0].stride;
16438 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16439 if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16440 uint8_t* ptr =
16441 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16442 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16443 size_t n;
16444 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16445 wuffs_base__poke_u24le__no_bounds_check(ptr, color);
16446 ptr += 3;
16447 }
16448 return;
16449 }
16450
16451 uint32_t y;
16452 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16453 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16454 (3 * ((size_t)rect.min_incl_x));
16455 uint32_t n;
16456 for (n = width; n > 0; n--) {
16457 wuffs_base__poke_u24le__no_bounds_check(ptr, color);
16458 ptr += 3;
16459 }
16460 }
16461 }
16462
16463 static inline void //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint32_t color)16464 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16465 wuffs_base__pixel_buffer* pb,
16466 wuffs_base__rect_ie_u32 rect,
16467 uint32_t color) {
16468 size_t stride = pb->private_impl.planes[0].stride;
16469 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16470 if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16471 uint8_t* ptr =
16472 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16473 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16474 size_t n;
16475 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16476 wuffs_base__poke_u32le__no_bounds_check(ptr, color);
16477 ptr += 4;
16478 }
16479 return;
16480 }
16481
16482 uint32_t y;
16483 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16484 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16485 (4 * ((size_t)rect.min_incl_x));
16486 uint32_t n;
16487 for (n = width; n > 0; n--) {
16488 wuffs_base__poke_u32le__no_bounds_check(ptr, color);
16489 ptr += 4;
16490 }
16491 }
16492 }
16493
16494 static inline void //
wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,uint64_t color)16495 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
16496 wuffs_base__pixel_buffer* pb,
16497 wuffs_base__rect_ie_u32 rect,
16498 uint64_t color) {
16499 size_t stride = pb->private_impl.planes[0].stride;
16500 uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
16501 if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
16502 uint8_t* ptr =
16503 pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
16504 uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
16505 size_t n;
16506 for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
16507 wuffs_base__poke_u64le__no_bounds_check(ptr, color);
16508 ptr += 8;
16509 }
16510 return;
16511 }
16512
16513 uint32_t y;
16514 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16515 uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
16516 (8 * ((size_t)rect.min_incl_x));
16517 uint32_t n;
16518 for (n = width; n > 0; n--) {
16519 wuffs_base__poke_u64le__no_bounds_check(ptr, color);
16520 ptr += 8;
16521 }
16522 }
16523 }
16524
16525 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
wuffs_base__pixel_buffer__set_color_u32_fill_rect(wuffs_base__pixel_buffer * pb,wuffs_base__rect_ie_u32 rect,wuffs_base__color_u32_argb_premul color)16526 wuffs_base__pixel_buffer__set_color_u32_fill_rect(
16527 wuffs_base__pixel_buffer* pb,
16528 wuffs_base__rect_ie_u32 rect,
16529 wuffs_base__color_u32_argb_premul color) {
16530 if (!pb) {
16531 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
16532 } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) {
16533 return wuffs_base__make_status(NULL);
16534 }
16535 wuffs_base__rect_ie_u32 bounds =
16536 wuffs_base__pixel_config__bounds(&pb->pixcfg);
16537 if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) {
16538 return wuffs_base__make_status(wuffs_base__error__bad_argument);
16539 }
16540
16541 if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
16542 // TODO: support planar formats.
16543 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
16544 }
16545
16546 switch (pb->pixcfg.private_impl.pixfmt.repr) {
16547 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
16548 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
16549 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect, color);
16550 return wuffs_base__make_status(NULL);
16551
16552 // Common formats above. Rarer formats below.
16553
16554 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
16555 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
16556 pb, rect,
16557 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
16558 return wuffs_base__make_status(NULL);
16559
16560 case WUFFS_BASE__PIXEL_FORMAT__BGR:
16561 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect, color);
16562 return wuffs_base__make_status(NULL);
16563
16564 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
16565 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16566 pb, rect,
16567 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16568 color));
16569 return wuffs_base__make_status(NULL);
16570
16571 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
16572 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
16573 pb, rect,
16574 wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
16575 color));
16576 return wuffs_base__make_status(NULL);
16577
16578 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
16579 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16580 pb, rect,
16581 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
16582 wuffs_base__swap_u32_argb_abgr(color)));
16583 return wuffs_base__make_status(NULL);
16584
16585 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
16586 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
16587 wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
16588 pb, rect, wuffs_base__swap_u32_argb_abgr(color));
16589 return wuffs_base__make_status(NULL);
16590 }
16591
16592 uint32_t y;
16593 for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
16594 uint32_t x;
16595 for (x = rect.min_incl_x; x < rect.max_excl_x; x++) {
16596 wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color);
16597 }
16598 }
16599 return wuffs_base__make_status(NULL);
16600 }
16601
16602 // --------
16603
16604 WUFFS_BASE__MAYBE_STATIC uint8_t //
wuffs_base__pixel_palette__closest_element(wuffs_base__slice_u8 palette_slice,wuffs_base__pixel_format palette_format,wuffs_base__color_u32_argb_premul c)16605 wuffs_base__pixel_palette__closest_element(
16606 wuffs_base__slice_u8 palette_slice,
16607 wuffs_base__pixel_format palette_format,
16608 wuffs_base__color_u32_argb_premul c) {
16609 size_t n = palette_slice.len / 4;
16610 if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
16611 n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4);
16612 }
16613 size_t best_index = 0;
16614 uint64_t best_score = 0xFFFFFFFFFFFFFFFF;
16615
16616 // Work in 16-bit color.
16617 uint32_t ca = 0x101 * (0xFF & (c >> 24));
16618 uint32_t cr = 0x101 * (0xFF & (c >> 16));
16619 uint32_t cg = 0x101 * (0xFF & (c >> 8));
16620 uint32_t cb = 0x101 * (0xFF & (c >> 0));
16621
16622 switch (palette_format.repr) {
16623 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
16624 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
16625 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
16626 bool nonpremul = palette_format.repr ==
16627 WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL;
16628
16629 size_t i;
16630 for (i = 0; i < n; i++) {
16631 // Work in 16-bit color.
16632 uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0]));
16633 uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1]));
16634 uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2]));
16635 uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3]));
16636
16637 // Convert to premultiplied alpha.
16638 if (nonpremul && (pa != 0xFFFF)) {
16639 pb = (pb * pa) / 0xFFFF;
16640 pg = (pg * pa) / 0xFFFF;
16641 pr = (pr * pa) / 0xFFFF;
16642 }
16643
16644 // These deltas are conceptually int32_t (signed) but after squaring,
16645 // it's equivalent to work in uint32_t (unsigned).
16646 pb -= cb;
16647 pg -= cg;
16648 pr -= cr;
16649 pa -= ca;
16650 uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) +
16651 ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa));
16652 if (best_score > score) {
16653 best_score = score;
16654 best_index = i;
16655 }
16656 }
16657 break;
16658 }
16659 }
16660
16661 return (uint8_t)best_index;
16662 }
16663
16664 // --------
16665
16666 static inline uint32_t //
wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_nonpremul)16667 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,
16668 uint32_t src_nonpremul) {
16669 // Extract 16-bit color components.
16670 //
16671 // If the destination is transparent then SRC_OVER is equivalent to SRC: just
16672 // return src_nonpremul. This isn't just an optimization (skipping the rest
16673 // of the function's computation). It also preserves the nonpremul
16674 // distinction between e.g. transparent red and transparent blue that would
16675 // otherwise be lost by converting from nonpremul to premul and back.
16676 uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
16677 if (da == 0) {
16678 return src_nonpremul;
16679 }
16680 uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
16681 uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
16682 uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
16683 uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
16684 uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
16685 uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
16686 uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
16687
16688 // Convert dst from nonpremul to premul.
16689 dr = (dr * da) / 0xFFFF;
16690 dg = (dg * da) / 0xFFFF;
16691 db = (db * da) / 0xFFFF;
16692
16693 // Calculate the inverse of the src-alpha: how much of the dst to keep.
16694 uint32_t ia = 0xFFFF - sa;
16695
16696 // Composite src (nonpremul) over dst (premul).
16697 da = sa + ((da * ia) / 0xFFFF);
16698 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16699 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16700 db = ((sb * sa) + (db * ia)) / 0xFFFF;
16701
16702 // Convert dst from premul to nonpremul.
16703 if (da != 0) {
16704 dr = (dr * 0xFFFF) / da;
16705 dg = (dg * 0xFFFF) / da;
16706 db = (db * 0xFFFF) / da;
16707 }
16708
16709 // Convert from 16-bit color to 8-bit color.
16710 da >>= 8;
16711 dr >>= 8;
16712 dg >>= 8;
16713 db >>= 8;
16714
16715 // Combine components.
16716 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16717 }
16718
16719 static inline uint64_t //
wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_nonpremul)16720 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,
16721 uint64_t src_nonpremul) {
16722 // Extract components.
16723 //
16724 // If the destination is transparent then SRC_OVER is equivalent to SRC: just
16725 // return src_nonpremul. This isn't just an optimization (skipping the rest
16726 // of the function's computation). It also preserves the nonpremul
16727 // distinction between e.g. transparent red and transparent blue that would
16728 // otherwise be lost by converting from nonpremul to premul and back.
16729 uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
16730 if (da == 0) {
16731 return src_nonpremul;
16732 }
16733 uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
16734 uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
16735 uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
16736 uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
16737 uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
16738 uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
16739 uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
16740
16741 // Convert dst from nonpremul to premul.
16742 dr = (dr * da) / 0xFFFF;
16743 dg = (dg * da) / 0xFFFF;
16744 db = (db * da) / 0xFFFF;
16745
16746 // Calculate the inverse of the src-alpha: how much of the dst to keep.
16747 uint64_t ia = 0xFFFF - sa;
16748
16749 // Composite src (nonpremul) over dst (premul).
16750 da = sa + ((da * ia) / 0xFFFF);
16751 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16752 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16753 db = ((sb * sa) + (db * ia)) / 0xFFFF;
16754
16755 // Convert dst from premul to nonpremul.
16756 if (da != 0) {
16757 dr = (dr * 0xFFFF) / da;
16758 dg = (dg * 0xFFFF) / da;
16759 db = (db * 0xFFFF) / da;
16760 }
16761
16762 // Combine components.
16763 return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16764 }
16765
16766 static inline uint32_t //
wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,uint32_t src_premul)16767 wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,
16768 uint32_t src_premul) {
16769 // Extract 16-bit color components.
16770 uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
16771 uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
16772 uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
16773 uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
16774 uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
16775 uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
16776 uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
16777 uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
16778
16779 // Convert dst from nonpremul to premul.
16780 dr = (dr * da) / 0xFFFF;
16781 dg = (dg * da) / 0xFFFF;
16782 db = (db * da) / 0xFFFF;
16783
16784 // Calculate the inverse of the src-alpha: how much of the dst to keep.
16785 uint32_t ia = 0xFFFF - sa;
16786
16787 // Composite src (premul) over dst (premul).
16788 da = sa + ((da * ia) / 0xFFFF);
16789 dr = sr + ((dr * ia) / 0xFFFF);
16790 dg = sg + ((dg * ia) / 0xFFFF);
16791 db = sb + ((db * ia) / 0xFFFF);
16792
16793 // Convert dst from premul to nonpremul.
16794 if (da != 0) {
16795 dr = (dr * 0xFFFF) / da;
16796 dg = (dg * 0xFFFF) / da;
16797 db = (db * 0xFFFF) / da;
16798 }
16799
16800 // Convert from 16-bit color to 8-bit color.
16801 da >>= 8;
16802 dr >>= 8;
16803 dg >>= 8;
16804 db >>= 8;
16805
16806 // Combine components.
16807 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16808 }
16809
16810 static inline uint64_t //
wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,uint64_t src_premul)16811 wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,
16812 uint64_t src_premul) {
16813 // Extract components.
16814 uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
16815 uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
16816 uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
16817 uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
16818 uint64_t sa = 0xFFFF & (src_premul >> 48);
16819 uint64_t sr = 0xFFFF & (src_premul >> 32);
16820 uint64_t sg = 0xFFFF & (src_premul >> 16);
16821 uint64_t sb = 0xFFFF & (src_premul >> 0);
16822
16823 // Convert dst from nonpremul to premul.
16824 dr = (dr * da) / 0xFFFF;
16825 dg = (dg * da) / 0xFFFF;
16826 db = (db * da) / 0xFFFF;
16827
16828 // Calculate the inverse of the src-alpha: how much of the dst to keep.
16829 uint64_t ia = 0xFFFF - sa;
16830
16831 // Composite src (premul) over dst (premul).
16832 da = sa + ((da * ia) / 0xFFFF);
16833 dr = sr + ((dr * ia) / 0xFFFF);
16834 dg = sg + ((dg * ia) / 0xFFFF);
16835 db = sb + ((db * ia) / 0xFFFF);
16836
16837 // Convert dst from premul to nonpremul.
16838 if (da != 0) {
16839 dr = (dr * 0xFFFF) / da;
16840 dg = (dg * 0xFFFF) / da;
16841 db = (db * 0xFFFF) / da;
16842 }
16843
16844 // Combine components.
16845 return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16846 }
16847
16848 static inline uint32_t //
wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,uint32_t src_nonpremul)16849 wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,
16850 uint32_t src_nonpremul) {
16851 // Extract 16-bit color components.
16852 uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
16853 uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
16854 uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
16855 uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
16856 uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
16857 uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
16858 uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
16859 uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
16860
16861 // Calculate the inverse of the src-alpha: how much of the dst to keep.
16862 uint32_t ia = 0xFFFF - sa;
16863
16864 // Composite src (nonpremul) over dst (premul).
16865 da = sa + ((da * ia) / 0xFFFF);
16866 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16867 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16868 db = ((sb * sa) + (db * ia)) / 0xFFFF;
16869
16870 // Convert from 16-bit color to 8-bit color.
16871 da >>= 8;
16872 dr >>= 8;
16873 dg >>= 8;
16874 db >>= 8;
16875
16876 // Combine components.
16877 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16878 }
16879
16880 static inline uint64_t //
wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,uint64_t src_nonpremul)16881 wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,
16882 uint64_t src_nonpremul) {
16883 // Extract components.
16884 uint64_t da = 0xFFFF & (dst_premul >> 48);
16885 uint64_t dr = 0xFFFF & (dst_premul >> 32);
16886 uint64_t dg = 0xFFFF & (dst_premul >> 16);
16887 uint64_t db = 0xFFFF & (dst_premul >> 0);
16888 uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
16889 uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
16890 uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
16891 uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
16892
16893 // Calculate the inverse of the src-alpha: how much of the dst to keep.
16894 uint64_t ia = 0xFFFF - sa;
16895
16896 // Composite src (nonpremul) over dst (premul).
16897 da = sa + ((da * ia) / 0xFFFF);
16898 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
16899 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
16900 db = ((sb * sa) + (db * ia)) / 0xFFFF;
16901
16902 // Combine components.
16903 return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
16904 }
16905
16906 static inline uint32_t //
wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,uint32_t src_premul)16907 wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,
16908 uint32_t src_premul) {
16909 // Extract 16-bit color components.
16910 uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
16911 uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
16912 uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
16913 uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
16914 uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
16915 uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
16916 uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
16917 uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
16918
16919 // Calculate the inverse of the src-alpha: how much of the dst to keep.
16920 uint32_t ia = 0xFFFF - sa;
16921
16922 // Composite src (premul) over dst (premul).
16923 da = sa + ((da * ia) / 0xFFFF);
16924 dr = sr + ((dr * ia) / 0xFFFF);
16925 dg = sg + ((dg * ia) / 0xFFFF);
16926 db = sb + ((db * ia) / 0xFFFF);
16927
16928 // Convert from 16-bit color to 8-bit color.
16929 da >>= 8;
16930 dr >>= 8;
16931 dg >>= 8;
16932 db >>= 8;
16933
16934 // Combine components.
16935 return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
16936 }
16937
16938 // --------
16939
16940 static uint64_t //
wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t * dst_ptr,size_t dst_len,const uint8_t * src_ptr,size_t src_len,bool nonpremul)16941 wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t* dst_ptr,
16942 size_t dst_len,
16943 const uint8_t* src_ptr,
16944 size_t src_len,
16945 bool nonpremul) {
16946 size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
16947 uint8_t* d = dst_ptr;
16948 const uint8_t* s = src_ptr;
16949
16950 size_t n = len;
16951 while (n--) {
16952 uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s);
16953 if (nonpremul) {
16954 argb =
16955 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb);
16956 }
16957 uint32_t b5 = 0x1F & (argb >> (8 - 5));
16958 uint32_t g6 = 0x3F & (argb >> (16 - 6));
16959 uint32_t r5 = 0x1F & (argb >> (24 - 5));
16960 uint32_t alpha = argb & 0xFF000000;
16961 wuffs_base__poke_u32le__no_bounds_check(
16962 d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0));
16963 s += 4;
16964 d += 4;
16965 }
16966 return len;
16967 }
16968
16969 // --------
16970
16971 static uint64_t //
wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)16972 wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t* dst_ptr,
16973 size_t dst_len,
16974 uint8_t* dst_palette_ptr,
16975 size_t dst_palette_len,
16976 const uint8_t* src_ptr,
16977 size_t src_len) {
16978 size_t len = (dst_len < src_len ? dst_len : src_len) / 3;
16979 uint8_t* d = dst_ptr;
16980 const uint8_t* s = src_ptr;
16981
16982 size_t n = len;
16983 while (n--) {
16984 uint8_t s0 = s[0];
16985 uint8_t s1 = s[1];
16986 uint8_t s2 = s[2];
16987 d[0] = s2;
16988 d[1] = s1;
16989 d[2] = s0;
16990 s += 3;
16991 d += 3;
16992 }
16993 return len;
16994 }
16995
16996 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
16997 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
16998 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
16999 static uint64_t //
wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17000 wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42(uint8_t* dst_ptr,
17001 size_t dst_len,
17002 uint8_t* dst_palette_ptr,
17003 size_t dst_palette_len,
17004 const uint8_t* src_ptr,
17005 size_t src_len) {
17006 size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
17007 uint8_t* d = dst_ptr;
17008 const uint8_t* s = src_ptr;
17009 size_t n = len;
17010
17011 __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E, //
17012 +0x0B, +0x08, +0x09, +0x0A, //
17013 +0x07, +0x04, +0x05, +0x06, //
17014 +0x03, +0x00, +0x01, +0x02);
17015
17016 while (n >= 4) {
17017 __m128i x;
17018 x = _mm_lddqu_si128((const __m128i*)(const void*)s);
17019 x = _mm_shuffle_epi8(x, shuffle);
17020 _mm_storeu_si128((__m128i*)(void*)d, x);
17021
17022 s += 4 * 4;
17023 d += 4 * 4;
17024 n -= 4;
17025 }
17026
17027 while (n--) {
17028 uint8_t s0 = s[0];
17029 uint8_t s1 = s[1];
17030 uint8_t s2 = s[2];
17031 uint8_t s3 = s[3];
17032 d[0] = s2;
17033 d[1] = s1;
17034 d[2] = s0;
17035 d[3] = s3;
17036 s += 4;
17037 d += 4;
17038 }
17039 return len;
17040 }
17041 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
17042 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
17043
17044 static uint64_t //
wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17045 wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t* dst_ptr,
17046 size_t dst_len,
17047 uint8_t* dst_palette_ptr,
17048 size_t dst_palette_len,
17049 const uint8_t* src_ptr,
17050 size_t src_len) {
17051 size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
17052 uint8_t* d = dst_ptr;
17053 const uint8_t* s = src_ptr;
17054
17055 size_t n = len;
17056 while (n--) {
17057 uint8_t s0 = s[0];
17058 uint8_t s1 = s[1];
17059 uint8_t s2 = s[2];
17060 uint8_t s3 = s[3];
17061 d[0] = s2;
17062 d[1] = s1;
17063 d[2] = s0;
17064 d[3] = s3;
17065 s += 4;
17066 d += 4;
17067 }
17068 return len;
17069 }
17070
17071 // --------
17072
17073 static uint64_t //
wuffs_base__pixel_swizzler__copy_1_1(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17074 wuffs_base__pixel_swizzler__copy_1_1(uint8_t* dst_ptr,
17075 size_t dst_len,
17076 uint8_t* dst_palette_ptr,
17077 size_t dst_palette_len,
17078 const uint8_t* src_ptr,
17079 size_t src_len) {
17080 size_t len = (dst_len < src_len) ? dst_len : src_len;
17081 if (len > 0) {
17082 memmove(dst_ptr, src_ptr, len);
17083 }
17084 return len;
17085 }
17086
17087 static uint64_t //
wuffs_base__pixel_swizzler__copy_2_2(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17088 wuffs_base__pixel_swizzler__copy_2_2(uint8_t* dst_ptr,
17089 size_t dst_len,
17090 uint8_t* dst_palette_ptr,
17091 size_t dst_palette_len,
17092 const uint8_t* src_ptr,
17093 size_t src_len) {
17094 size_t dst_len2 = dst_len / 2;
17095 size_t src_len2 = src_len / 2;
17096 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
17097 if (len > 0) {
17098 memmove(dst_ptr, src_ptr, len * 2);
17099 }
17100 return len;
17101 }
17102
17103 static uint64_t //
wuffs_base__pixel_swizzler__copy_3_3(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17104 wuffs_base__pixel_swizzler__copy_3_3(uint8_t* dst_ptr,
17105 size_t dst_len,
17106 uint8_t* dst_palette_ptr,
17107 size_t dst_palette_len,
17108 const uint8_t* src_ptr,
17109 size_t src_len) {
17110 size_t dst_len3 = dst_len / 3;
17111 size_t src_len3 = src_len / 3;
17112 size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3;
17113 if (len > 0) {
17114 memmove(dst_ptr, src_ptr, len * 3);
17115 }
17116 return len;
17117 }
17118
17119 static uint64_t //
wuffs_base__pixel_swizzler__copy_4_4(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17120 wuffs_base__pixel_swizzler__copy_4_4(uint8_t* dst_ptr,
17121 size_t dst_len,
17122 uint8_t* dst_palette_ptr,
17123 size_t dst_palette_len,
17124 const uint8_t* src_ptr,
17125 size_t src_len) {
17126 size_t dst_len4 = dst_len / 4;
17127 size_t src_len4 = src_len / 4;
17128 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
17129 if (len > 0) {
17130 memmove(dst_ptr, src_ptr, len * 4);
17131 }
17132 return len;
17133 }
17134
17135 static uint64_t //
wuffs_base__pixel_swizzler__copy_8_8(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17136 wuffs_base__pixel_swizzler__copy_8_8(uint8_t* dst_ptr,
17137 size_t dst_len,
17138 uint8_t* dst_palette_ptr,
17139 size_t dst_palette_len,
17140 const uint8_t* src_ptr,
17141 size_t src_len) {
17142 size_t dst_len8 = dst_len / 8;
17143 size_t src_len8 = src_len / 8;
17144 size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
17145 if (len > 0) {
17146 memmove(dst_ptr, src_ptr, len * 8);
17147 }
17148 return len;
17149 }
17150
17151 // --------
17152
17153 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17154 wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t* dst_ptr,
17155 size_t dst_len,
17156 uint8_t* dst_palette_ptr,
17157 size_t dst_palette_len,
17158 const uint8_t* src_ptr,
17159 size_t src_len) {
17160 size_t dst_len2 = dst_len / 2;
17161 size_t src_len3 = src_len / 3;
17162 size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
17163 uint8_t* d = dst_ptr;
17164 const uint8_t* s = src_ptr;
17165 size_t n = len;
17166
17167 // TODO: unroll.
17168
17169 while (n >= 1) {
17170 uint32_t b5 = s[0] >> 3;
17171 uint32_t g6 = s[1] >> 2;
17172 uint32_t r5 = s[2] >> 3;
17173 uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
17174 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17175
17176 s += 1 * 3;
17177 d += 1 * 2;
17178 n -= 1;
17179 }
17180
17181 return len;
17182 }
17183
17184 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17185 wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t* dst_ptr,
17186 size_t dst_len,
17187 uint8_t* dst_palette_ptr,
17188 size_t dst_palette_len,
17189 const uint8_t* src_ptr,
17190 size_t src_len) {
17191 size_t dst_len2 = dst_len / 2;
17192 size_t src_len4 = src_len / 4;
17193 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17194 uint8_t* d = dst_ptr;
17195 const uint8_t* s = src_ptr;
17196 size_t n = len;
17197
17198 // TODO: unroll.
17199
17200 while (n >= 1) {
17201 uint32_t b5 = s[0] >> 3;
17202 uint32_t g6 = s[1] >> 2;
17203 uint32_t r5 = s[2] >> 3;
17204 uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
17205 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17206
17207 s += 1 * 4;
17208 d += 1 * 2;
17209 n -= 1;
17210 }
17211
17212 return len;
17213 }
17214
17215 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17216 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(
17217 uint8_t* dst_ptr,
17218 size_t dst_len,
17219 uint8_t* dst_palette_ptr,
17220 size_t dst_palette_len,
17221 const uint8_t* src_ptr,
17222 size_t src_len) {
17223 size_t dst_len2 = dst_len / 2;
17224 size_t src_len4 = src_len / 4;
17225 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17226 uint8_t* d = dst_ptr;
17227 const uint8_t* s = src_ptr;
17228 size_t n = len;
17229
17230 // TODO: unroll.
17231
17232 while (n >= 1) {
17233 wuffs_base__poke_u16le__no_bounds_check(
17234 d + (0 * 2),
17235 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17236 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17237 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
17238
17239 s += 1 * 4;
17240 d += 1 * 2;
17241 n -= 1;
17242 }
17243
17244 return len;
17245 }
17246
17247 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17248 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src(
17249 uint8_t* dst_ptr,
17250 size_t dst_len,
17251 uint8_t* dst_palette_ptr,
17252 size_t dst_palette_len,
17253 const uint8_t* src_ptr,
17254 size_t src_len) {
17255 size_t dst_len2 = dst_len / 2;
17256 size_t src_len8 = src_len / 8;
17257 size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
17258 uint8_t* d = dst_ptr;
17259 const uint8_t* s = src_ptr;
17260 size_t n = len;
17261
17262 // TODO: unroll.
17263
17264 while (n >= 1) {
17265 wuffs_base__poke_u16le__no_bounds_check(
17266 d + (0 * 2),
17267 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17268 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
17269 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))));
17270
17271 s += 1 * 8;
17272 d += 1 * 2;
17273 n -= 1;
17274 }
17275
17276 return len;
17277 }
17278
17279 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17280 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(
17281 uint8_t* dst_ptr,
17282 size_t dst_len,
17283 uint8_t* dst_palette_ptr,
17284 size_t dst_palette_len,
17285 const uint8_t* src_ptr,
17286 size_t src_len) {
17287 size_t dst_len2 = dst_len / 2;
17288 size_t src_len4 = src_len / 4;
17289 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17290 uint8_t* d = dst_ptr;
17291 const uint8_t* s = src_ptr;
17292 size_t n = len;
17293
17294 // TODO: unroll.
17295
17296 while (n >= 1) {
17297 // Extract 16-bit color components.
17298 uint32_t sa = 0x101 * ((uint32_t)s[3]);
17299 uint32_t sr = 0x101 * ((uint32_t)s[2]);
17300 uint32_t sg = 0x101 * ((uint32_t)s[1]);
17301 uint32_t sb = 0x101 * ((uint32_t)s[0]);
17302
17303 // Convert from 565 color to 16-bit color.
17304 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17305 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17306 uint32_t dr = (0x8421 * old_r5) >> 4;
17307 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17308 uint32_t dg = (0x1041 * old_g6) >> 2;
17309 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17310 uint32_t db = (0x8421 * old_b5) >> 4;
17311
17312 // Calculate the inverse of the src-alpha: how much of the dst to keep.
17313 uint32_t ia = 0xFFFF - sa;
17314
17315 // Composite src (nonpremul) over dst (premul).
17316 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17317 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17318 db = ((sb * sa) + (db * ia)) / 0xFFFF;
17319
17320 // Convert from 16-bit color to 565 color and combine the components.
17321 uint32_t new_r5 = 0x1F & (dr >> 11);
17322 uint32_t new_g6 = 0x3F & (dg >> 10);
17323 uint32_t new_b5 = 0x1F & (db >> 11);
17324 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17325 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17326
17327 s += 1 * 4;
17328 d += 1 * 2;
17329 n -= 1;
17330 }
17331
17332 return len;
17333 }
17334
17335 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17336 wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over(
17337 uint8_t* dst_ptr,
17338 size_t dst_len,
17339 uint8_t* dst_palette_ptr,
17340 size_t dst_palette_len,
17341 const uint8_t* src_ptr,
17342 size_t src_len) {
17343 size_t dst_len2 = dst_len / 2;
17344 size_t src_len8 = src_len / 8;
17345 size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
17346 uint8_t* d = dst_ptr;
17347 const uint8_t* s = src_ptr;
17348 size_t n = len;
17349
17350 // TODO: unroll.
17351
17352 while (n >= 1) {
17353 // Extract 16-bit color components.
17354 uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
17355 uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
17356 uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
17357 uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
17358
17359 // Convert from 565 color to 16-bit color.
17360 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17361 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17362 uint32_t dr = (0x8421 * old_r5) >> 4;
17363 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17364 uint32_t dg = (0x1041 * old_g6) >> 2;
17365 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17366 uint32_t db = (0x8421 * old_b5) >> 4;
17367
17368 // Calculate the inverse of the src-alpha: how much of the dst to keep.
17369 uint32_t ia = 0xFFFF - sa;
17370
17371 // Composite src (nonpremul) over dst (premul).
17372 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17373 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17374 db = ((sb * sa) + (db * ia)) / 0xFFFF;
17375
17376 // Convert from 16-bit color to 565 color and combine the components.
17377 uint32_t new_r5 = 0x1F & (dr >> 11);
17378 uint32_t new_g6 = 0x3F & (dg >> 10);
17379 uint32_t new_b5 = 0x1F & (db >> 11);
17380 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17381 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17382
17383 s += 1 * 8;
17384 d += 1 * 2;
17385 n -= 1;
17386 }
17387
17388 return len;
17389 }
17390
17391 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17392 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t* dst_ptr,
17393 size_t dst_len,
17394 uint8_t* dst_palette_ptr,
17395 size_t dst_palette_len,
17396 const uint8_t* src_ptr,
17397 size_t src_len) {
17398 size_t dst_len2 = dst_len / 2;
17399 size_t src_len4 = src_len / 4;
17400 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17401 uint8_t* d = dst_ptr;
17402 const uint8_t* s = src_ptr;
17403 size_t n = len;
17404
17405 // TODO: unroll.
17406
17407 while (n >= 1) {
17408 wuffs_base__poke_u16le__no_bounds_check(
17409 d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17410 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
17411
17412 s += 1 * 4;
17413 d += 1 * 2;
17414 n -= 1;
17415 }
17416
17417 return len;
17418 }
17419
17420 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17421 wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over(
17422 uint8_t* dst_ptr,
17423 size_t dst_len,
17424 uint8_t* dst_palette_ptr,
17425 size_t dst_palette_len,
17426 const uint8_t* src_ptr,
17427 size_t src_len) {
17428 size_t dst_len2 = dst_len / 2;
17429 size_t src_len4 = src_len / 4;
17430 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17431 uint8_t* d = dst_ptr;
17432 const uint8_t* s = src_ptr;
17433 size_t n = len;
17434
17435 // TODO: unroll.
17436
17437 while (n >= 1) {
17438 // Extract 16-bit color components.
17439 uint32_t sa = 0x101 * ((uint32_t)s[3]);
17440 uint32_t sr = 0x101 * ((uint32_t)s[2]);
17441 uint32_t sg = 0x101 * ((uint32_t)s[1]);
17442 uint32_t sb = 0x101 * ((uint32_t)s[0]);
17443
17444 // Convert from 565 color to 16-bit color.
17445 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17446 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17447 uint32_t dr = (0x8421 * old_r5) >> 4;
17448 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17449 uint32_t dg = (0x1041 * old_g6) >> 2;
17450 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17451 uint32_t db = (0x8421 * old_b5) >> 4;
17452
17453 // Calculate the inverse of the src-alpha: how much of the dst to keep.
17454 uint32_t ia = 0xFFFF - sa;
17455
17456 // Composite src (premul) over dst (premul).
17457 dr = sr + ((dr * ia) / 0xFFFF);
17458 dg = sg + ((dg * ia) / 0xFFFF);
17459 db = sb + ((db * ia) / 0xFFFF);
17460
17461 // Convert from 16-bit color to 565 color and combine the components.
17462 uint32_t new_r5 = 0x1F & (dr >> 11);
17463 uint32_t new_g6 = 0x3F & (dg >> 10);
17464 uint32_t new_b5 = 0x1F & (db >> 11);
17465 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17466 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17467
17468 s += 1 * 4;
17469 d += 1 * 2;
17470 n -= 1;
17471 }
17472
17473 return len;
17474 }
17475
17476 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17477 wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t* dst_ptr,
17478 size_t dst_len,
17479 uint8_t* dst_palette_ptr,
17480 size_t dst_palette_len,
17481 const uint8_t* src_ptr,
17482 size_t src_len) {
17483 size_t dst_len2 = dst_len / 2;
17484 size_t src_len3 = src_len / 3;
17485 size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
17486 uint8_t* d = dst_ptr;
17487 const uint8_t* s = src_ptr;
17488 size_t n = len;
17489
17490 // TODO: unroll.
17491
17492 while (n >= 1) {
17493 uint32_t r5 = s[0] >> 3;
17494 uint32_t g6 = s[1] >> 2;
17495 uint32_t b5 = s[2] >> 3;
17496 uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
17497 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17498
17499 s += 1 * 3;
17500 d += 1 * 2;
17501 n -= 1;
17502 }
17503
17504 return len;
17505 }
17506
17507 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17508 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src(
17509 uint8_t* dst_ptr,
17510 size_t dst_len,
17511 uint8_t* dst_palette_ptr,
17512 size_t dst_palette_len,
17513 const uint8_t* src_ptr,
17514 size_t src_len) {
17515 size_t dst_len2 = dst_len / 2;
17516 size_t src_len4 = src_len / 4;
17517 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17518 uint8_t* d = dst_ptr;
17519 const uint8_t* s = src_ptr;
17520 size_t n = len;
17521
17522 // TODO: unroll.
17523
17524 while (n >= 1) {
17525 wuffs_base__poke_u16le__no_bounds_check(
17526 d + (0 * 2),
17527 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17528 wuffs_base__swap_u32_argb_abgr(
17529 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17530 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))));
17531
17532 s += 1 * 4;
17533 d += 1 * 2;
17534 n -= 1;
17535 }
17536
17537 return len;
17538 }
17539
17540 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17541 wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over(
17542 uint8_t* dst_ptr,
17543 size_t dst_len,
17544 uint8_t* dst_palette_ptr,
17545 size_t dst_palette_len,
17546 const uint8_t* src_ptr,
17547 size_t src_len) {
17548 size_t dst_len2 = dst_len / 2;
17549 size_t src_len4 = src_len / 4;
17550 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17551 uint8_t* d = dst_ptr;
17552 const uint8_t* s = src_ptr;
17553 size_t n = len;
17554
17555 // TODO: unroll.
17556
17557 while (n >= 1) {
17558 // Extract 16-bit color components.
17559 uint32_t sa = 0x101 * ((uint32_t)s[3]);
17560 uint32_t sb = 0x101 * ((uint32_t)s[2]);
17561 uint32_t sg = 0x101 * ((uint32_t)s[1]);
17562 uint32_t sr = 0x101 * ((uint32_t)s[0]);
17563
17564 // Convert from 565 color to 16-bit color.
17565 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17566 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17567 uint32_t dr = (0x8421 * old_r5) >> 4;
17568 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17569 uint32_t dg = (0x1041 * old_g6) >> 2;
17570 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17571 uint32_t db = (0x8421 * old_b5) >> 4;
17572
17573 // Calculate the inverse of the src-alpha: how much of the dst to keep.
17574 uint32_t ia = 0xFFFF - sa;
17575
17576 // Composite src (nonpremul) over dst (premul).
17577 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17578 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17579 db = ((sb * sa) + (db * ia)) / 0xFFFF;
17580
17581 // Convert from 16-bit color to 565 color and combine the components.
17582 uint32_t new_r5 = 0x1F & (dr >> 11);
17583 uint32_t new_g6 = 0x3F & (dg >> 10);
17584 uint32_t new_b5 = 0x1F & (db >> 11);
17585 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17586 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17587
17588 s += 1 * 4;
17589 d += 1 * 2;
17590 n -= 1;
17591 }
17592
17593 return len;
17594 }
17595
17596 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17597 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t* dst_ptr,
17598 size_t dst_len,
17599 uint8_t* dst_palette_ptr,
17600 size_t dst_palette_len,
17601 const uint8_t* src_ptr,
17602 size_t src_len) {
17603 size_t dst_len2 = dst_len / 2;
17604 size_t src_len4 = src_len / 4;
17605 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17606 uint8_t* d = dst_ptr;
17607 const uint8_t* s = src_ptr;
17608 size_t n = len;
17609
17610 // TODO: unroll.
17611
17612 while (n >= 1) {
17613 wuffs_base__poke_u16le__no_bounds_check(
17614 d + (0 * 2),
17615 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17616 wuffs_base__swap_u32_argb_abgr(
17617 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
17618
17619 s += 1 * 4;
17620 d += 1 * 2;
17621 n -= 1;
17622 }
17623
17624 return len;
17625 }
17626
17627 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17628 wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over(
17629 uint8_t* dst_ptr,
17630 size_t dst_len,
17631 uint8_t* dst_palette_ptr,
17632 size_t dst_palette_len,
17633 const uint8_t* src_ptr,
17634 size_t src_len) {
17635 size_t dst_len2 = dst_len / 2;
17636 size_t src_len4 = src_len / 4;
17637 size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
17638 uint8_t* d = dst_ptr;
17639 const uint8_t* s = src_ptr;
17640 size_t n = len;
17641
17642 // TODO: unroll.
17643
17644 while (n >= 1) {
17645 // Extract 16-bit color components.
17646 uint32_t sa = 0x101 * ((uint32_t)s[3]);
17647 uint32_t sb = 0x101 * ((uint32_t)s[2]);
17648 uint32_t sg = 0x101 * ((uint32_t)s[1]);
17649 uint32_t sr = 0x101 * ((uint32_t)s[0]);
17650
17651 // Convert from 565 color to 16-bit color.
17652 uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
17653 uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
17654 uint32_t dr = (0x8421 * old_r5) >> 4;
17655 uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
17656 uint32_t dg = (0x1041 * old_g6) >> 2;
17657 uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
17658 uint32_t db = (0x8421 * old_b5) >> 4;
17659
17660 // Calculate the inverse of the src-alpha: how much of the dst to keep.
17661 uint32_t ia = 0xFFFF - sa;
17662
17663 // Composite src (premul) over dst (premul).
17664 dr = sr + ((dr * ia) / 0xFFFF);
17665 dg = sg + ((dg * ia) / 0xFFFF);
17666 db = sb + ((db * ia) / 0xFFFF);
17667
17668 // Convert from 16-bit color to 565 color and combine the components.
17669 uint32_t new_r5 = 0x1F & (dr >> 11);
17670 uint32_t new_g6 = 0x3F & (dg >> 10);
17671 uint32_t new_b5 = 0x1F & (db >> 11);
17672 uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
17673 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
17674
17675 s += 1 * 4;
17676 d += 1 * 2;
17677 n -= 1;
17678 }
17679
17680 return len;
17681 }
17682
17683 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17684 wuffs_base__pixel_swizzler__bgr_565__y(uint8_t* dst_ptr,
17685 size_t dst_len,
17686 uint8_t* dst_palette_ptr,
17687 size_t dst_palette_len,
17688 const uint8_t* src_ptr,
17689 size_t src_len) {
17690 size_t dst_len2 = dst_len / 2;
17691 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17692 uint8_t* d = dst_ptr;
17693 const uint8_t* s = src_ptr;
17694 size_t n = len;
17695
17696 // TODO: unroll.
17697
17698 while (n >= 1) {
17699 uint32_t y5 = s[0] >> 3;
17700 uint32_t y6 = s[0] >> 2;
17701 uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
17702 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17703
17704 s += 1 * 1;
17705 d += 1 * 2;
17706 n -= 1;
17707 }
17708
17709 return len;
17710 }
17711
17712 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17713 wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t* dst_ptr,
17714 size_t dst_len,
17715 uint8_t* dst_palette_ptr,
17716 size_t dst_palette_len,
17717 const uint8_t* src_ptr,
17718 size_t src_len) {
17719 size_t dst_len2 = dst_len / 2;
17720 size_t src_len2 = src_len / 2;
17721 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
17722 uint8_t* d = dst_ptr;
17723 const uint8_t* s = src_ptr;
17724 size_t n = len;
17725
17726 // TODO: unroll.
17727
17728 while (n >= 1) {
17729 uint32_t y5 = s[0] >> 3;
17730 uint32_t y6 = s[0] >> 2;
17731 uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
17732 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
17733
17734 s += 1 * 2;
17735 d += 1 * 2;
17736 n -= 1;
17737 }
17738
17739 return len;
17740 }
17741
17742 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17743 wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t* dst_ptr,
17744 size_t dst_len,
17745 uint8_t* dst_palette_ptr,
17746 size_t dst_palette_len,
17747 const uint8_t* src_ptr,
17748 size_t src_len) {
17749 if (dst_palette_len !=
17750 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17751 return 0;
17752 }
17753 size_t dst_len2 = dst_len / 2;
17754 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17755 uint8_t* d = dst_ptr;
17756 const uint8_t* s = src_ptr;
17757 size_t n = len;
17758
17759 const size_t loop_unroll_count = 4;
17760
17761 while (n >= loop_unroll_count) {
17762 wuffs_base__poke_u16le__no_bounds_check(
17763 d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
17764 dst_palette_ptr + ((size_t)s[0] * 4)));
17765 wuffs_base__poke_u16le__no_bounds_check(
17766 d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check(
17767 dst_palette_ptr + ((size_t)s[1] * 4)));
17768 wuffs_base__poke_u16le__no_bounds_check(
17769 d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check(
17770 dst_palette_ptr + ((size_t)s[2] * 4)));
17771 wuffs_base__poke_u16le__no_bounds_check(
17772 d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check(
17773 dst_palette_ptr + ((size_t)s[3] * 4)));
17774
17775 s += loop_unroll_count * 1;
17776 d += loop_unroll_count * 2;
17777 n -= loop_unroll_count;
17778 }
17779
17780 while (n >= 1) {
17781 wuffs_base__poke_u16le__no_bounds_check(
17782 d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
17783 dst_palette_ptr + ((size_t)s[0] * 4)));
17784
17785 s += 1 * 1;
17786 d += 1 * 2;
17787 n -= 1;
17788 }
17789
17790 return len;
17791 }
17792
17793 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17794 wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over(
17795 uint8_t* dst_ptr,
17796 size_t dst_len,
17797 uint8_t* dst_palette_ptr,
17798 size_t dst_palette_len,
17799 const uint8_t* src_ptr,
17800 size_t src_len) {
17801 if (dst_palette_len !=
17802 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17803 return 0;
17804 }
17805 size_t dst_len2 = dst_len / 2;
17806 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17807 uint8_t* d = dst_ptr;
17808 const uint8_t* s = src_ptr;
17809 size_t n = len;
17810
17811 // TODO: unroll.
17812
17813 while (n >= 1) {
17814 uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
17815 wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)));
17816 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
17817 ((size_t)s[0] * 4));
17818 wuffs_base__poke_u16le__no_bounds_check(
17819 d + (0 * 2),
17820 wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
17821 wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)));
17822
17823 s += 1 * 1;
17824 d += 1 * 2;
17825 n -= 1;
17826 }
17827
17828 return len;
17829 }
17830
17831 static uint64_t //
wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17832 wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(
17833 uint8_t* dst_ptr,
17834 size_t dst_len,
17835 uint8_t* dst_palette_ptr,
17836 size_t dst_palette_len,
17837 const uint8_t* src_ptr,
17838 size_t src_len) {
17839 if (dst_palette_len !=
17840 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
17841 return 0;
17842 }
17843 size_t dst_len2 = dst_len / 2;
17844 size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
17845 uint8_t* d = dst_ptr;
17846 const uint8_t* s = src_ptr;
17847 size_t n = len;
17848
17849 // TODO: unroll.
17850
17851 while (n >= 1) {
17852 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
17853 ((size_t)s[0] * 4));
17854 if (s0) {
17855 wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0);
17856 }
17857
17858 s += 1 * 1;
17859 d += 1 * 2;
17860 n -= 1;
17861 }
17862
17863 return len;
17864 }
17865
17866 // --------
17867
17868 static uint64_t //
wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17869 wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t* dst_ptr,
17870 size_t dst_len,
17871 uint8_t* dst_palette_ptr,
17872 size_t dst_palette_len,
17873 const uint8_t* src_ptr,
17874 size_t src_len) {
17875 size_t dst_len3 = dst_len / 3;
17876 size_t src_len2 = src_len / 2;
17877 size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
17878 uint8_t* d = dst_ptr;
17879 const uint8_t* s = src_ptr;
17880 size_t n = len;
17881
17882 // TODO: unroll.
17883
17884 while (n >= 1) {
17885 uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
17886 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)));
17887 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17888
17889 s += 1 * 2;
17890 d += 1 * 3;
17891 n -= 1;
17892 }
17893
17894 return len;
17895 }
17896
17897 static uint64_t //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17898 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t* dst_ptr,
17899 size_t dst_len,
17900 uint8_t* dst_palette_ptr,
17901 size_t dst_palette_len,
17902 const uint8_t* src_ptr,
17903 size_t src_len) {
17904 size_t dst_len3 = dst_len / 3;
17905 size_t src_len4 = src_len / 4;
17906 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17907 uint8_t* d = dst_ptr;
17908 const uint8_t* s = src_ptr;
17909 size_t n = len;
17910
17911 // TODO: unroll.
17912
17913 while (n >= 1) {
17914 uint32_t s0 =
17915 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
17916 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
17917 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17918
17919 s += 1 * 4;
17920 d += 1 * 3;
17921 n -= 1;
17922 }
17923
17924 return len;
17925 }
17926
17927 static uint64_t //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17928 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src(
17929 uint8_t* dst_ptr,
17930 size_t dst_len,
17931 uint8_t* dst_palette_ptr,
17932 size_t dst_palette_len,
17933 const uint8_t* src_ptr,
17934 size_t src_len) {
17935 size_t dst_len3 = dst_len / 3;
17936 size_t src_len8 = src_len / 8;
17937 size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
17938 uint8_t* d = dst_ptr;
17939 const uint8_t* s = src_ptr;
17940 size_t n = len;
17941
17942 // TODO: unroll.
17943
17944 while (n >= 1) {
17945 uint32_t s0 =
17946 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
17947 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
17948 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
17949
17950 s += 1 * 8;
17951 d += 1 * 3;
17952 n -= 1;
17953 }
17954
17955 return len;
17956 }
17957
17958 static uint64_t //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)17959 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(
17960 uint8_t* dst_ptr,
17961 size_t dst_len,
17962 uint8_t* dst_palette_ptr,
17963 size_t dst_palette_len,
17964 const uint8_t* src_ptr,
17965 size_t src_len) {
17966 size_t dst_len3 = dst_len / 3;
17967 size_t src_len4 = src_len / 4;
17968 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
17969 uint8_t* d = dst_ptr;
17970 const uint8_t* s = src_ptr;
17971 size_t n = len;
17972
17973 // TODO: unroll.
17974
17975 while (n >= 1) {
17976 // Extract 16-bit color components.
17977 uint32_t dr = 0x101 * ((uint32_t)d[2]);
17978 uint32_t dg = 0x101 * ((uint32_t)d[1]);
17979 uint32_t db = 0x101 * ((uint32_t)d[0]);
17980 uint32_t sa = 0x101 * ((uint32_t)s[3]);
17981 uint32_t sr = 0x101 * ((uint32_t)s[2]);
17982 uint32_t sg = 0x101 * ((uint32_t)s[1]);
17983 uint32_t sb = 0x101 * ((uint32_t)s[0]);
17984
17985 // Calculate the inverse of the src-alpha: how much of the dst to keep.
17986 uint32_t ia = 0xFFFF - sa;
17987
17988 // Composite src (nonpremul) over dst (premul).
17989 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
17990 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
17991 db = ((sb * sa) + (db * ia)) / 0xFFFF;
17992
17993 // Convert from 16-bit color to 8-bit color.
17994 d[0] = (uint8_t)(db >> 8);
17995 d[1] = (uint8_t)(dg >> 8);
17996 d[2] = (uint8_t)(dr >> 8);
17997
17998 s += 1 * 4;
17999 d += 1 * 3;
18000 n -= 1;
18001 }
18002
18003 return len;
18004 }
18005
18006 static uint64_t //
wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18007 wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over(
18008 uint8_t* dst_ptr,
18009 size_t dst_len,
18010 uint8_t* dst_palette_ptr,
18011 size_t dst_palette_len,
18012 const uint8_t* src_ptr,
18013 size_t src_len) {
18014 size_t dst_len3 = dst_len / 3;
18015 size_t src_len8 = src_len / 8;
18016 size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
18017 uint8_t* d = dst_ptr;
18018 const uint8_t* s = src_ptr;
18019 size_t n = len;
18020
18021 // TODO: unroll.
18022
18023 while (n >= 1) {
18024 // Extract 16-bit color components.
18025 uint32_t dr = 0x101 * ((uint32_t)d[2]);
18026 uint32_t dg = 0x101 * ((uint32_t)d[1]);
18027 uint32_t db = 0x101 * ((uint32_t)d[0]);
18028 uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
18029 uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
18030 uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
18031 uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
18032
18033 // Calculate the inverse of the src-alpha: how much of the dst to keep.
18034 uint32_t ia = 0xFFFF - sa;
18035
18036 // Composite src (nonpremul) over dst (premul).
18037 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
18038 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
18039 db = ((sb * sa) + (db * ia)) / 0xFFFF;
18040
18041 // Convert from 16-bit color to 8-bit color.
18042 d[0] = (uint8_t)(db >> 8);
18043 d[1] = (uint8_t)(dg >> 8);
18044 d[2] = (uint8_t)(dr >> 8);
18045
18046 s += 1 * 8;
18047 d += 1 * 3;
18048 n -= 1;
18049 }
18050
18051 return len;
18052 }
18053
18054 static uint64_t //
wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18055 wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t* dst_ptr,
18056 size_t dst_len,
18057 uint8_t* dst_palette_ptr,
18058 size_t dst_palette_len,
18059 const uint8_t* src_ptr,
18060 size_t src_len) {
18061 size_t dst_len3 = dst_len / 3;
18062 size_t src_len4 = src_len / 4;
18063 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18064 uint8_t* d = dst_ptr;
18065 const uint8_t* s = src_ptr;
18066 size_t n = len;
18067
18068 while (n >= 1) {
18069 uint8_t s0 = s[0];
18070 uint8_t s1 = s[1];
18071 uint8_t s2 = s[2];
18072 d[0] = s0;
18073 d[1] = s1;
18074 d[2] = s2;
18075
18076 s += 1 * 4;
18077 d += 1 * 3;
18078 n -= 1;
18079 }
18080
18081 return len;
18082 }
18083
18084 static uint64_t //
wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18085 wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t* dst_ptr,
18086 size_t dst_len,
18087 uint8_t* dst_palette_ptr,
18088 size_t dst_palette_len,
18089 const uint8_t* src_ptr,
18090 size_t src_len) {
18091 size_t dst_len3 = dst_len / 3;
18092 size_t src_len4 = src_len / 4;
18093 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18094 uint8_t* d = dst_ptr;
18095 const uint8_t* s = src_ptr;
18096 size_t n = len;
18097
18098 while (n >= 1) {
18099 // Extract 16-bit color components.
18100 uint32_t dr = 0x101 * ((uint32_t)d[2]);
18101 uint32_t dg = 0x101 * ((uint32_t)d[1]);
18102 uint32_t db = 0x101 * ((uint32_t)d[0]);
18103 uint32_t sa = 0x101 * ((uint32_t)s[3]);
18104 uint32_t sr = 0x101 * ((uint32_t)s[2]);
18105 uint32_t sg = 0x101 * ((uint32_t)s[1]);
18106 uint32_t sb = 0x101 * ((uint32_t)s[0]);
18107
18108 // Calculate the inverse of the src-alpha: how much of the dst to keep.
18109 uint32_t ia = 0xFFFF - sa;
18110
18111 // Composite src (premul) over dst (premul).
18112 dr = sr + ((dr * ia) / 0xFFFF);
18113 dg = sg + ((dg * ia) / 0xFFFF);
18114 db = sb + ((db * ia) / 0xFFFF);
18115
18116 // Convert from 16-bit color to 8-bit color.
18117 d[0] = (uint8_t)(db >> 8);
18118 d[1] = (uint8_t)(dg >> 8);
18119 d[2] = (uint8_t)(dr >> 8);
18120
18121 s += 1 * 4;
18122 d += 1 * 3;
18123 n -= 1;
18124 }
18125
18126 return len;
18127 }
18128
18129 static uint64_t //
wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18130 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t* dst_ptr,
18131 size_t dst_len,
18132 uint8_t* dst_palette_ptr,
18133 size_t dst_palette_len,
18134 const uint8_t* src_ptr,
18135 size_t src_len) {
18136 size_t dst_len3 = dst_len / 3;
18137 size_t src_len4 = src_len / 4;
18138 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18139 uint8_t* d = dst_ptr;
18140 const uint8_t* s = src_ptr;
18141 size_t n = len;
18142
18143 // TODO: unroll.
18144
18145 while (n >= 1) {
18146 uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18147 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
18148 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18149 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
18150
18151 s += 1 * 4;
18152 d += 1 * 3;
18153 n -= 1;
18154 }
18155
18156 return len;
18157 }
18158
18159 static uint64_t //
wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18160 wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over(
18161 uint8_t* dst_ptr,
18162 size_t dst_len,
18163 uint8_t* dst_palette_ptr,
18164 size_t dst_palette_len,
18165 const uint8_t* src_ptr,
18166 size_t src_len) {
18167 size_t dst_len3 = dst_len / 3;
18168 size_t src_len4 = src_len / 4;
18169 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18170 uint8_t* d = dst_ptr;
18171 const uint8_t* s = src_ptr;
18172 size_t n = len;
18173
18174 // TODO: unroll.
18175
18176 while (n >= 1) {
18177 // Extract 16-bit color components.
18178 uint32_t dr = 0x101 * ((uint32_t)d[2]);
18179 uint32_t dg = 0x101 * ((uint32_t)d[1]);
18180 uint32_t db = 0x101 * ((uint32_t)d[0]);
18181 uint32_t sa = 0x101 * ((uint32_t)s[3]);
18182 uint32_t sb = 0x101 * ((uint32_t)s[2]);
18183 uint32_t sg = 0x101 * ((uint32_t)s[1]);
18184 uint32_t sr = 0x101 * ((uint32_t)s[0]);
18185
18186 // Calculate the inverse of the src-alpha: how much of the dst to keep.
18187 uint32_t ia = 0xFFFF - sa;
18188
18189 // Composite src (nonpremul) over dst (premul).
18190 dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
18191 dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
18192 db = ((sb * sa) + (db * ia)) / 0xFFFF;
18193
18194 // Convert from 16-bit color to 8-bit color.
18195 d[0] = (uint8_t)(db >> 8);
18196 d[1] = (uint8_t)(dg >> 8);
18197 d[2] = (uint8_t)(dr >> 8);
18198
18199 s += 1 * 4;
18200 d += 1 * 3;
18201 n -= 1;
18202 }
18203
18204 return len;
18205 }
18206
18207 static uint64_t //
wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18208 wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t* dst_ptr,
18209 size_t dst_len,
18210 uint8_t* dst_palette_ptr,
18211 size_t dst_palette_len,
18212 const uint8_t* src_ptr,
18213 size_t src_len) {
18214 size_t dst_len3 = dst_len / 3;
18215 size_t src_len4 = src_len / 4;
18216 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18217 uint8_t* d = dst_ptr;
18218 const uint8_t* s = src_ptr;
18219 size_t n = len;
18220
18221 while (n >= 1) {
18222 uint8_t s0 = s[0];
18223 uint8_t s1 = s[1];
18224 uint8_t s2 = s[2];
18225 d[0] = s2;
18226 d[1] = s1;
18227 d[2] = s0;
18228
18229 s += 1 * 4;
18230 d += 1 * 3;
18231 n -= 1;
18232 }
18233
18234 return len;
18235 }
18236
18237 static uint64_t //
wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18238 wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t* dst_ptr,
18239 size_t dst_len,
18240 uint8_t* dst_palette_ptr,
18241 size_t dst_palette_len,
18242 const uint8_t* src_ptr,
18243 size_t src_len) {
18244 size_t dst_len3 = dst_len / 3;
18245 size_t src_len4 = src_len / 4;
18246 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
18247 uint8_t* d = dst_ptr;
18248 const uint8_t* s = src_ptr;
18249 size_t n = len;
18250
18251 while (n >= 1) {
18252 // Extract 16-bit color components.
18253 uint32_t dr = 0x101 * ((uint32_t)d[2]);
18254 uint32_t dg = 0x101 * ((uint32_t)d[1]);
18255 uint32_t db = 0x101 * ((uint32_t)d[0]);
18256 uint32_t sa = 0x101 * ((uint32_t)s[3]);
18257 uint32_t sb = 0x101 * ((uint32_t)s[2]);
18258 uint32_t sg = 0x101 * ((uint32_t)s[1]);
18259 uint32_t sr = 0x101 * ((uint32_t)s[0]);
18260
18261 // Calculate the inverse of the src-alpha: how much of the dst to keep.
18262 uint32_t ia = 0xFFFF - sa;
18263
18264 // Composite src (premul) over dst (premul).
18265 dr = sr + ((dr * ia) / 0xFFFF);
18266 dg = sg + ((dg * ia) / 0xFFFF);
18267 db = sb + ((db * ia) / 0xFFFF);
18268
18269 // Convert from 16-bit color to 8-bit color.
18270 d[0] = (uint8_t)(db >> 8);
18271 d[1] = (uint8_t)(dg >> 8);
18272 d[2] = (uint8_t)(dr >> 8);
18273
18274 s += 1 * 4;
18275 d += 1 * 3;
18276 n -= 1;
18277 }
18278
18279 return len;
18280 }
18281
18282 // --------
18283
18284 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18285 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(
18286 uint8_t* dst_ptr,
18287 size_t dst_len,
18288 uint8_t* dst_palette_ptr,
18289 size_t dst_palette_len,
18290 const uint8_t* src_ptr,
18291 size_t src_len) {
18292 size_t dst_len4 = dst_len / 4;
18293 size_t src_len4 = src_len / 4;
18294 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18295 uint8_t* d = dst_ptr;
18296 const uint8_t* s = src_ptr;
18297 size_t n = len;
18298
18299 while (n >= 1) {
18300 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18301 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18302 wuffs_base__poke_u32le__no_bounds_check(
18303 d + (0 * 4),
18304 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
18305
18306 s += 1 * 4;
18307 d += 1 * 4;
18308 n -= 1;
18309 }
18310
18311 return len;
18312 }
18313
18314 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18315 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src(
18316 uint8_t* dst_ptr,
18317 size_t dst_len,
18318 uint8_t* dst_palette_ptr,
18319 size_t dst_palette_len,
18320 const uint8_t* src_ptr,
18321 size_t src_len) {
18322 size_t dst_len4 = dst_len / 4;
18323 size_t src_len8 = src_len / 8;
18324 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18325 uint8_t* d = dst_ptr;
18326 const uint8_t* s = src_ptr;
18327
18328 size_t n = len;
18329 while (n >= 1) {
18330 wuffs_base__poke_u32le__no_bounds_check(
18331 d + (0 * 4), wuffs_base__color_u64__as__color_u32(
18332 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
18333
18334 s += 1 * 8;
18335 d += 1 * 4;
18336 n -= 1;
18337 }
18338 return len;
18339 }
18340
18341 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18342 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over(
18343 uint8_t* dst_ptr,
18344 size_t dst_len,
18345 uint8_t* dst_palette_ptr,
18346 size_t dst_palette_len,
18347 const uint8_t* src_ptr,
18348 size_t src_len) {
18349 size_t dst_len4 = dst_len / 4;
18350 size_t src_len8 = src_len / 8;
18351 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18352 uint8_t* d = dst_ptr;
18353 const uint8_t* s = src_ptr;
18354 size_t n = len;
18355
18356 while (n >= 1) {
18357 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
18358 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
18359 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18360 wuffs_base__poke_u32le__no_bounds_check(
18361 d + (0 * 4),
18362 wuffs_base__color_u64__as__color_u32(
18363 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
18364
18365 s += 1 * 8;
18366 d += 1 * 4;
18367 n -= 1;
18368 }
18369
18370 return len;
18371 }
18372
18373 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18374 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src(
18375 uint8_t* dst_ptr,
18376 size_t dst_len,
18377 uint8_t* dst_palette_ptr,
18378 size_t dst_palette_len,
18379 const uint8_t* src_ptr,
18380 size_t src_len) {
18381 size_t dst_len4 = dst_len / 4;
18382 size_t src_len4 = src_len / 4;
18383 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18384 uint8_t* d = dst_ptr;
18385 const uint8_t* s = src_ptr;
18386 size_t n = len;
18387
18388 while (n >= 1) {
18389 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18390 wuffs_base__poke_u32le__no_bounds_check(
18391 d + (0 * 4),
18392 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
18393
18394 s += 1 * 4;
18395 d += 1 * 4;
18396 n -= 1;
18397 }
18398
18399 return len;
18400 }
18401
18402 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18403 wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over(
18404 uint8_t* dst_ptr,
18405 size_t dst_len,
18406 uint8_t* dst_palette_ptr,
18407 size_t dst_palette_len,
18408 const uint8_t* src_ptr,
18409 size_t src_len) {
18410 size_t dst_len4 = dst_len / 4;
18411 size_t src_len4 = src_len / 4;
18412 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18413 uint8_t* d = dst_ptr;
18414 const uint8_t* s = src_ptr;
18415 size_t n = len;
18416
18417 while (n >= 1) {
18418 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18419 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18420 wuffs_base__poke_u32le__no_bounds_check(
18421 d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
18422
18423 s += 1 * 4;
18424 d += 1 * 4;
18425 n -= 1;
18426 }
18427
18428 return len;
18429 }
18430
18431 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18432 wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over(
18433 uint8_t* dst_ptr,
18434 size_t dst_len,
18435 uint8_t* dst_palette_ptr,
18436 size_t dst_palette_len,
18437 const uint8_t* src_ptr,
18438 size_t src_len) {
18439 if (dst_palette_len !=
18440 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
18441 return 0;
18442 }
18443 size_t dst_len4 = dst_len / 4;
18444 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
18445 uint8_t* d = dst_ptr;
18446 const uint8_t* s = src_ptr;
18447 size_t n = len;
18448
18449 // TODO: unroll.
18450
18451 while (n >= 1) {
18452 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18453 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
18454 ((size_t)s[0] * 4));
18455 wuffs_base__poke_u32le__no_bounds_check(
18456 d + (0 * 4),
18457 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
18458
18459 s += 1 * 1;
18460 d += 1 * 4;
18461 n -= 1;
18462 }
18463
18464 return len;
18465 }
18466
18467 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18468 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over(
18469 uint8_t* dst_ptr,
18470 size_t dst_len,
18471 uint8_t* dst_palette_ptr,
18472 size_t dst_palette_len,
18473 const uint8_t* src_ptr,
18474 size_t src_len) {
18475 size_t dst_len4 = dst_len / 4;
18476 size_t src_len4 = src_len / 4;
18477 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18478 uint8_t* d = dst_ptr;
18479 const uint8_t* s = src_ptr;
18480 size_t n = len;
18481
18482 while (n >= 1) {
18483 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18484 uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18485 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18486 wuffs_base__poke_u32le__no_bounds_check(
18487 d + (0 * 4),
18488 wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
18489
18490 s += 1 * 4;
18491 d += 1 * 4;
18492 n -= 1;
18493 }
18494
18495 return len;
18496 }
18497
18498 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18499 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src(
18500 uint8_t* dst_ptr,
18501 size_t dst_len,
18502 uint8_t* dst_palette_ptr,
18503 size_t dst_palette_len,
18504 const uint8_t* src_ptr,
18505 size_t src_len) {
18506 size_t dst_len4 = dst_len / 4;
18507 size_t src_len4 = src_len / 4;
18508 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18509 uint8_t* d = dst_ptr;
18510 const uint8_t* s = src_ptr;
18511 size_t n = len;
18512
18513 while (n >= 1) {
18514 uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18515 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18516 wuffs_base__poke_u32le__no_bounds_check(
18517 d + (0 * 4),
18518 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
18519
18520 s += 1 * 4;
18521 d += 1 * 4;
18522 n -= 1;
18523 }
18524
18525 return len;
18526 }
18527
18528 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18529 wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over(
18530 uint8_t* dst_ptr,
18531 size_t dst_len,
18532 uint8_t* dst_palette_ptr,
18533 size_t dst_palette_len,
18534 const uint8_t* src_ptr,
18535 size_t src_len) {
18536 size_t dst_len4 = dst_len / 4;
18537 size_t src_len4 = src_len / 4;
18538 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18539 uint8_t* d = dst_ptr;
18540 const uint8_t* s = src_ptr;
18541 size_t n = len;
18542
18543 while (n >= 1) {
18544 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18545 uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
18546 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18547 wuffs_base__poke_u32le__no_bounds_check(
18548 d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
18549
18550 s += 1 * 4;
18551 d += 1 * 4;
18552 n -= 1;
18553 }
18554
18555 return len;
18556 }
18557
18558 // --------
18559
18560 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18561 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src(
18562 uint8_t* dst_ptr,
18563 size_t dst_len,
18564 uint8_t* dst_palette_ptr,
18565 size_t dst_palette_len,
18566 const uint8_t* src_ptr,
18567 size_t src_len) {
18568 size_t dst_len8 = dst_len / 8;
18569 size_t src_len4 = src_len / 4;
18570 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18571 uint8_t* d = dst_ptr;
18572 const uint8_t* s = src_ptr;
18573
18574 size_t n = len;
18575 while (n >= 1) {
18576 uint8_t s0 = s[0];
18577 uint8_t s1 = s[1];
18578 uint8_t s2 = s[2];
18579 uint8_t s3 = s[3];
18580 d[0] = s0;
18581 d[1] = s0;
18582 d[2] = s1;
18583 d[3] = s1;
18584 d[4] = s2;
18585 d[5] = s2;
18586 d[6] = s3;
18587 d[7] = s3;
18588
18589 s += 1 * 4;
18590 d += 1 * 8;
18591 n -= 1;
18592 }
18593 return len;
18594 }
18595
18596 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18597 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over(
18598 uint8_t* dst_ptr,
18599 size_t dst_len,
18600 uint8_t* dst_palette_ptr,
18601 size_t dst_palette_len,
18602 const uint8_t* src_ptr,
18603 size_t src_len) {
18604 size_t dst_len8 = dst_len / 8;
18605 size_t src_len4 = src_len / 4;
18606 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18607 uint8_t* d = dst_ptr;
18608 const uint8_t* s = src_ptr;
18609
18610 size_t n = len;
18611 while (n >= 1) {
18612 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18613 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18614 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18615 wuffs_base__poke_u64le__no_bounds_check(
18616 d + (0 * 8),
18617 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18618
18619 s += 1 * 4;
18620 d += 1 * 8;
18621 n -= 1;
18622 }
18623 return len;
18624 }
18625
18626 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18627 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(
18628 uint8_t* dst_ptr,
18629 size_t dst_len,
18630 uint8_t* dst_palette_ptr,
18631 size_t dst_palette_len,
18632 const uint8_t* src_ptr,
18633 size_t src_len) {
18634 size_t dst_len8 = dst_len / 8;
18635 size_t src_len8 = src_len / 8;
18636 size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
18637 uint8_t* d = dst_ptr;
18638 const uint8_t* s = src_ptr;
18639
18640 size_t n = len;
18641 while (n >= 1) {
18642 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18643 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18644 wuffs_base__poke_u64le__no_bounds_check(
18645 d + (0 * 8),
18646 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18647
18648 s += 1 * 8;
18649 d += 1 * 8;
18650 n -= 1;
18651 }
18652 return len;
18653 }
18654
18655 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18656 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src(
18657 uint8_t* dst_ptr,
18658 size_t dst_len,
18659 uint8_t* dst_palette_ptr,
18660 size_t dst_palette_len,
18661 const uint8_t* src_ptr,
18662 size_t src_len) {
18663 size_t dst_len8 = dst_len / 8;
18664 size_t src_len4 = src_len / 4;
18665 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18666 uint8_t* d = dst_ptr;
18667 const uint8_t* s = src_ptr;
18668
18669 size_t n = len;
18670 while (n >= 1) {
18671 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18672 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
18673 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18674 wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
18675
18676 s += 1 * 4;
18677 d += 1 * 8;
18678 n -= 1;
18679 }
18680 return len;
18681 }
18682
18683 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18684 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over(
18685 uint8_t* dst_ptr,
18686 size_t dst_len,
18687 uint8_t* dst_palette_ptr,
18688 size_t dst_palette_len,
18689 const uint8_t* src_ptr,
18690 size_t src_len) {
18691 size_t dst_len8 = dst_len / 8;
18692 size_t src_len4 = src_len / 4;
18693 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18694 uint8_t* d = dst_ptr;
18695 const uint8_t* s = src_ptr;
18696
18697 size_t n = len;
18698 while (n >= 1) {
18699 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18700 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18701 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
18702 wuffs_base__poke_u64le__no_bounds_check(
18703 d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
18704
18705 s += 1 * 4;
18706 d += 1 * 8;
18707 n -= 1;
18708 }
18709 return len;
18710 }
18711
18712 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18713 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(
18714 uint8_t* dst_ptr,
18715 size_t dst_len,
18716 uint8_t* dst_palette_ptr,
18717 size_t dst_palette_len,
18718 const uint8_t* src_ptr,
18719 size_t src_len) {
18720 if (dst_palette_len !=
18721 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
18722 return 0;
18723 }
18724 size_t dst_len8 = dst_len / 8;
18725 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
18726 uint8_t* d = dst_ptr;
18727 const uint8_t* s = src_ptr;
18728 size_t n = len;
18729
18730 while (n >= 1) {
18731 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18732 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18733 wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
18734 ((size_t)s[0] * 4)));
18735 wuffs_base__poke_u64le__no_bounds_check(
18736 d + (0 * 8),
18737 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18738
18739 s += 1 * 1;
18740 d += 1 * 8;
18741 n -= 1;
18742 }
18743
18744 return len;
18745 }
18746
18747 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18748 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src(
18749 uint8_t* dst_ptr,
18750 size_t dst_len,
18751 uint8_t* dst_palette_ptr,
18752 size_t dst_palette_len,
18753 const uint8_t* src_ptr,
18754 size_t src_len) {
18755 size_t dst_len8 = dst_len / 8;
18756 size_t src_len4 = src_len / 4;
18757 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18758 uint8_t* d = dst_ptr;
18759 const uint8_t* s = src_ptr;
18760
18761 size_t n = len;
18762 while (n >= 1) {
18763 uint8_t s0 = s[0];
18764 uint8_t s1 = s[1];
18765 uint8_t s2 = s[2];
18766 uint8_t s3 = s[3];
18767 d[0] = s2;
18768 d[1] = s2;
18769 d[2] = s1;
18770 d[3] = s1;
18771 d[4] = s0;
18772 d[5] = s0;
18773 d[6] = s3;
18774 d[7] = s3;
18775
18776 s += 1 * 4;
18777 d += 1 * 8;
18778 n -= 1;
18779 }
18780 return len;
18781 }
18782
18783 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18784 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over(
18785 uint8_t* dst_ptr,
18786 size_t dst_len,
18787 uint8_t* dst_palette_ptr,
18788 size_t dst_palette_len,
18789 const uint8_t* src_ptr,
18790 size_t src_len) {
18791 size_t dst_len8 = dst_len / 8;
18792 size_t src_len4 = src_len / 4;
18793 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18794 uint8_t* d = dst_ptr;
18795 const uint8_t* s = src_ptr;
18796
18797 size_t n = len;
18798 while (n >= 1) {
18799 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18800 uint64_t s0 =
18801 wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
18802 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18803 wuffs_base__poke_u64le__no_bounds_check(
18804 d + (0 * 8),
18805 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
18806
18807 s += 1 * 4;
18808 d += 1 * 8;
18809 n -= 1;
18810 }
18811 return len;
18812 }
18813
18814 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18815 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src(
18816 uint8_t* dst_ptr,
18817 size_t dst_len,
18818 uint8_t* dst_palette_ptr,
18819 size_t dst_palette_len,
18820 const uint8_t* src_ptr,
18821 size_t src_len) {
18822 size_t dst_len8 = dst_len / 8;
18823 size_t src_len4 = src_len / 4;
18824 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18825 uint8_t* d = dst_ptr;
18826 const uint8_t* s = src_ptr;
18827
18828 size_t n = len;
18829 while (n >= 1) {
18830 uint64_t s0 = wuffs_base__color_u32__as__color_u64(
18831 wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
18832 wuffs_base__swap_u32_argb_abgr(
18833 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
18834 wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
18835
18836 s += 1 * 4;
18837 d += 1 * 8;
18838 n -= 1;
18839 }
18840 return len;
18841 }
18842
18843 static uint64_t //
wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18844 wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over(
18845 uint8_t* dst_ptr,
18846 size_t dst_len,
18847 uint8_t* dst_palette_ptr,
18848 size_t dst_palette_len,
18849 const uint8_t* src_ptr,
18850 size_t src_len) {
18851 size_t dst_len8 = dst_len / 8;
18852 size_t src_len4 = src_len / 4;
18853 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
18854 uint8_t* d = dst_ptr;
18855 const uint8_t* s = src_ptr;
18856
18857 size_t n = len;
18858 while (n >= 1) {
18859 uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
18860 uint64_t s0 =
18861 wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
18862 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
18863 wuffs_base__poke_u64le__no_bounds_check(
18864 d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
18865
18866 s += 1 * 4;
18867 d += 1 * 8;
18868 n -= 1;
18869 }
18870 return len;
18871 }
18872
18873 // --------
18874
18875 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18876 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
18877 uint8_t* dst_ptr,
18878 size_t dst_len,
18879 uint8_t* dst_palette_ptr,
18880 size_t dst_palette_len,
18881 const uint8_t* src_ptr,
18882 size_t src_len) {
18883 size_t dst_len4 = dst_len / 4;
18884 size_t src_len4 = src_len / 4;
18885 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18886 uint8_t* d = dst_ptr;
18887 const uint8_t* s = src_ptr;
18888 size_t n = len;
18889
18890 // TODO: unroll.
18891
18892 while (n >= 1) {
18893 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18894 wuffs_base__poke_u32le__no_bounds_check(
18895 d + (0 * 4),
18896 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
18897
18898 s += 1 * 4;
18899 d += 1 * 4;
18900 n -= 1;
18901 }
18902
18903 return len;
18904 }
18905
18906 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18907 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src(
18908 uint8_t* dst_ptr,
18909 size_t dst_len,
18910 uint8_t* dst_palette_ptr,
18911 size_t dst_palette_len,
18912 const uint8_t* src_ptr,
18913 size_t src_len) {
18914 size_t dst_len4 = dst_len / 4;
18915 size_t src_len8 = src_len / 8;
18916 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18917 uint8_t* d = dst_ptr;
18918 const uint8_t* s = src_ptr;
18919 size_t n = len;
18920
18921 // TODO: unroll.
18922
18923 while (n >= 1) {
18924 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18925 wuffs_base__poke_u32le__no_bounds_check(
18926 d + (0 * 4),
18927 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0));
18928
18929 s += 1 * 8;
18930 d += 1 * 4;
18931 n -= 1;
18932 }
18933
18934 return len;
18935 }
18936
18937 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18938 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(
18939 uint8_t* dst_ptr,
18940 size_t dst_len,
18941 uint8_t* dst_palette_ptr,
18942 size_t dst_palette_len,
18943 const uint8_t* src_ptr,
18944 size_t src_len) {
18945 size_t dst_len4 = dst_len / 4;
18946 size_t src_len4 = src_len / 4;
18947 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
18948 uint8_t* d = dst_ptr;
18949 const uint8_t* s = src_ptr;
18950 size_t n = len;
18951
18952 // TODO: unroll.
18953
18954 while (n >= 1) {
18955 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
18956 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
18957 wuffs_base__poke_u32le__no_bounds_check(
18958 d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
18959
18960 s += 1 * 4;
18961 d += 1 * 4;
18962 n -= 1;
18963 }
18964
18965 return len;
18966 }
18967
18968 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)18969 wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over(
18970 uint8_t* dst_ptr,
18971 size_t dst_len,
18972 uint8_t* dst_palette_ptr,
18973 size_t dst_palette_len,
18974 const uint8_t* src_ptr,
18975 size_t src_len) {
18976 size_t dst_len4 = dst_len / 4;
18977 size_t src_len8 = src_len / 8;
18978 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
18979 uint8_t* d = dst_ptr;
18980 const uint8_t* s = src_ptr;
18981 size_t n = len;
18982
18983 // TODO: unroll.
18984
18985 while (n >= 1) {
18986 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
18987 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
18988 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
18989 wuffs_base__poke_u32le__no_bounds_check(
18990 d + (0 * 4),
18991 wuffs_base__color_u64__as__color_u32(
18992 wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
18993
18994 s += 1 * 8;
18995 d += 1 * 4;
18996 n -= 1;
18997 }
18998
18999 return len;
19000 }
19001
19002 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19003 wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over(
19004 uint8_t* dst_ptr,
19005 size_t dst_len,
19006 uint8_t* dst_palette_ptr,
19007 size_t dst_palette_len,
19008 const uint8_t* src_ptr,
19009 size_t src_len) {
19010 size_t dst_len4 = dst_len / 4;
19011 size_t src_len4 = src_len / 4;
19012 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19013 uint8_t* d = dst_ptr;
19014 const uint8_t* s = src_ptr;
19015 size_t n = len;
19016
19017 // TODO: unroll.
19018
19019 while (n >= 1) {
19020 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19021 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
19022 wuffs_base__poke_u32le__no_bounds_check(
19023 d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
19024
19025 s += 1 * 4;
19026 d += 1 * 4;
19027 n -= 1;
19028 }
19029
19030 return len;
19031 }
19032
19033 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19034 wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over(
19035 uint8_t* dst_ptr,
19036 size_t dst_len,
19037 uint8_t* dst_palette_ptr,
19038 size_t dst_palette_len,
19039 const uint8_t* src_ptr,
19040 size_t src_len) {
19041 if (dst_palette_len !=
19042 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19043 return 0;
19044 }
19045 size_t dst_len4 = dst_len / 4;
19046 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19047 uint8_t* d = dst_ptr;
19048 const uint8_t* s = src_ptr;
19049 size_t n = len;
19050
19051 // TODO: unroll.
19052
19053 while (n >= 1) {
19054 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19055 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19056 ((size_t)s[0] * 4));
19057 wuffs_base__poke_u32le__no_bounds_check(
19058 d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
19059
19060 s += 1 * 1;
19061 d += 1 * 4;
19062 n -= 1;
19063 }
19064
19065 return len;
19066 }
19067
19068 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19069 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
19070 uint8_t* dst_ptr,
19071 size_t dst_len,
19072 uint8_t* dst_palette_ptr,
19073 size_t dst_palette_len,
19074 const uint8_t* src_ptr,
19075 size_t src_len) {
19076 size_t dst_len4 = dst_len / 4;
19077 size_t src_len4 = src_len / 4;
19078 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19079 uint8_t* d = dst_ptr;
19080 const uint8_t* s = src_ptr;
19081 size_t n = len;
19082
19083 // TODO: unroll.
19084
19085 while (n >= 1) {
19086 uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
19087 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19088 wuffs_base__poke_u32le__no_bounds_check(
19089 d + (0 * 4),
19090 wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
19091
19092 s += 1 * 4;
19093 d += 1 * 4;
19094 n -= 1;
19095 }
19096
19097 return len;
19098 }
19099
19100 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19101 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over(
19102 uint8_t* dst_ptr,
19103 size_t dst_len,
19104 uint8_t* dst_palette_ptr,
19105 size_t dst_palette_len,
19106 const uint8_t* src_ptr,
19107 size_t src_len) {
19108 size_t dst_len4 = dst_len / 4;
19109 size_t src_len4 = src_len / 4;
19110 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19111 uint8_t* d = dst_ptr;
19112 const uint8_t* s = src_ptr;
19113 size_t n = len;
19114
19115 // TODO: unroll.
19116
19117 while (n >= 1) {
19118 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19119 uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
19120 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19121 wuffs_base__poke_u32le__no_bounds_check(
19122 d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
19123
19124 s += 1 * 4;
19125 d += 1 * 4;
19126 n -= 1;
19127 }
19128
19129 return len;
19130 }
19131
19132 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19133 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src(
19134 uint8_t* dst_ptr,
19135 size_t dst_len,
19136 uint8_t* dst_palette_ptr,
19137 size_t dst_palette_len,
19138 const uint8_t* src_ptr,
19139 size_t src_len) {
19140 size_t dst_len4 = dst_len / 4;
19141 size_t src_len8 = src_len / 8;
19142 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19143 uint8_t* d = dst_ptr;
19144 const uint8_t* s = src_ptr;
19145 size_t n = len;
19146
19147 // TODO: unroll.
19148
19149 while (n >= 1) {
19150 uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
19151 wuffs_base__poke_u32le__no_bounds_check(
19152 d + (0 * 4),
19153 wuffs_base__swap_u32_argb_abgr(
19154 wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
19155 s0)));
19156
19157 s += 1 * 8;
19158 d += 1 * 4;
19159 n -= 1;
19160 }
19161
19162 return len;
19163 }
19164
19165 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19166 wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over(
19167 uint8_t* dst_ptr,
19168 size_t dst_len,
19169 uint8_t* dst_palette_ptr,
19170 size_t dst_palette_len,
19171 const uint8_t* src_ptr,
19172 size_t src_len) {
19173 size_t dst_len4 = dst_len / 4;
19174 size_t src_len8 = src_len / 8;
19175 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19176 uint8_t* d = dst_ptr;
19177 const uint8_t* s = src_ptr;
19178 size_t n = len;
19179
19180 // TODO: unroll.
19181
19182 while (n >= 1) {
19183 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
19184 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
19185 uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
19186 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
19187 wuffs_base__poke_u32le__no_bounds_check(
19188 d + (0 * 4),
19189 wuffs_base__color_u64__as__color_u32(
19190 wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
19191
19192 s += 1 * 8;
19193 d += 1 * 4;
19194 n -= 1;
19195 }
19196
19197 return len;
19198 }
19199
19200 static uint64_t //
wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19201 wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over(
19202 uint8_t* dst_ptr,
19203 size_t dst_len,
19204 uint8_t* dst_palette_ptr,
19205 size_t dst_palette_len,
19206 const uint8_t* src_ptr,
19207 size_t src_len) {
19208 size_t dst_len4 = dst_len / 4;
19209 size_t src_len4 = src_len / 4;
19210 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19211 uint8_t* d = dst_ptr;
19212 const uint8_t* s = src_ptr;
19213 size_t n = len;
19214
19215 while (n >= 1) {
19216 uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
19217 uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
19218 wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19219 wuffs_base__poke_u32le__no_bounds_check(
19220 d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
19221
19222 s += 1 * 4;
19223 d += 1 * 4;
19224 n -= 1;
19225 }
19226
19227 return len;
19228 }
19229
19230 // --------
19231
19232 static uint64_t //
wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19233 wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr,
19234 size_t dst_len,
19235 uint8_t* dst_palette_ptr,
19236 size_t dst_palette_len,
19237 const uint8_t* src_ptr,
19238 size_t src_len) {
19239 size_t dst_len4 = dst_len / 4;
19240 size_t src_len3 = src_len / 3;
19241 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
19242 uint8_t* d = dst_ptr;
19243 const uint8_t* s = src_ptr;
19244 size_t n = len;
19245
19246 // TODO: unroll.
19247
19248 while (n >= 1) {
19249 wuffs_base__poke_u32le__no_bounds_check(
19250 d + (0 * 4),
19251 0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3)));
19252
19253 s += 1 * 3;
19254 d += 1 * 4;
19255 n -= 1;
19256 }
19257
19258 return len;
19259 }
19260
19261 static uint64_t //
wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19262 wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr,
19263 size_t dst_len,
19264 uint8_t* dst_palette_ptr,
19265 size_t dst_palette_len,
19266 const uint8_t* src_ptr,
19267 size_t src_len) {
19268 size_t dst_len4 = dst_len / 4;
19269 size_t src_len2 = src_len / 2;
19270 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
19271 uint8_t* d = dst_ptr;
19272 const uint8_t* s = src_ptr;
19273 size_t n = len;
19274
19275 // TODO: unroll.
19276
19277 while (n >= 1) {
19278 wuffs_base__poke_u32le__no_bounds_check(
19279 d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19280 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))));
19281
19282 s += 1 * 2;
19283 d += 1 * 4;
19284 n -= 1;
19285 }
19286
19287 return len;
19288 }
19289
19290 static uint64_t //
wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19291 wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t* dst_ptr,
19292 size_t dst_len,
19293 uint8_t* dst_palette_ptr,
19294 size_t dst_palette_len,
19295 const uint8_t* src_ptr,
19296 size_t src_len) {
19297 size_t dst_len4 = dst_len / 4;
19298 size_t src_len4 = src_len / 4;
19299 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19300 uint8_t* d = dst_ptr;
19301 const uint8_t* s = src_ptr;
19302 size_t n = len;
19303
19304 // TODO: unroll.
19305
19306 while (n >= 1) {
19307 wuffs_base__poke_u32le__no_bounds_check(
19308 d + (0 * 4),
19309 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19310
19311 s += 1 * 4;
19312 d += 1 * 4;
19313 n -= 1;
19314 }
19315
19316 return len;
19317 }
19318
19319 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
19320 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19321 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
19322 static uint64_t //
wuffs_base__pixel_swizzler__bgrw__rgb__sse42(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19323 wuffs_base__pixel_swizzler__bgrw__rgb__sse42(uint8_t* dst_ptr,
19324 size_t dst_len,
19325 uint8_t* dst_palette_ptr,
19326 size_t dst_palette_len,
19327 const uint8_t* src_ptr,
19328 size_t src_len) {
19329 size_t dst_len4 = dst_len / 4;
19330 size_t src_len3 = src_len / 3;
19331 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
19332 uint8_t* d = dst_ptr;
19333 const uint8_t* s = src_ptr;
19334 size_t n = len;
19335
19336 __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B, //
19337 +0x00, +0x06, +0x07, +0x08, //
19338 +0x00, +0x03, +0x04, +0x05, //
19339 +0x00, +0x00, +0x01, +0x02);
19340 __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, //
19341 -0x01, +0x00, +0x00, +0x00, //
19342 -0x01, +0x00, +0x00, +0x00, //
19343 -0x01, +0x00, +0x00, +0x00);
19344
19345 while (n >= 6) {
19346 __m128i x;
19347 x = _mm_lddqu_si128((const __m128i*)(const void*)s);
19348 x = _mm_shuffle_epi8(x, shuffle);
19349 x = _mm_or_si128(x, or_ff);
19350 _mm_storeu_si128((__m128i*)(void*)d, x);
19351
19352 s += 4 * 3;
19353 d += 4 * 4;
19354 n -= 4;
19355 }
19356
19357 while (n >= 1) {
19358 uint8_t b0 = s[0];
19359 uint8_t b1 = s[1];
19360 uint8_t b2 = s[2];
19361 d[0] = b2;
19362 d[1] = b1;
19363 d[2] = b0;
19364 d[3] = 0xFF;
19365
19366 s += 1 * 3;
19367 d += 1 * 4;
19368 n -= 1;
19369 }
19370
19371 return len;
19372 }
19373 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
19374 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
19375
19376 static uint64_t //
wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19377 wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t* dst_ptr,
19378 size_t dst_len,
19379 uint8_t* dst_palette_ptr,
19380 size_t dst_palette_len,
19381 const uint8_t* src_ptr,
19382 size_t src_len) {
19383 size_t dst_len4 = dst_len / 4;
19384 size_t src_len3 = src_len / 3;
19385 size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
19386 uint8_t* d = dst_ptr;
19387 const uint8_t* s = src_ptr;
19388 size_t n = len;
19389
19390 while (n >= 1) {
19391 uint8_t b0 = s[0];
19392 uint8_t b1 = s[1];
19393 uint8_t b2 = s[2];
19394 d[0] = b2;
19395 d[1] = b1;
19396 d[2] = b0;
19397 d[3] = 0xFF;
19398
19399 s += 1 * 3;
19400 d += 1 * 4;
19401 n -= 1;
19402 }
19403
19404 return len;
19405 }
19406
19407 static uint64_t //
wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19408 wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t* dst_ptr,
19409 size_t dst_len,
19410 uint8_t* dst_palette_ptr,
19411 size_t dst_palette_len,
19412 const uint8_t* src_ptr,
19413 size_t src_len) {
19414 size_t dst_len4 = dst_len / 4;
19415 size_t src_len4 = src_len / 4;
19416 size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
19417 uint8_t* d = dst_ptr;
19418 const uint8_t* s = src_ptr;
19419 size_t n = len;
19420
19421 // TODO: unroll.
19422
19423 while (n >= 1) {
19424 uint8_t b0 = s[0];
19425 uint8_t b1 = s[1];
19426 uint8_t b2 = s[2];
19427 d[0] = b2;
19428 d[1] = b1;
19429 d[2] = b0;
19430 d[3] = 0xFF;
19431
19432 s += 1 * 4;
19433 d += 1 * 4;
19434 n -= 1;
19435 }
19436
19437 return len;
19438 }
19439
19440 // --------
19441
19442 static uint64_t //
wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19443 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t* dst_ptr,
19444 size_t dst_len,
19445 uint8_t* dst_palette_ptr,
19446 size_t dst_palette_len,
19447 const uint8_t* src_ptr,
19448 size_t src_len) {
19449 size_t dst_len8 = dst_len / 8;
19450 size_t src_len3 = src_len / 3;
19451 size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
19452 uint8_t* d = dst_ptr;
19453 const uint8_t* s = src_ptr;
19454 size_t n = len;
19455
19456 while (n >= 1) {
19457 uint8_t s0 = s[0];
19458 uint8_t s1 = s[1];
19459 uint8_t s2 = s[2];
19460 d[0] = s0;
19461 d[1] = s0;
19462 d[2] = s1;
19463 d[3] = s1;
19464 d[4] = s2;
19465 d[5] = s2;
19466 d[6] = 0xFF;
19467 d[7] = 0xFF;
19468
19469 s += 1 * 3;
19470 d += 1 * 8;
19471 n -= 1;
19472 }
19473
19474 return len;
19475 }
19476
19477 static uint64_t //
wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19478 wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t* dst_ptr,
19479 size_t dst_len,
19480 uint8_t* dst_palette_ptr,
19481 size_t dst_palette_len,
19482 const uint8_t* src_ptr,
19483 size_t src_len) {
19484 size_t dst_len8 = dst_len / 8;
19485 size_t src_len2 = src_len / 2;
19486 size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
19487 uint8_t* d = dst_ptr;
19488 const uint8_t* s = src_ptr;
19489 size_t n = len;
19490
19491 while (n >= 1) {
19492 wuffs_base__poke_u64le__no_bounds_check(
19493 d + (0 * 8),
19494 wuffs_base__color_u32__as__color_u64(
19495 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19496 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
19497
19498 s += 1 * 2;
19499 d += 1 * 8;
19500 n -= 1;
19501 }
19502
19503 return len;
19504 }
19505
19506 static uint64_t //
wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19507 wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t* dst_ptr,
19508 size_t dst_len,
19509 uint8_t* dst_palette_ptr,
19510 size_t dst_palette_len,
19511 const uint8_t* src_ptr,
19512 size_t src_len) {
19513 size_t dst_len8 = dst_len / 8;
19514 size_t src_len4 = src_len / 4;
19515 size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
19516 uint8_t* d = dst_ptr;
19517 const uint8_t* s = src_ptr;
19518 size_t n = len;
19519
19520 while (n >= 1) {
19521 uint8_t s0 = s[0];
19522 uint8_t s1 = s[1];
19523 uint8_t s2 = s[2];
19524 d[0] = s0;
19525 d[1] = s0;
19526 d[2] = s1;
19527 d[3] = s1;
19528 d[4] = s2;
19529 d[5] = s2;
19530 d[6] = 0xFF;
19531 d[7] = 0xFF;
19532
19533 s += 1 * 4;
19534 d += 1 * 8;
19535 n -= 1;
19536 }
19537
19538 return len;
19539 }
19540
19541 static uint64_t //
wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19542 wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t* dst_ptr,
19543 size_t dst_len,
19544 uint8_t* dst_palette_ptr,
19545 size_t dst_palette_len,
19546 const uint8_t* src_ptr,
19547 size_t src_len) {
19548 size_t dst_len8 = dst_len / 8;
19549 size_t src_len3 = src_len / 3;
19550 size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
19551 uint8_t* d = dst_ptr;
19552 const uint8_t* s = src_ptr;
19553 size_t n = len;
19554
19555 while (n >= 1) {
19556 uint8_t s0 = s[0];
19557 uint8_t s1 = s[1];
19558 uint8_t s2 = s[2];
19559 d[0] = s2;
19560 d[1] = s2;
19561 d[2] = s1;
19562 d[3] = s1;
19563 d[4] = s0;
19564 d[5] = s0;
19565 d[6] = 0xFF;
19566 d[7] = 0xFF;
19567
19568 s += 1 * 3;
19569 d += 1 * 8;
19570 n -= 1;
19571 }
19572
19573 return len;
19574 }
19575
19576 // --------
19577
19578 static uint64_t //
wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19579 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src(
19580 uint8_t* dst_ptr,
19581 size_t dst_len,
19582 uint8_t* dst_palette_ptr,
19583 size_t dst_palette_len,
19584 const uint8_t* src_ptr,
19585 size_t src_len) {
19586 size_t dst_len4 = dst_len / 4;
19587 size_t src_len8 = src_len / 8;
19588 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19589 uint8_t* d = dst_ptr;
19590 const uint8_t* s = src_ptr;
19591
19592 size_t n = len;
19593 while (n >= 1) {
19594 wuffs_base__poke_u32le__no_bounds_check(
19595 d + (0 * 4), wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(
19596 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
19597
19598 s += 1 * 8;
19599 d += 1 * 4;
19600 n -= 1;
19601 }
19602 return len;
19603 }
19604
19605 static uint64_t //
wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19606 wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over(
19607 uint8_t* dst_ptr,
19608 size_t dst_len,
19609 uint8_t* dst_palette_ptr,
19610 size_t dst_palette_len,
19611 const uint8_t* src_ptr,
19612 size_t src_len) {
19613 size_t dst_len4 = dst_len / 4;
19614 size_t src_len8 = src_len / 8;
19615 size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
19616 uint8_t* d = dst_ptr;
19617 const uint8_t* s = src_ptr;
19618 size_t n = len;
19619
19620 while (n >= 1) {
19621 uint64_t d0 = wuffs_base__color_u32__as__color_u64(
19622 wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
19623 uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
19624 wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
19625 wuffs_base__poke_u32le__no_bounds_check(
19626 d + (0 * 4),
19627 wuffs_base__color_u64__as__color_u32(
19628 wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
19629
19630 s += 1 * 8;
19631 d += 1 * 4;
19632 n -= 1;
19633 }
19634
19635 return len;
19636 }
19637
19638 // --------
19639
19640 static uint64_t //
wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19641 wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t* dst_ptr,
19642 size_t dst_len,
19643 uint8_t* dst_palette_ptr,
19644 size_t dst_palette_len,
19645 const uint8_t* src_ptr,
19646 size_t src_len) {
19647 size_t dst_len4 = dst_len / 4;
19648 size_t src_len2 = src_len / 2;
19649 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
19650 uint8_t* d = dst_ptr;
19651 const uint8_t* s = src_ptr;
19652 size_t n = len;
19653
19654 // TODO: unroll.
19655
19656 while (n >= 1) {
19657 wuffs_base__poke_u32le__no_bounds_check(
19658 d + (0 * 4),
19659 wuffs_base__swap_u32_argb_abgr(
19660 wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
19661 wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
19662
19663 s += 1 * 2;
19664 d += 1 * 4;
19665 n -= 1;
19666 }
19667
19668 return len;
19669 }
19670
19671 // --------
19672
19673 static uint64_t //
wuffs_base__pixel_swizzler__xxx__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19674 wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr,
19675 size_t dst_len,
19676 uint8_t* dst_palette_ptr,
19677 size_t dst_palette_len,
19678 const uint8_t* src_ptr,
19679 size_t src_len) {
19680 if (dst_palette_len !=
19681 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19682 return 0;
19683 }
19684 size_t dst_len3 = dst_len / 3;
19685 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19686 uint8_t* d = dst_ptr;
19687 const uint8_t* s = src_ptr;
19688 size_t n = len;
19689
19690 const size_t loop_unroll_count = 4;
19691
19692 // The comparison in the while condition is ">", not ">=", because with
19693 // ">=", the last 4-byte store could write past the end of the dst slice.
19694 //
19695 // Each 4-byte store writes one too many bytes, but a subsequent store
19696 // will overwrite that with the correct byte. There is always another
19697 // store, whether a 4-byte store in this loop or a 1-byte store in the
19698 // next loop.
19699 while (n > loop_unroll_count) {
19700 wuffs_base__poke_u32le__no_bounds_check(
19701 d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(
19702 dst_palette_ptr + ((size_t)s[0] * 4)));
19703 wuffs_base__poke_u32le__no_bounds_check(
19704 d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check(
19705 dst_palette_ptr + ((size_t)s[1] * 4)));
19706 wuffs_base__poke_u32le__no_bounds_check(
19707 d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check(
19708 dst_palette_ptr + ((size_t)s[2] * 4)));
19709 wuffs_base__poke_u32le__no_bounds_check(
19710 d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check(
19711 dst_palette_ptr + ((size_t)s[3] * 4)));
19712
19713 s += loop_unroll_count * 1;
19714 d += loop_unroll_count * 3;
19715 n -= loop_unroll_count;
19716 }
19717
19718 while (n >= 1) {
19719 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19720 ((size_t)s[0] * 4));
19721 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19722
19723 s += 1 * 1;
19724 d += 1 * 3;
19725 n -= 1;
19726 }
19727
19728 return len;
19729 }
19730
19731 static uint64_t //
wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19732 wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over(
19733 uint8_t* dst_ptr,
19734 size_t dst_len,
19735 uint8_t* dst_palette_ptr,
19736 size_t dst_palette_len,
19737 const uint8_t* src_ptr,
19738 size_t src_len) {
19739 if (dst_palette_len !=
19740 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19741 return 0;
19742 }
19743 size_t dst_len3 = dst_len / 3;
19744 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19745 uint8_t* d = dst_ptr;
19746 const uint8_t* s = src_ptr;
19747 size_t n = len;
19748
19749 // TODO: unroll.
19750
19751 while (n >= 1) {
19752 uint32_t d0 =
19753 wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000;
19754 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19755 ((size_t)s[0] * 4));
19756 wuffs_base__poke_u24le__no_bounds_check(
19757 d + (0 * 3), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
19758
19759 s += 1 * 1;
19760 d += 1 * 3;
19761 n -= 1;
19762 }
19763
19764 return len;
19765 }
19766
19767 static uint64_t //
wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19768 wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(
19769 uint8_t* dst_ptr,
19770 size_t dst_len,
19771 uint8_t* dst_palette_ptr,
19772 size_t dst_palette_len,
19773 const uint8_t* src_ptr,
19774 size_t src_len) {
19775 if (dst_palette_len !=
19776 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19777 return 0;
19778 }
19779 size_t dst_len3 = dst_len / 3;
19780 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19781 uint8_t* d = dst_ptr;
19782 const uint8_t* s = src_ptr;
19783 size_t n = len;
19784
19785 const size_t loop_unroll_count = 4;
19786
19787 while (n >= loop_unroll_count) {
19788 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19789 ((size_t)s[0] * 4));
19790 if (s0) {
19791 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19792 }
19793 uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19794 ((size_t)s[1] * 4));
19795 if (s1) {
19796 wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1);
19797 }
19798 uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19799 ((size_t)s[2] * 4));
19800 if (s2) {
19801 wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2);
19802 }
19803 uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19804 ((size_t)s[3] * 4));
19805 if (s3) {
19806 wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3);
19807 }
19808
19809 s += loop_unroll_count * 1;
19810 d += loop_unroll_count * 3;
19811 n -= loop_unroll_count;
19812 }
19813
19814 while (n >= 1) {
19815 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19816 ((size_t)s[0] * 4));
19817 if (s0) {
19818 wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
19819 }
19820
19821 s += 1 * 1;
19822 d += 1 * 3;
19823 n -= 1;
19824 }
19825
19826 return len;
19827 }
19828
19829 static uint64_t //
wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19830 wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr,
19831 size_t dst_len,
19832 uint8_t* dst_palette_ptr,
19833 size_t dst_palette_len,
19834 const uint8_t* src_ptr,
19835 size_t src_len) {
19836 size_t dst_len3 = dst_len / 3;
19837 size_t src_len4 = src_len / 4;
19838 size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
19839 uint8_t* d = dst_ptr;
19840 const uint8_t* s = src_ptr;
19841 size_t n = len;
19842
19843 // TODO: unroll.
19844
19845 while (n >= 1) {
19846 wuffs_base__poke_u24le__no_bounds_check(
19847 d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
19848
19849 s += 1 * 4;
19850 d += 1 * 3;
19851 n -= 1;
19852 }
19853
19854 return len;
19855 }
19856
19857 static uint64_t //
wuffs_base__pixel_swizzler__xxx__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19858 wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr,
19859 size_t dst_len,
19860 uint8_t* dst_palette_ptr,
19861 size_t dst_palette_len,
19862 const uint8_t* src_ptr,
19863 size_t src_len) {
19864 size_t dst_len3 = dst_len / 3;
19865 size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
19866 uint8_t* d = dst_ptr;
19867 const uint8_t* s = src_ptr;
19868 size_t n = len;
19869
19870 // TODO: unroll.
19871
19872 while (n >= 1) {
19873 uint8_t s0 = s[0];
19874 d[0] = s0;
19875 d[1] = s0;
19876 d[2] = s0;
19877
19878 s += 1 * 1;
19879 d += 1 * 3;
19880 n -= 1;
19881 }
19882
19883 return len;
19884 }
19885
19886 static uint64_t //
wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19887 wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t* dst_ptr,
19888 size_t dst_len,
19889 uint8_t* dst_palette_ptr,
19890 size_t dst_palette_len,
19891 const uint8_t* src_ptr,
19892 size_t src_len) {
19893 size_t dst_len3 = dst_len / 3;
19894 size_t src_len2 = src_len / 2;
19895 size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
19896 uint8_t* d = dst_ptr;
19897 const uint8_t* s = src_ptr;
19898 size_t n = len;
19899
19900 // TODO: unroll.
19901
19902 while (n >= 1) {
19903 uint8_t s0 = s[0];
19904 d[0] = s0;
19905 d[1] = s0;
19906 d[2] = s0;
19907
19908 s += 1 * 2;
19909 d += 1 * 3;
19910 n -= 1;
19911 }
19912
19913 return len;
19914 }
19915
19916 // --------
19917
19918 static uint64_t //
wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19919 wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t* dst_ptr,
19920 size_t dst_len,
19921 uint8_t* dst_palette_ptr,
19922 size_t dst_palette_len,
19923 const uint8_t* src_ptr,
19924 size_t src_len) {
19925 if (dst_palette_len !=
19926 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19927 return 0;
19928 }
19929 size_t dst_len4 = dst_len / 4;
19930 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19931 uint8_t* d = dst_ptr;
19932 const uint8_t* s = src_ptr;
19933 size_t n = len;
19934
19935 const size_t loop_unroll_count = 4;
19936
19937 while (n >= loop_unroll_count) {
19938 wuffs_base__poke_u32le__no_bounds_check(
19939 d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
19940 dst_palette_ptr + ((size_t)s[0] * 4)));
19941 wuffs_base__poke_u32le__no_bounds_check(
19942 d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check(
19943 dst_palette_ptr + ((size_t)s[1] * 4)));
19944 wuffs_base__poke_u32le__no_bounds_check(
19945 d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check(
19946 dst_palette_ptr + ((size_t)s[2] * 4)));
19947 wuffs_base__poke_u32le__no_bounds_check(
19948 d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check(
19949 dst_palette_ptr + ((size_t)s[3] * 4)));
19950
19951 s += loop_unroll_count * 1;
19952 d += loop_unroll_count * 4;
19953 n -= loop_unroll_count;
19954 }
19955
19956 while (n >= 1) {
19957 wuffs_base__poke_u32le__no_bounds_check(
19958 d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
19959 dst_palette_ptr + ((size_t)s[0] * 4)));
19960
19961 s += 1 * 1;
19962 d += 1 * 4;
19963 n -= 1;
19964 }
19965
19966 return len;
19967 }
19968
19969 static uint64_t //
wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)19970 wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(
19971 uint8_t* dst_ptr,
19972 size_t dst_len,
19973 uint8_t* dst_palette_ptr,
19974 size_t dst_palette_len,
19975 const uint8_t* src_ptr,
19976 size_t src_len) {
19977 if (dst_palette_len !=
19978 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
19979 return 0;
19980 }
19981 size_t dst_len4 = dst_len / 4;
19982 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
19983 uint8_t* d = dst_ptr;
19984 const uint8_t* s = src_ptr;
19985 size_t n = len;
19986
19987 const size_t loop_unroll_count = 4;
19988
19989 while (n >= loop_unroll_count) {
19990 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19991 ((size_t)s[0] * 4));
19992 if (s0) {
19993 wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
19994 }
19995 uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
19996 ((size_t)s[1] * 4));
19997 if (s1) {
19998 wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1);
19999 }
20000 uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20001 ((size_t)s[2] * 4));
20002 if (s2) {
20003 wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2);
20004 }
20005 uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20006 ((size_t)s[3] * 4));
20007 if (s3) {
20008 wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3);
20009 }
20010
20011 s += loop_unroll_count * 1;
20012 d += loop_unroll_count * 4;
20013 n -= loop_unroll_count;
20014 }
20015
20016 while (n >= 1) {
20017 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20018 ((size_t)s[0] * 4));
20019 if (s0) {
20020 wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
20021 }
20022
20023 s += 1 * 1;
20024 d += 1 * 4;
20025 n -= 1;
20026 }
20027
20028 return len;
20029 }
20030
20031 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
20032 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20033 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
20034 static uint64_t //
wuffs_base__pixel_swizzler__xxxx__y__sse42(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20035 wuffs_base__pixel_swizzler__xxxx__y__sse42(uint8_t* dst_ptr,
20036 size_t dst_len,
20037 uint8_t* dst_palette_ptr,
20038 size_t dst_palette_len,
20039 const uint8_t* src_ptr,
20040 size_t src_len) {
20041 size_t dst_len4 = dst_len / 4;
20042 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
20043 uint8_t* d = dst_ptr;
20044 const uint8_t* s = src_ptr;
20045 size_t n = len;
20046
20047 __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03, //
20048 +0x02, +0x02, +0x02, +0x02, //
20049 +0x01, +0x01, +0x01, +0x01, //
20050 +0x00, +0x00, +0x00, +0x00);
20051 __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, //
20052 -0x01, +0x00, +0x00, +0x00, //
20053 -0x01, +0x00, +0x00, +0x00, //
20054 -0x01, +0x00, +0x00, +0x00);
20055
20056 while (n >= 4) {
20057 __m128i x;
20058 x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s)));
20059 x = _mm_shuffle_epi8(x, shuffle);
20060 x = _mm_or_si128(x, or_ff);
20061 _mm_storeu_si128((__m128i*)(void*)d, x);
20062
20063 s += 4 * 1;
20064 d += 4 * 4;
20065 n -= 4;
20066 }
20067
20068 while (n >= 1) {
20069 wuffs_base__poke_u32le__no_bounds_check(
20070 d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
20071
20072 s += 1 * 1;
20073 d += 1 * 4;
20074 n -= 1;
20075 }
20076
20077 return len;
20078 }
20079 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20080 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
20081
20082 static uint64_t //
wuffs_base__pixel_swizzler__xxxx__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20083 wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr,
20084 size_t dst_len,
20085 uint8_t* dst_palette_ptr,
20086 size_t dst_palette_len,
20087 const uint8_t* src_ptr,
20088 size_t src_len) {
20089 size_t dst_len4 = dst_len / 4;
20090 size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
20091 uint8_t* d = dst_ptr;
20092 const uint8_t* s = src_ptr;
20093 size_t n = len;
20094
20095 while (n >= 1) {
20096 wuffs_base__poke_u32le__no_bounds_check(
20097 d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
20098
20099 s += 1 * 1;
20100 d += 1 * 4;
20101 n -= 1;
20102 }
20103
20104 return len;
20105 }
20106
20107 static uint64_t //
wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20108 wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t* dst_ptr,
20109 size_t dst_len,
20110 uint8_t* dst_palette_ptr,
20111 size_t dst_palette_len,
20112 const uint8_t* src_ptr,
20113 size_t src_len) {
20114 size_t dst_len4 = dst_len / 4;
20115 size_t src_len2 = src_len / 2;
20116 size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
20117 uint8_t* d = dst_ptr;
20118 const uint8_t* s = src_ptr;
20119 size_t n = len;
20120
20121 while (n >= 1) {
20122 wuffs_base__poke_u32le__no_bounds_check(
20123 d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
20124
20125 s += 1 * 2;
20126 d += 1 * 4;
20127 n -= 1;
20128 }
20129
20130 return len;
20131 }
20132
20133 // --------
20134
20135 static uint64_t //
wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20136 wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t* dst_ptr,
20137 size_t dst_len,
20138 uint8_t* dst_palette_ptr,
20139 size_t dst_palette_len,
20140 const uint8_t* src_ptr,
20141 size_t src_len) {
20142 if (dst_palette_len !=
20143 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20144 return 0;
20145 }
20146 size_t dst_len8 = dst_len / 8;
20147 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
20148 uint8_t* d = dst_ptr;
20149 const uint8_t* s = src_ptr;
20150 size_t n = len;
20151
20152 while (n >= 1) {
20153 wuffs_base__poke_u64le__no_bounds_check(
20154 d + (0 * 8), wuffs_base__color_u32__as__color_u64(
20155 wuffs_base__peek_u32le__no_bounds_check(
20156 dst_palette_ptr + ((size_t)s[0] * 4))));
20157
20158 s += 1 * 1;
20159 d += 1 * 8;
20160 n -= 1;
20161 }
20162
20163 return len;
20164 }
20165
20166 static uint64_t //
wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20167 wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over(
20168 uint8_t* dst_ptr,
20169 size_t dst_len,
20170 uint8_t* dst_palette_ptr,
20171 size_t dst_palette_len,
20172 const uint8_t* src_ptr,
20173 size_t src_len) {
20174 if (dst_palette_len !=
20175 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20176 return 0;
20177 }
20178 size_t dst_len8 = dst_len / 8;
20179 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
20180 uint8_t* d = dst_ptr;
20181 const uint8_t* s = src_ptr;
20182 size_t n = len;
20183
20184 while (n >= 1) {
20185 uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
20186 ((size_t)s[0] * 4));
20187 if (s0) {
20188 wuffs_base__poke_u64le__no_bounds_check(
20189 d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0));
20190 }
20191
20192 s += 1 * 1;
20193 d += 1 * 8;
20194 n -= 1;
20195 }
20196
20197 return len;
20198 }
20199
20200 static uint64_t //
wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20201 wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t* dst_ptr,
20202 size_t dst_len,
20203 uint8_t* dst_palette_ptr,
20204 size_t dst_palette_len,
20205 const uint8_t* src_ptr,
20206 size_t src_len) {
20207 size_t dst_len8 = dst_len / 8;
20208 size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
20209 uint8_t* d = dst_ptr;
20210 const uint8_t* s = src_ptr;
20211 size_t n = len;
20212
20213 while (n >= 1) {
20214 wuffs_base__poke_u64le__no_bounds_check(
20215 d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0]));
20216
20217 s += 1 * 1;
20218 d += 1 * 8;
20219 n -= 1;
20220 }
20221
20222 return len;
20223 }
20224
20225 static uint64_t //
wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20226 wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t* dst_ptr,
20227 size_t dst_len,
20228 uint8_t* dst_palette_ptr,
20229 size_t dst_palette_len,
20230 const uint8_t* src_ptr,
20231 size_t src_len) {
20232 size_t dst_len8 = dst_len / 8;
20233 size_t src_len2 = src_len / 2;
20234 size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
20235 uint8_t* d = dst_ptr;
20236 const uint8_t* s = src_ptr;
20237 size_t n = len;
20238
20239 while (n >= 1) {
20240 uint64_t s0 =
20241 ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2))));
20242 wuffs_base__poke_u64le__no_bounds_check(
20243 d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0));
20244
20245 s += 1 * 2;
20246 d += 1 * 8;
20247 n -= 1;
20248 }
20249
20250 return len;
20251 }
20252
20253 // --------
20254
20255 static uint64_t //
wuffs_base__pixel_swizzler__y__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20256 wuffs_base__pixel_swizzler__y__y_16be(uint8_t* dst_ptr,
20257 size_t dst_len,
20258 uint8_t* dst_palette_ptr,
20259 size_t dst_palette_len,
20260 const uint8_t* src_ptr,
20261 size_t src_len) {
20262 size_t src_len2 = src_len / 2;
20263 size_t len = (dst_len < src_len2) ? dst_len : src_len2;
20264 uint8_t* d = dst_ptr;
20265 const uint8_t* s = src_ptr;
20266 size_t n = len;
20267
20268 while (n >= 1) {
20269 d[0] = s[0];
20270
20271 s += 1 * 2;
20272 d += 1 * 1;
20273 n -= 1;
20274 }
20275
20276 return len;
20277 }
20278
20279 static uint64_t //
wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,const uint8_t * src_ptr,size_t src_len)20280 wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t* dst_ptr,
20281 size_t dst_len,
20282 uint8_t* dst_palette_ptr,
20283 size_t dst_palette_len,
20284 const uint8_t* src_ptr,
20285 size_t src_len) {
20286 size_t dst_len2 = dst_len / 2;
20287 size_t src_len2 = src_len / 2;
20288 size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
20289 uint8_t* d = dst_ptr;
20290 const uint8_t* s = src_ptr;
20291 size_t n = len;
20292
20293 while (n >= 1) {
20294 uint8_t s0 = s[0];
20295 uint8_t s1 = s[1];
20296 d[0] = s1;
20297 d[1] = s0;
20298
20299 s += 1 * 2;
20300 d += 1 * 2;
20301 n -= 1;
20302 }
20303
20304 return len;
20305 }
20306
20307 // --------
20308
20309 static uint64_t //
wuffs_base__pixel_swizzler__transparent_black_src(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,uint64_t num_pixels,uint32_t dst_pixfmt_bytes_per_pixel)20310 wuffs_base__pixel_swizzler__transparent_black_src(
20311 uint8_t* dst_ptr,
20312 size_t dst_len,
20313 uint8_t* dst_palette_ptr,
20314 size_t dst_palette_len,
20315 uint64_t num_pixels,
20316 uint32_t dst_pixfmt_bytes_per_pixel) {
20317 uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
20318 if (n > num_pixels) {
20319 n = num_pixels;
20320 }
20321 memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel)));
20322 return n;
20323 }
20324
20325 static uint64_t //
wuffs_base__pixel_swizzler__transparent_black_src_over(uint8_t * dst_ptr,size_t dst_len,uint8_t * dst_palette_ptr,size_t dst_palette_len,uint64_t num_pixels,uint32_t dst_pixfmt_bytes_per_pixel)20326 wuffs_base__pixel_swizzler__transparent_black_src_over(
20327 uint8_t* dst_ptr,
20328 size_t dst_len,
20329 uint8_t* dst_palette_ptr,
20330 size_t dst_palette_len,
20331 uint64_t num_pixels,
20332 uint32_t dst_pixfmt_bytes_per_pixel) {
20333 uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
20334 if (n > num_pixels) {
20335 n = num_pixels;
20336 }
20337 return n;
20338 }
20339
20340 // --------
20341
20342 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20343 wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler* p,
20344 wuffs_base__pixel_format dst_pixfmt,
20345 wuffs_base__slice_u8 dst_palette,
20346 wuffs_base__slice_u8 src_palette,
20347 wuffs_base__pixel_blend blend) {
20348 switch (dst_pixfmt.repr) {
20349 case WUFFS_BASE__PIXEL_FORMAT__Y:
20350 return wuffs_base__pixel_swizzler__copy_1_1;
20351
20352 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20353 return wuffs_base__pixel_swizzler__bgr_565__y;
20354
20355 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20356 case WUFFS_BASE__PIXEL_FORMAT__RGB:
20357 return wuffs_base__pixel_swizzler__xxx__y;
20358
20359 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20360 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20361 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20362 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20363 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20364 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20365 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20366 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20367 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20368 if (wuffs_base__cpu_arch__have_x86_sse42()) {
20369 return wuffs_base__pixel_swizzler__xxxx__y__sse42;
20370 }
20371 #endif
20372 return wuffs_base__pixel_swizzler__xxxx__y;
20373
20374 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20375 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20376 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
20377 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
20378 return wuffs_base__pixel_swizzler__xxxxxxxx__y;
20379 }
20380 return NULL;
20381 }
20382
20383 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20384 wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler* p,
20385 wuffs_base__pixel_format dst_pixfmt,
20386 wuffs_base__slice_u8 dst_palette,
20387 wuffs_base__slice_u8 src_palette,
20388 wuffs_base__pixel_blend blend) {
20389 switch (dst_pixfmt.repr) {
20390 case WUFFS_BASE__PIXEL_FORMAT__Y:
20391 return wuffs_base__pixel_swizzler__y__y_16be;
20392
20393 case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
20394 return wuffs_base__pixel_swizzler__y_16le__y_16be;
20395
20396 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
20397 return wuffs_base__pixel_swizzler__copy_2_2;
20398
20399 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20400 return wuffs_base__pixel_swizzler__bgr_565__y_16be;
20401
20402 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20403 case WUFFS_BASE__PIXEL_FORMAT__RGB:
20404 return wuffs_base__pixel_swizzler__xxx__y_16be;
20405
20406 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20407 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20408 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20409 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20410 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20411 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20412 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20413 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20414 return wuffs_base__pixel_swizzler__xxxx__y_16be;
20415
20416 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20417 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20418 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
20419 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
20420 return wuffs_base__pixel_swizzler__xxxxxxxx__y_16be;
20421 }
20422 return NULL;
20423 }
20424
20425 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20426 wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
20427 wuffs_base__pixel_swizzler* p,
20428 wuffs_base__pixel_format dst_pixfmt,
20429 wuffs_base__slice_u8 dst_palette,
20430 wuffs_base__slice_u8 src_palette,
20431 wuffs_base__pixel_blend blend) {
20432 switch (dst_pixfmt.repr) {
20433 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
20434 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20435 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20436 return NULL;
20437 }
20438 switch (blend) {
20439 case WUFFS_BASE__PIXEL_BLEND__SRC:
20440 return wuffs_base__pixel_swizzler__copy_1_1;
20441 }
20442 return NULL;
20443
20444 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20445 switch (blend) {
20446 case WUFFS_BASE__PIXEL_BLEND__SRC:
20447 if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
20448 dst_palette.ptr, dst_palette.len, src_palette.ptr,
20449 src_palette.len, true) !=
20450 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20451 return NULL;
20452 }
20453 return wuffs_base__pixel_swizzler__bgr_565__index__src;
20454 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20455 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20456 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20457 return NULL;
20458 }
20459 return wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over;
20460 }
20461 return NULL;
20462
20463 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20464 switch (blend) {
20465 case WUFFS_BASE__PIXEL_BLEND__SRC:
20466 if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
20467 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20468 src_palette.len) !=
20469 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20470 return NULL;
20471 }
20472 return wuffs_base__pixel_swizzler__xxx__index__src;
20473 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20474 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20475 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20476 return NULL;
20477 }
20478 return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over;
20479 }
20480 return NULL;
20481
20482 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20483 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20484 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20485 return NULL;
20486 }
20487 switch (blend) {
20488 case WUFFS_BASE__PIXEL_BLEND__SRC:
20489 return wuffs_base__pixel_swizzler__xxxx__index__src;
20490 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20491 return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
20492 }
20493 return NULL;
20494
20495 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20496 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20497 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20498 return NULL;
20499 }
20500 switch (blend) {
20501 case WUFFS_BASE__PIXEL_BLEND__SRC:
20502 return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
20503 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20504 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over;
20505 }
20506 return NULL;
20507
20508 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20509 switch (blend) {
20510 case WUFFS_BASE__PIXEL_BLEND__SRC:
20511 if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
20512 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20513 src_palette.len) !=
20514 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20515 return NULL;
20516 }
20517 return wuffs_base__pixel_swizzler__xxxx__index__src;
20518 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20519 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20520 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20521 return NULL;
20522 }
20523 return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
20524 }
20525 return NULL;
20526
20527 case WUFFS_BASE__PIXEL_FORMAT__RGB:
20528 // TODO.
20529 break;
20530
20531 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20532 if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20533 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20534 src_palette.len) !=
20535 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20536 return NULL;
20537 }
20538 switch (blend) {
20539 case WUFFS_BASE__PIXEL_BLEND__SRC:
20540 return wuffs_base__pixel_swizzler__xxxx__index__src;
20541 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20542 return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
20543 }
20544 return NULL;
20545
20546 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20547 switch (blend) {
20548 case WUFFS_BASE__PIXEL_BLEND__SRC:
20549 if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
20550 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20551 src_palette.len) !=
20552 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20553 return NULL;
20554 }
20555 return wuffs_base__pixel_swizzler__xxxx__index__src;
20556 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20557 if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20558 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20559 src_palette.len) !=
20560 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20561 return NULL;
20562 }
20563 return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
20564 }
20565 return NULL;
20566
20567 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20568 // TODO.
20569 break;
20570 }
20571 return NULL;
20572 }
20573
20574 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20575 wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
20576 wuffs_base__pixel_swizzler* p,
20577 wuffs_base__pixel_format dst_pixfmt,
20578 wuffs_base__slice_u8 dst_palette,
20579 wuffs_base__slice_u8 src_palette,
20580 wuffs_base__pixel_blend blend) {
20581 switch (dst_pixfmt.repr) {
20582 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
20583 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
20584 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
20585 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20586 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20587 return NULL;
20588 }
20589 switch (blend) {
20590 case WUFFS_BASE__PIXEL_BLEND__SRC:
20591 return wuffs_base__pixel_swizzler__copy_1_1;
20592 }
20593 return NULL;
20594
20595 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20596 if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
20597 dst_palette.ptr, dst_palette.len, src_palette.ptr,
20598 src_palette.len, false) !=
20599 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20600 return NULL;
20601 }
20602 switch (blend) {
20603 case WUFFS_BASE__PIXEL_BLEND__SRC:
20604 return wuffs_base__pixel_swizzler__bgr_565__index__src;
20605 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20606 return wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over;
20607 }
20608 return NULL;
20609
20610 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20611 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20612 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20613 return NULL;
20614 }
20615 switch (blend) {
20616 case WUFFS_BASE__PIXEL_BLEND__SRC:
20617 return wuffs_base__pixel_swizzler__xxx__index__src;
20618 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20619 return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
20620 }
20621 return NULL;
20622
20623 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20624 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20625 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20626 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20627 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20628 return NULL;
20629 }
20630 switch (blend) {
20631 case WUFFS_BASE__PIXEL_BLEND__SRC:
20632 return wuffs_base__pixel_swizzler__xxxx__index__src;
20633 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20634 return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
20635 }
20636 return NULL;
20637
20638 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20639 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20640 if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
20641 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
20642 return NULL;
20643 }
20644 switch (blend) {
20645 case WUFFS_BASE__PIXEL_BLEND__SRC:
20646 return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
20647 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20648 return wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over;
20649 }
20650 return NULL;
20651
20652 case WUFFS_BASE__PIXEL_FORMAT__RGB:
20653 if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20654 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20655 src_palette.len) !=
20656 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20657 return NULL;
20658 }
20659 switch (blend) {
20660 case WUFFS_BASE__PIXEL_BLEND__SRC:
20661 return wuffs_base__pixel_swizzler__xxx__index__src;
20662 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20663 return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
20664 }
20665 return NULL;
20666
20667 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20668 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20669 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20670 if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
20671 dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
20672 src_palette.len) !=
20673 (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
20674 return NULL;
20675 }
20676 switch (blend) {
20677 case WUFFS_BASE__PIXEL_BLEND__SRC:
20678 return wuffs_base__pixel_swizzler__xxxx__index__src;
20679 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20680 return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
20681 }
20682 return NULL;
20683 }
20684 return NULL;
20685 }
20686
20687 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__bgr_565(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20688 wuffs_base__pixel_swizzler__prepare__bgr_565(
20689 wuffs_base__pixel_swizzler* p,
20690 wuffs_base__pixel_format dst_pixfmt,
20691 wuffs_base__slice_u8 dst_palette,
20692 wuffs_base__slice_u8 src_palette,
20693 wuffs_base__pixel_blend blend) {
20694 switch (dst_pixfmt.repr) {
20695 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20696 return wuffs_base__pixel_swizzler__copy_2_2;
20697
20698 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20699 return wuffs_base__pixel_swizzler__bgr__bgr_565;
20700
20701 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20702 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20703 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20704 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20705 return wuffs_base__pixel_swizzler__bgrw__bgr_565;
20706
20707 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20708 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20709 return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565;
20710
20711 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20712 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20713 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20714 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20715 return wuffs_base__pixel_swizzler__rgbw__bgr_565;
20716 }
20717 return NULL;
20718 }
20719
20720 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20721 wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler* p,
20722 wuffs_base__pixel_format dst_pixfmt,
20723 wuffs_base__slice_u8 dst_palette,
20724 wuffs_base__slice_u8 src_palette,
20725 wuffs_base__pixel_blend blend) {
20726 switch (dst_pixfmt.repr) {
20727 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20728 return wuffs_base__pixel_swizzler__bgr_565__bgr;
20729
20730 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20731 return wuffs_base__pixel_swizzler__copy_3_3;
20732
20733 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20734 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20735 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20736 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20737 return wuffs_base__pixel_swizzler__bgrw__bgr;
20738
20739 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20740 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
20741 return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr;
20742
20743 case WUFFS_BASE__PIXEL_FORMAT__RGB:
20744 return wuffs_base__pixel_swizzler__swap_rgb_bgr;
20745
20746 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20747 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20748 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20749 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20750 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20751 if (wuffs_base__cpu_arch__have_x86_sse42()) {
20752 return wuffs_base__pixel_swizzler__bgrw__rgb__sse42;
20753 }
20754 #endif
20755 return wuffs_base__pixel_swizzler__bgrw__rgb;
20756 }
20757 return NULL;
20758 }
20759
20760 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20761 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
20762 wuffs_base__pixel_swizzler* p,
20763 wuffs_base__pixel_format dst_pixfmt,
20764 wuffs_base__slice_u8 dst_palette,
20765 wuffs_base__slice_u8 src_palette,
20766 wuffs_base__pixel_blend blend) {
20767 switch (dst_pixfmt.repr) {
20768 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20769 switch (blend) {
20770 case WUFFS_BASE__PIXEL_BLEND__SRC:
20771 return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src;
20772 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20773 return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over;
20774 }
20775 return NULL;
20776
20777 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20778 switch (blend) {
20779 case WUFFS_BASE__PIXEL_BLEND__SRC:
20780 return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
20781 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20782 return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
20783 }
20784 return NULL;
20785
20786 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20787 switch (blend) {
20788 case WUFFS_BASE__PIXEL_BLEND__SRC:
20789 return wuffs_base__pixel_swizzler__copy_4_4;
20790 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20791 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
20792 }
20793 return NULL;
20794
20795 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20796 switch (blend) {
20797 case WUFFS_BASE__PIXEL_BLEND__SRC:
20798 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src;
20799 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20800 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over;
20801 }
20802 return NULL;
20803
20804 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20805 switch (blend) {
20806 case WUFFS_BASE__PIXEL_BLEND__SRC:
20807 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
20808 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20809 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
20810 }
20811 return NULL;
20812
20813 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20814 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20815 // TODO.
20816 break;
20817
20818 case WUFFS_BASE__PIXEL_FORMAT__RGB:
20819 // TODO.
20820 break;
20821
20822 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20823 switch (blend) {
20824 case WUFFS_BASE__PIXEL_BLEND__SRC:
20825 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
20826 if (wuffs_base__cpu_arch__have_x86_sse42()) {
20827 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
20828 }
20829 #endif
20830 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
20831 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20832 return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
20833 }
20834 return NULL;
20835
20836 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20837 switch (blend) {
20838 case WUFFS_BASE__PIXEL_BLEND__SRC:
20839 return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
20840 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20841 return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
20842 }
20843 return NULL;
20844
20845 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20846 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20847 // TODO.
20848 break;
20849 }
20850 return NULL;
20851 }
20852
20853 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20854 wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
20855 wuffs_base__pixel_swizzler* p,
20856 wuffs_base__pixel_format dst_pixfmt,
20857 wuffs_base__slice_u8 dst_palette,
20858 wuffs_base__slice_u8 src_palette,
20859 wuffs_base__pixel_blend blend) {
20860 switch (dst_pixfmt.repr) {
20861 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20862 switch (blend) {
20863 case WUFFS_BASE__PIXEL_BLEND__SRC:
20864 return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src;
20865 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20866 return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over;
20867 }
20868 return NULL;
20869
20870 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20871 switch (blend) {
20872 case WUFFS_BASE__PIXEL_BLEND__SRC:
20873 return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src;
20874 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20875 return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over;
20876 }
20877 return NULL;
20878
20879 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20880 switch (blend) {
20881 case WUFFS_BASE__PIXEL_BLEND__SRC:
20882 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src;
20883 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20884 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over;
20885 }
20886 return NULL;
20887
20888 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20889 switch (blend) {
20890 case WUFFS_BASE__PIXEL_BLEND__SRC:
20891 return wuffs_base__pixel_swizzler__copy_8_8;
20892 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20893 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over;
20894 }
20895 return NULL;
20896
20897 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20898 switch (blend) {
20899 case WUFFS_BASE__PIXEL_BLEND__SRC:
20900 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src;
20901 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20902 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over;
20903 }
20904 return NULL;
20905
20906 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
20907 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
20908 // TODO.
20909 break;
20910
20911 case WUFFS_BASE__PIXEL_FORMAT__RGB:
20912 // TODO.
20913 break;
20914
20915 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20916 switch (blend) {
20917 case WUFFS_BASE__PIXEL_BLEND__SRC:
20918 return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src;
20919 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20920 return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over;
20921 }
20922 break;
20923
20924 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
20925 switch (blend) {
20926 case WUFFS_BASE__PIXEL_BLEND__SRC:
20927 return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src;
20928 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20929 return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over;
20930 }
20931 return NULL;
20932
20933 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
20934 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
20935 // TODO.
20936 break;
20937 }
20938 return NULL;
20939 }
20940
20941 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__bgra_premul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)20942 wuffs_base__pixel_swizzler__prepare__bgra_premul(
20943 wuffs_base__pixel_swizzler* p,
20944 wuffs_base__pixel_format dst_pixfmt,
20945 wuffs_base__slice_u8 dst_palette,
20946 wuffs_base__slice_u8 src_palette,
20947 wuffs_base__pixel_blend blend) {
20948 switch (dst_pixfmt.repr) {
20949 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
20950 switch (blend) {
20951 case WUFFS_BASE__PIXEL_BLEND__SRC:
20952 return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src;
20953 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20954 return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over;
20955 }
20956 return NULL;
20957
20958 case WUFFS_BASE__PIXEL_FORMAT__BGR:
20959 switch (blend) {
20960 case WUFFS_BASE__PIXEL_BLEND__SRC:
20961 return wuffs_base__pixel_swizzler__bgr__bgra_premul__src;
20962 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20963 return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over;
20964 }
20965 return NULL;
20966
20967 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
20968 switch (blend) {
20969 case WUFFS_BASE__PIXEL_BLEND__SRC:
20970 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
20971 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20972 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
20973 }
20974 return NULL;
20975
20976 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
20977 switch (blend) {
20978 case WUFFS_BASE__PIXEL_BLEND__SRC:
20979 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src;
20980 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20981 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over;
20982 }
20983 return NULL;
20984
20985 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
20986 switch (blend) {
20987 case WUFFS_BASE__PIXEL_BLEND__SRC:
20988 return wuffs_base__pixel_swizzler__copy_4_4;
20989 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20990 return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
20991 }
20992 return NULL;
20993
20994 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
20995 switch (blend) {
20996 case WUFFS_BASE__PIXEL_BLEND__SRC:
20997 return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
20998 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
20999 return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
21000 }
21001 return NULL;
21002
21003 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21004 switch (blend) {
21005 case WUFFS_BASE__PIXEL_BLEND__SRC:
21006 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21007 if (wuffs_base__cpu_arch__have_x86_sse42()) {
21008 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
21009 }
21010 #endif
21011 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
21012 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21013 return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
21014 }
21015 return NULL;
21016 }
21017 return NULL;
21018 }
21019
21020 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)21021 wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler* p,
21022 wuffs_base__pixel_format dst_pixfmt,
21023 wuffs_base__slice_u8 dst_palette,
21024 wuffs_base__slice_u8 src_palette,
21025 wuffs_base__pixel_blend blend) {
21026 switch (dst_pixfmt.repr) {
21027 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21028 return wuffs_base__pixel_swizzler__bgr_565__bgrx;
21029
21030 case WUFFS_BASE__PIXEL_FORMAT__BGR:
21031 return wuffs_base__pixel_swizzler__xxx__xxxx;
21032
21033 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21034 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21035 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
21036 return wuffs_base__pixel_swizzler__bgrw__bgrx;
21037
21038 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21039 return wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx;
21040
21041 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21042 return wuffs_base__pixel_swizzler__copy_4_4;
21043
21044 case WUFFS_BASE__PIXEL_FORMAT__RGB:
21045 // TODO.
21046 break;
21047
21048 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21049 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21050 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
21051 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
21052 return wuffs_base__pixel_swizzler__bgrw__rgbx;
21053 }
21054 return NULL;
21055 }
21056
21057 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)21058 wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler* p,
21059 wuffs_base__pixel_format dst_pixfmt,
21060 wuffs_base__slice_u8 dst_palette,
21061 wuffs_base__slice_u8 src_palette,
21062 wuffs_base__pixel_blend blend) {
21063 switch (dst_pixfmt.repr) {
21064 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21065 return wuffs_base__pixel_swizzler__bgr_565__rgb;
21066
21067 case WUFFS_BASE__PIXEL_FORMAT__BGR:
21068 return wuffs_base__pixel_swizzler__swap_rgb_bgr;
21069
21070 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21071 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21072 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
21073 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21074 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21075 if (wuffs_base__cpu_arch__have_x86_sse42()) {
21076 return wuffs_base__pixel_swizzler__bgrw__rgb__sse42;
21077 }
21078 #endif
21079 return wuffs_base__pixel_swizzler__bgrw__rgb;
21080
21081 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21082 return wuffs_base__pixel_swizzler__bgrw_4x16le__rgb;
21083
21084 case WUFFS_BASE__PIXEL_FORMAT__RGB:
21085 return wuffs_base__pixel_swizzler__copy_3_3;
21086
21087 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21088 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21089 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
21090 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
21091 return wuffs_base__pixel_swizzler__bgrw__bgr;
21092 }
21093 return NULL;
21094 }
21095
21096 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)21097 wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
21098 wuffs_base__pixel_swizzler* p,
21099 wuffs_base__pixel_format dst_pixfmt,
21100 wuffs_base__slice_u8 dst_palette,
21101 wuffs_base__slice_u8 src_palette,
21102 wuffs_base__pixel_blend blend) {
21103 switch (dst_pixfmt.repr) {
21104 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21105 switch (blend) {
21106 case WUFFS_BASE__PIXEL_BLEND__SRC:
21107 return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src;
21108 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21109 return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over;
21110 }
21111 return NULL;
21112
21113 case WUFFS_BASE__PIXEL_FORMAT__BGR:
21114 switch (blend) {
21115 case WUFFS_BASE__PIXEL_BLEND__SRC:
21116 return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src;
21117 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21118 return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over;
21119 }
21120 return NULL;
21121
21122 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21123 switch (blend) {
21124 case WUFFS_BASE__PIXEL_BLEND__SRC:
21125 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21126 if (wuffs_base__cpu_arch__have_x86_sse42()) {
21127 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
21128 }
21129 #endif
21130 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
21131 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21132 return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
21133 }
21134 return NULL;
21135
21136 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21137 switch (blend) {
21138 case WUFFS_BASE__PIXEL_BLEND__SRC:
21139 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src;
21140 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21141 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over;
21142 }
21143 return NULL;
21144
21145 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21146 switch (blend) {
21147 case WUFFS_BASE__PIXEL_BLEND__SRC:
21148 return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
21149 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21150 return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
21151 }
21152 return NULL;
21153
21154 case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
21155 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21156 // TODO.
21157 break;
21158
21159 case WUFFS_BASE__PIXEL_FORMAT__RGB:
21160 // TODO.
21161 break;
21162
21163 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21164 switch (blend) {
21165 case WUFFS_BASE__PIXEL_BLEND__SRC:
21166 return wuffs_base__pixel_swizzler__copy_4_4;
21167 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21168 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
21169 }
21170 return NULL;
21171
21172 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21173 switch (blend) {
21174 case WUFFS_BASE__PIXEL_BLEND__SRC:
21175 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
21176 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21177 return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
21178 }
21179 return NULL;
21180
21181 case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
21182 case WUFFS_BASE__PIXEL_FORMAT__RGBX:
21183 // TODO.
21184 break;
21185 }
21186 return NULL;
21187 }
21188
21189 static wuffs_base__pixel_swizzler__func //
wuffs_base__pixel_swizzler__prepare__rgba_premul(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)21190 wuffs_base__pixel_swizzler__prepare__rgba_premul(
21191 wuffs_base__pixel_swizzler* p,
21192 wuffs_base__pixel_format dst_pixfmt,
21193 wuffs_base__slice_u8 dst_palette,
21194 wuffs_base__slice_u8 src_palette,
21195 wuffs_base__pixel_blend blend) {
21196 switch (dst_pixfmt.repr) {
21197 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21198 switch (blend) {
21199 case WUFFS_BASE__PIXEL_BLEND__SRC:
21200 return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src;
21201 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21202 return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over;
21203 }
21204 return NULL;
21205
21206 case WUFFS_BASE__PIXEL_FORMAT__BGR:
21207 switch (blend) {
21208 case WUFFS_BASE__PIXEL_BLEND__SRC:
21209 return wuffs_base__pixel_swizzler__bgr__rgba_premul__src;
21210 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21211 return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over;
21212 }
21213 return NULL;
21214
21215 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21216 switch (blend) {
21217 case WUFFS_BASE__PIXEL_BLEND__SRC:
21218 return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
21219 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21220 return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
21221 }
21222 return NULL;
21223
21224 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21225 switch (blend) {
21226 case WUFFS_BASE__PIXEL_BLEND__SRC:
21227 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src;
21228 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21229 return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over;
21230 }
21231 return NULL;
21232
21233 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21234 switch (blend) {
21235 case WUFFS_BASE__PIXEL_BLEND__SRC:
21236 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21237 if (wuffs_base__cpu_arch__have_x86_sse42()) {
21238 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__sse42;
21239 }
21240 #endif
21241 return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
21242 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21243 return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
21244 }
21245 return NULL;
21246
21247 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21248 switch (blend) {
21249 case WUFFS_BASE__PIXEL_BLEND__SRC:
21250 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
21251 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21252 return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
21253 }
21254 return NULL;
21255
21256 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21257 switch (blend) {
21258 case WUFFS_BASE__PIXEL_BLEND__SRC:
21259 return wuffs_base__pixel_swizzler__copy_4_4;
21260 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21261 return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
21262 }
21263 return NULL;
21264 }
21265 return NULL;
21266 }
21267
21268 // --------
21269
21270 WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler * p,wuffs_base__pixel_format dst_pixfmt,wuffs_base__slice_u8 dst_palette,wuffs_base__pixel_format src_pixfmt,wuffs_base__slice_u8 src_palette,wuffs_base__pixel_blend blend)21271 wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
21272 wuffs_base__pixel_format dst_pixfmt,
21273 wuffs_base__slice_u8 dst_palette,
21274 wuffs_base__pixel_format src_pixfmt,
21275 wuffs_base__slice_u8 src_palette,
21276 wuffs_base__pixel_blend blend) {
21277 if (!p) {
21278 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21279 }
21280 p->private_impl.func = NULL;
21281 p->private_impl.transparent_black_func = NULL;
21282 p->private_impl.dst_pixfmt_bytes_per_pixel = 0;
21283 p->private_impl.src_pixfmt_bytes_per_pixel = 0;
21284
21285 wuffs_base__pixel_swizzler__func func = NULL;
21286 wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func =
21287 NULL;
21288
21289 uint32_t dst_pixfmt_bits_per_pixel =
21290 wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt);
21291 if ((dst_pixfmt_bits_per_pixel == 0) ||
21292 ((dst_pixfmt_bits_per_pixel & 7) != 0)) {
21293 return wuffs_base__make_status(
21294 wuffs_base__error__unsupported_pixel_swizzler_option);
21295 }
21296
21297 uint32_t src_pixfmt_bits_per_pixel =
21298 wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);
21299 if ((src_pixfmt_bits_per_pixel == 0) ||
21300 ((src_pixfmt_bits_per_pixel & 7) != 0)) {
21301 return wuffs_base__make_status(
21302 wuffs_base__error__unsupported_pixel_swizzler_option);
21303 }
21304
21305 // TODO: support many more formats.
21306
21307 switch (blend) {
21308 case WUFFS_BASE__PIXEL_BLEND__SRC:
21309 transparent_black_func =
21310 wuffs_base__pixel_swizzler__transparent_black_src;
21311 break;
21312
21313 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
21314 transparent_black_func =
21315 wuffs_base__pixel_swizzler__transparent_black_src_over;
21316 break;
21317 }
21318
21319 switch (src_pixfmt.repr) {
21320 case WUFFS_BASE__PIXEL_FORMAT__Y:
21321 func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette,
21322 src_palette, blend);
21323 break;
21324
21325 case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
21326 func = wuffs_base__pixel_swizzler__prepare__y_16be(
21327 p, dst_pixfmt, dst_palette, src_palette, blend);
21328 break;
21329
21330 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
21331 func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
21332 p, dst_pixfmt, dst_palette, src_palette, blend);
21333 break;
21334
21335 case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
21336 func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
21337 p, dst_pixfmt, dst_palette, src_palette, blend);
21338 break;
21339
21340 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
21341 func = wuffs_base__pixel_swizzler__prepare__bgr_565(
21342 p, dst_pixfmt, dst_palette, src_palette, blend);
21343 break;
21344
21345 case WUFFS_BASE__PIXEL_FORMAT__BGR:
21346 func = wuffs_base__pixel_swizzler__prepare__bgr(
21347 p, dst_pixfmt, dst_palette, src_palette, blend);
21348 break;
21349
21350 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
21351 func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
21352 p, dst_pixfmt, dst_palette, src_palette, blend);
21353 break;
21354
21355 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
21356 func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
21357 p, dst_pixfmt, dst_palette, src_palette, blend);
21358 break;
21359
21360 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
21361 func = wuffs_base__pixel_swizzler__prepare__bgra_premul(
21362 p, dst_pixfmt, dst_palette, src_palette, blend);
21363 break;
21364
21365 case WUFFS_BASE__PIXEL_FORMAT__BGRX:
21366 func = wuffs_base__pixel_swizzler__prepare__bgrx(
21367 p, dst_pixfmt, dst_palette, src_palette, blend);
21368 break;
21369
21370 case WUFFS_BASE__PIXEL_FORMAT__RGB:
21371 func = wuffs_base__pixel_swizzler__prepare__rgb(
21372 p, dst_pixfmt, dst_palette, src_palette, blend);
21373 break;
21374
21375 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
21376 func = wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
21377 p, dst_pixfmt, dst_palette, src_palette, blend);
21378 break;
21379
21380 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
21381 func = wuffs_base__pixel_swizzler__prepare__rgba_premul(
21382 p, dst_pixfmt, dst_palette, src_palette, blend);
21383 break;
21384 }
21385
21386 p->private_impl.func = func;
21387 p->private_impl.transparent_black_func = transparent_black_func;
21388 p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;
21389 p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;
21390 return wuffs_base__make_status(
21391 func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);
21392 }
21393
21394 WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(const wuffs_base__pixel_swizzler * p,uint32_t up_to_num_pixels,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,const uint8_t ** ptr_iop_r,const uint8_t * io2_r)21395 wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
21396 const wuffs_base__pixel_swizzler* p,
21397 uint32_t up_to_num_pixels,
21398 wuffs_base__slice_u8 dst,
21399 wuffs_base__slice_u8 dst_palette,
21400 const uint8_t** ptr_iop_r,
21401 const uint8_t* io2_r) {
21402 if (p && p->private_impl.func) {
21403 const uint8_t* iop_r = *ptr_iop_r;
21404 uint64_t src_len = wuffs_base__u64__min(
21405 ((uint64_t)up_to_num_pixels) *
21406 ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
21407 ((uint64_t)(io2_r - iop_r)));
21408 uint64_t n =
21409 (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
21410 dst_palette.len, iop_r, (size_t)src_len);
21411 *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
21412 return n;
21413 }
21414 return 0;
21415 }
21416
21417 WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(const wuffs_base__pixel_swizzler * p,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,const uint8_t ** ptr_iop_r,const uint8_t * io2_r)21418 wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
21419 const wuffs_base__pixel_swizzler* p,
21420 wuffs_base__slice_u8 dst,
21421 wuffs_base__slice_u8 dst_palette,
21422 const uint8_t** ptr_iop_r,
21423 const uint8_t* io2_r) {
21424 if (p && p->private_impl.func) {
21425 const uint8_t* iop_r = *ptr_iop_r;
21426 uint64_t src_len = ((uint64_t)(io2_r - iop_r));
21427 uint64_t n =
21428 (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
21429 dst_palette.len, iop_r, (size_t)src_len);
21430 *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
21431 return n;
21432 }
21433 return 0;
21434 }
21435
21436 WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(const wuffs_base__pixel_swizzler * p,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,wuffs_base__slice_u8 src)21437 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
21438 const wuffs_base__pixel_swizzler* p,
21439 wuffs_base__slice_u8 dst,
21440 wuffs_base__slice_u8 dst_palette,
21441 wuffs_base__slice_u8 src) {
21442 if (p && p->private_impl.func) {
21443 return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
21444 dst_palette.len, src.ptr, src.len);
21445 }
21446 return 0;
21447 }
21448
21449 WUFFS_BASE__MAYBE_STATIC uint64_t //
wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(const wuffs_base__pixel_swizzler * p,wuffs_base__slice_u8 dst,wuffs_base__slice_u8 dst_palette,uint64_t num_pixels)21450 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
21451 const wuffs_base__pixel_swizzler* p,
21452 wuffs_base__slice_u8 dst,
21453 wuffs_base__slice_u8 dst_palette,
21454 uint64_t num_pixels) {
21455 if (p && p->private_impl.transparent_black_func) {
21456 return (*p->private_impl.transparent_black_func)(
21457 dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,
21458 p->private_impl.dst_pixfmt_bytes_per_pixel);
21459 }
21460 return 0;
21461 }
21462
21463 #endif // !defined(WUFFS_CONFIG__MODULES) ||
21464 // defined(WUFFS_CONFIG__MODULE__BASE) ||
21465 // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
21466
21467 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
21468 defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
21469
21470 // ---------------- Unicode and UTF-8
21471
21472 WUFFS_BASE__MAYBE_STATIC size_t //
wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst,uint32_t code_point)21473 wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {
21474 if (code_point <= 0x7F) {
21475 if (dst.len >= 1) {
21476 dst.ptr[0] = (uint8_t)(code_point);
21477 return 1;
21478 }
21479
21480 } else if (code_point <= 0x07FF) {
21481 if (dst.len >= 2) {
21482 dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));
21483 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
21484 return 2;
21485 }
21486
21487 } else if (code_point <= 0xFFFF) {
21488 if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {
21489 dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));
21490 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
21491 dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
21492 return 3;
21493 }
21494
21495 } else if (code_point <= 0x10FFFF) {
21496 if (dst.len >= 4) {
21497 dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));
21498 dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
21499 dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
21500 dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
21501 return 4;
21502 }
21503 }
21504
21505 return 0;
21506 }
21507
21508 // wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a
21509 // UTF-8 encoded code point, based on the encoding's initial byte.
21510 // - 0x00 is 1-byte UTF-8 (ASCII).
21511 // - 0x01 is the start of 2-byte UTF-8.
21512 // - 0x02 is the start of 3-byte UTF-8.
21513 // - 0x03 is the start of 4-byte UTF-8.
21514 // - 0x40 is a UTF-8 tail byte.
21515 // - 0x80 is invalid UTF-8.
21516 //
21517 // RFC 3629 (UTF-8) gives this grammar for valid UTF-8:
21518 // UTF8-1 = %x00-7F
21519 // UTF8-2 = %xC2-DF UTF8-tail
21520 // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
21521 // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
21522 // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
21523 // %xF4 %x80-8F 2( UTF8-tail )
21524 // UTF8-tail = %x80-BF
21525 static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {
21526 // 0 1 2 3 4 5 6 7
21527 // 8 9 A B C D E F
21528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
21529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
21530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
21531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
21532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
21533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
21534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 ..= 0x37.
21535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F.
21536
21537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
21538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
21539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
21540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
21541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
21542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
21543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
21544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
21545
21546 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x80 ..= 0x87.
21547 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x88 ..= 0x8F.
21548 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x90 ..= 0x97.
21549 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x98 ..= 0x9F.
21550 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA0 ..= 0xA7.
21551 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA8 ..= 0xAF.
21552 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB0 ..= 0xB7.
21553 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB8 ..= 0xBF.
21554
21555 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC0 ..= 0xC7.
21556 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC8 ..= 0xCF.
21557 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD0 ..= 0xD7.
21558 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD8 ..= 0xDF.
21559 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE0 ..= 0xE7.
21560 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE8 ..= 0xEF.
21561 0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
21562 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
21563 // 0 1 2 3 4 5 6 7
21564 // 8 9 A B C D E F
21565 };
21566
21567 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
wuffs_base__utf_8__next(const uint8_t * s_ptr,size_t s_len)21568 wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) {
21569 if (s_len == 0) {
21570 return wuffs_base__make_utf_8__next__output(0, 0);
21571 }
21572 uint32_t c = s_ptr[0];
21573 switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) {
21574 case 0:
21575 return wuffs_base__make_utf_8__next__output(c, 1);
21576
21577 case 1:
21578 if (s_len < 2) {
21579 break;
21580 }
21581 c = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
21582 if ((c & 0xC000) != 0x8000) {
21583 break;
21584 }
21585 c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8));
21586 return wuffs_base__make_utf_8__next__output(c, 2);
21587
21588 case 2:
21589 if (s_len < 3) {
21590 break;
21591 }
21592 c = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
21593 if ((c & 0xC0C000) != 0x808000) {
21594 break;
21595 }
21596 c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) |
21597 (0x00003F & (c >> 16));
21598 if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) {
21599 break;
21600 }
21601 return wuffs_base__make_utf_8__next__output(c, 3);
21602
21603 case 3:
21604 if (s_len < 4) {
21605 break;
21606 }
21607 c = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
21608 if ((c & 0xC0C0C000) != 0x80808000) {
21609 break;
21610 }
21611 c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) |
21612 (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24));
21613 if ((c <= 0xFFFF) || (0x110000 <= c)) {
21614 break;
21615 }
21616 return wuffs_base__make_utf_8__next__output(c, 4);
21617 }
21618
21619 return wuffs_base__make_utf_8__next__output(
21620 WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
21621 }
21622
21623 WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
wuffs_base__utf_8__next_from_end(const uint8_t * s_ptr,size_t s_len)21624 wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) {
21625 if (s_len == 0) {
21626 return wuffs_base__make_utf_8__next__output(0, 0);
21627 }
21628 const uint8_t* ptr = &s_ptr[s_len - 1];
21629 if (*ptr < 0x80) {
21630 return wuffs_base__make_utf_8__next__output(*ptr, 1);
21631
21632 } else if (*ptr < 0xC0) {
21633 const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0];
21634 uint32_t n = 1;
21635 while (ptr != too_far) {
21636 ptr--;
21637 n++;
21638 if (*ptr < 0x80) {
21639 break;
21640 } else if (*ptr < 0xC0) {
21641 continue;
21642 }
21643 wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n);
21644 if (o.byte_length != n) {
21645 break;
21646 }
21647 return o;
21648 }
21649 }
21650
21651 return wuffs_base__make_utf_8__next__output(
21652 WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
21653 }
21654
21655 WUFFS_BASE__MAYBE_STATIC size_t //
wuffs_base__utf_8__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)21656 wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
21657 // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time).
21658 //
21659 // TODO: possibly optimize this by manually inlining the
21660 // wuffs_base__utf_8__next calls.
21661 size_t original_len = s_len;
21662 while (s_len > 0) {
21663 wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len);
21664 if ((o.code_point > 0x7F) && (o.byte_length == 1)) {
21665 break;
21666 }
21667 s_ptr += o.byte_length;
21668 s_len -= o.byte_length;
21669 }
21670 return original_len - s_len;
21671 }
21672
21673 WUFFS_BASE__MAYBE_STATIC size_t //
wuffs_base__ascii__longest_valid_prefix(const uint8_t * s_ptr,size_t s_len)21674 wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
21675 // TODO: possibly optimize this by checking 4 or 8 bytes at a time.
21676 const uint8_t* original_ptr = s_ptr;
21677 const uint8_t* p = s_ptr;
21678 const uint8_t* q = s_ptr + s_len;
21679 for (; (p != q) && ((*p & 0x80) == 0); p++) {
21680 }
21681 return (size_t)(p - original_ptr);
21682 }
21683
21684 #endif // !defined(WUFFS_CONFIG__MODULES) ||
21685 // defined(WUFFS_CONFIG__MODULE__BASE) ||
21686 // defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
21687
21688 #ifdef __cplusplus
21689 } // extern "C"
21690 #endif
21691
21692 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
21693
21694 // ---------------- Status Codes Implementations
21695
21696 // ---------------- Private Consts
21697
21698 // ---------------- Private Initializer Prototypes
21699
21700 // ---------------- Private Function Prototypes
21701
21702 static wuffs_base__empty_struct
21703 wuffs_adler32__hasher__up(
21704 wuffs_adler32__hasher* self,
21705 wuffs_base__slice_u8 a_x);
21706
21707 static wuffs_base__empty_struct
21708 wuffs_adler32__hasher__up__choosy_default(
21709 wuffs_adler32__hasher* self,
21710 wuffs_base__slice_u8 a_x);
21711
21712 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21713 static wuffs_base__empty_struct
21714 wuffs_adler32__hasher__up_arm_neon(
21715 wuffs_adler32__hasher* self,
21716 wuffs_base__slice_u8 a_x);
21717 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21718
21719 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21720 static wuffs_base__empty_struct
21721 wuffs_adler32__hasher__up_x86_sse42(
21722 wuffs_adler32__hasher* self,
21723 wuffs_base__slice_u8 a_x);
21724 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21725
21726 // ---------------- VTables
21727
21728 const wuffs_base__hasher_u32__func_ptrs
21729 wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
21730 (wuffs_base__empty_struct(*)(void*,
21731 uint32_t,
21732 bool))(&wuffs_adler32__hasher__set_quirk_enabled),
21733 (uint32_t(*)(void*,
21734 wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32),
21735 };
21736
21737 // ---------------- Initializer Implementations
21738
21739 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_adler32__hasher__initialize(wuffs_adler32__hasher * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)21740 wuffs_adler32__hasher__initialize(
21741 wuffs_adler32__hasher* self,
21742 size_t sizeof_star_self,
21743 uint64_t wuffs_version,
21744 uint32_t options){
21745 if (!self) {
21746 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
21747 }
21748 if (sizeof(*self) != sizeof_star_self) {
21749 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
21750 }
21751 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
21752 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
21753 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
21754 }
21755
21756 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
21757 // The whole point of this if-check is to detect an uninitialized *self.
21758 // We disable the warning on GCC. Clang-5.0 does not have this warning.
21759 #if !defined(__clang__) && defined(__GNUC__)
21760 #pragma GCC diagnostic push
21761 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
21762 #endif
21763 if (self->private_impl.magic != 0) {
21764 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
21765 }
21766 #if !defined(__clang__) && defined(__GNUC__)
21767 #pragma GCC diagnostic pop
21768 #endif
21769 } else {
21770 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
21771 memset(self, 0, sizeof(*self));
21772 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
21773 } else {
21774 memset(&(self->private_impl), 0, sizeof(self->private_impl));
21775 }
21776 }
21777
21778 self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default;
21779
21780 self->private_impl.magic = WUFFS_BASE__MAGIC;
21781 self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
21782 wuffs_base__hasher_u32__vtable_name;
21783 self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
21784 (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
21785 return wuffs_base__make_status(NULL);
21786 }
21787
21788 wuffs_adler32__hasher*
wuffs_adler32__hasher__alloc()21789 wuffs_adler32__hasher__alloc() {
21790 wuffs_adler32__hasher* x =
21791 (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
21792 if (!x) {
21793 return NULL;
21794 }
21795 if (wuffs_adler32__hasher__initialize(
21796 x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
21797 free(x);
21798 return NULL;
21799 }
21800 return x;
21801 }
21802
21803 size_t
sizeof__wuffs_adler32__hasher()21804 sizeof__wuffs_adler32__hasher() {
21805 return sizeof(wuffs_adler32__hasher);
21806 }
21807
21808 // ---------------- Function Implementations
21809
21810 // -------- func adler32.hasher.set_quirk_enabled
21811
21812 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_adler32__hasher__set_quirk_enabled(wuffs_adler32__hasher * self,uint32_t a_quirk,bool a_enabled)21813 wuffs_adler32__hasher__set_quirk_enabled(
21814 wuffs_adler32__hasher* self,
21815 uint32_t a_quirk,
21816 bool a_enabled) {
21817 return wuffs_base__make_empty_struct();
21818 }
21819
21820 // -------- func adler32.hasher.update_u32
21821
21822 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_adler32__hasher__update_u32(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21823 wuffs_adler32__hasher__update_u32(
21824 wuffs_adler32__hasher* self,
21825 wuffs_base__slice_u8 a_x) {
21826 if (!self) {
21827 return 0;
21828 }
21829 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
21830 return 0;
21831 }
21832
21833 if ( ! self->private_impl.f_started) {
21834 self->private_impl.f_started = true;
21835 self->private_impl.f_state = 1;
21836 self->private_impl.choosy_up = (
21837 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21838 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon :
21839 #endif
21840 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
21841 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 :
21842 #endif
21843 self->private_impl.choosy_up);
21844 }
21845 wuffs_adler32__hasher__up(self, a_x);
21846 return self->private_impl.f_state;
21847 }
21848
21849 // -------- func adler32.hasher.up
21850
21851 static wuffs_base__empty_struct
wuffs_adler32__hasher__up(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21852 wuffs_adler32__hasher__up(
21853 wuffs_adler32__hasher* self,
21854 wuffs_base__slice_u8 a_x) {
21855 return (*self->private_impl.choosy_up)(self, a_x);
21856 }
21857
21858 static wuffs_base__empty_struct
wuffs_adler32__hasher__up__choosy_default(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21859 wuffs_adler32__hasher__up__choosy_default(
21860 wuffs_adler32__hasher* self,
21861 wuffs_base__slice_u8 a_x) {
21862 uint32_t v_s1 = 0;
21863 uint32_t v_s2 = 0;
21864 wuffs_base__slice_u8 v_remaining = {0};
21865 wuffs_base__slice_u8 v_p = {0};
21866
21867 v_s1 = ((self->private_impl.f_state) & 0xFFFF);
21868 v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
21869 while (((uint64_t)(a_x.len)) > 0) {
21870 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
21871 if (((uint64_t)(a_x.len)) > 5552) {
21872 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552);
21873 a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552);
21874 }
21875 {
21876 wuffs_base__slice_u8 i_slice_p = a_x;
21877 v_p.ptr = i_slice_p.ptr;
21878 v_p.len = 1;
21879 uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
21880 while (v_p.ptr < i_end0_p) {
21881 v_s1 += ((uint32_t)(v_p.ptr[0]));
21882 v_s2 += v_s1;
21883 v_p.ptr += 1;
21884 v_s1 += ((uint32_t)(v_p.ptr[0]));
21885 v_s2 += v_s1;
21886 v_p.ptr += 1;
21887 v_s1 += ((uint32_t)(v_p.ptr[0]));
21888 v_s2 += v_s1;
21889 v_p.ptr += 1;
21890 v_s1 += ((uint32_t)(v_p.ptr[0]));
21891 v_s2 += v_s1;
21892 v_p.ptr += 1;
21893 v_s1 += ((uint32_t)(v_p.ptr[0]));
21894 v_s2 += v_s1;
21895 v_p.ptr += 1;
21896 v_s1 += ((uint32_t)(v_p.ptr[0]));
21897 v_s2 += v_s1;
21898 v_p.ptr += 1;
21899 v_s1 += ((uint32_t)(v_p.ptr[0]));
21900 v_s2 += v_s1;
21901 v_p.ptr += 1;
21902 v_s1 += ((uint32_t)(v_p.ptr[0]));
21903 v_s2 += v_s1;
21904 v_p.ptr += 1;
21905 }
21906 v_p.len = 1;
21907 uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
21908 while (v_p.ptr < i_end1_p) {
21909 v_s1 += ((uint32_t)(v_p.ptr[0]));
21910 v_s2 += v_s1;
21911 v_p.ptr += 1;
21912 }
21913 v_p.len = 0;
21914 }
21915 v_s1 %= 65521;
21916 v_s2 %= 65521;
21917 a_x = v_remaining;
21918 }
21919 self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
21920 return wuffs_base__make_empty_struct();
21921 }
21922
21923 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
21924 // -------- func adler32.hasher.up_arm_neon
21925
21926 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
21927 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_arm_neon(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)21928 wuffs_adler32__hasher__up_arm_neon(
21929 wuffs_adler32__hasher* self,
21930 wuffs_base__slice_u8 a_x) {
21931 uint32_t v_s1 = 0;
21932 uint32_t v_s2 = 0;
21933 wuffs_base__slice_u8 v_remaining = {0};
21934 wuffs_base__slice_u8 v_p = {0};
21935 uint8x16_t v_p__left = {0};
21936 uint8x16_t v_p_right = {0};
21937 uint32x4_t v_v1 = {0};
21938 uint32x4_t v_v2 = {0};
21939 uint16x8_t v_col0 = {0};
21940 uint16x8_t v_col1 = {0};
21941 uint16x8_t v_col2 = {0};
21942 uint16x8_t v_col3 = {0};
21943 uint32x2_t v_sum1 = {0};
21944 uint32x2_t v_sum2 = {0};
21945 uint32x2_t v_sum12 = {0};
21946 uint32_t v_num_iterate_bytes = 0;
21947 uint64_t v_tail_index = 0;
21948
21949 v_s1 = ((self->private_impl.f_state) & 0xFFFF);
21950 v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
21951 while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
21952 v_s1 += ((uint32_t)(a_x.ptr[0]));
21953 v_s2 += v_s1;
21954 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
21955 }
21956 v_s1 %= 65521;
21957 v_s2 %= 65521;
21958 while (((uint64_t)(a_x.len)) > 0) {
21959 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
21960 if (((uint64_t)(a_x.len)) > 5536) {
21961 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536);
21962 a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536);
21963 }
21964 v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264)));
21965 v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
21966 v_v1 = vdupq_n_u32(0);
21967 v_v2 = vdupq_n_u32(0);
21968 v_col0 = vdupq_n_u16(0);
21969 v_col1 = vdupq_n_u16(0);
21970 v_col2 = vdupq_n_u16(0);
21971 v_col3 = vdupq_n_u16(0);
21972 {
21973 wuffs_base__slice_u8 i_slice_p = a_x;
21974 v_p.ptr = i_slice_p.ptr;
21975 v_p.len = 32;
21976 uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
21977 while (v_p.ptr < i_end0_p) {
21978 v_p__left = vld1q_u8(v_p.ptr);
21979 v_p_right = vld1q_u8(v_p.ptr + 16);
21980 v_v2 = vaddq_u32(v_v2, v_v1);
21981 v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right));
21982 v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left));
21983 v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left));
21984 v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right));
21985 v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right));
21986 v_p.ptr += 32;
21987 }
21988 v_p.len = 0;
21989 }
21990
21991 static const uint16x4_t table_0 {32, 31, 30, 29};
21992 static const uint16x4_t table_1 {28, 27, 26, 25};
21993 static const uint16x4_t table_2 {24, 23, 22, 21};
21994 static const uint16x4_t table_3 {20, 19, 18, 17};
21995 static const uint16x4_t table_4 {16, 15, 14, 13};
21996 static const uint16x4_t table_5 {12, 11, 10, 9};
21997 static const uint16x4_t table_6 { 8, 7, 6, 5};
21998 static const uint16x4_t table_7 { 4, 3, 2, 1};
21999
22000 v_v2 = vshlq_n_u32(v_v2, 5);
22001 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), table_0);
22002 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), table_1);
22003 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), table_2);
22004 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), table_3);
22005 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), table_4);
22006 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), table_5);
22007 v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), table_6);
22008 v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), table_7);
22009 v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1));
22010 v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2));
22011 v_sum12 = vpadd_u32(v_sum1, v_sum2);
22012 v_s1 += vget_lane_u32(v_sum12, 0);
22013 v_s2 += vget_lane_u32(v_sum12, 1);
22014 v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
22015 if (v_tail_index < ((uint64_t)(a_x.len))) {
22016 {
22017 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
22018 v_p.ptr = i_slice_p.ptr;
22019 v_p.len = 1;
22020 uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
22021 while (v_p.ptr < i_end0_p) {
22022 v_s1 += ((uint32_t)(v_p.ptr[0]));
22023 v_s2 += v_s1;
22024 v_p.ptr += 1;
22025 }
22026 v_p.len = 0;
22027 }
22028 }
22029 v_s1 %= 65521;
22030 v_s2 %= 65521;
22031 a_x = v_remaining;
22032 }
22033 self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
22034 return wuffs_base__make_empty_struct();
22035 }
22036 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
22037 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
22038
22039 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
22040 // -------- func adler32.hasher.up_x86_sse42
22041
22042 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
22043 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
22044 static wuffs_base__empty_struct
wuffs_adler32__hasher__up_x86_sse42(wuffs_adler32__hasher * self,wuffs_base__slice_u8 a_x)22045 wuffs_adler32__hasher__up_x86_sse42(
22046 wuffs_adler32__hasher* self,
22047 wuffs_base__slice_u8 a_x) {
22048 uint32_t v_s1 = 0;
22049 uint32_t v_s2 = 0;
22050 wuffs_base__slice_u8 v_remaining = {0};
22051 wuffs_base__slice_u8 v_p = {0};
22052 __m128i v_zeroes = {0};
22053 __m128i v_ones = {0};
22054 __m128i v_weights__left = {0};
22055 __m128i v_weights_right = {0};
22056 __m128i v_q__left = {0};
22057 __m128i v_q_right = {0};
22058 __m128i v_v1 = {0};
22059 __m128i v_v2 = {0};
22060 __m128i v_v2j = {0};
22061 __m128i v_v2k = {0};
22062 uint32_t v_num_iterate_bytes = 0;
22063 uint64_t v_tail_index = 0;
22064
22065 v_zeroes = _mm_set1_epi16((int16_t)(0));
22066 v_ones = _mm_set1_epi16((int16_t)(1));
22067 v_weights__left = _mm_set_epi8((int8_t)(17), (int8_t)(18), (int8_t)(19), (int8_t)(20), (int8_t)(21), (int8_t)(22), (int8_t)(23), (int8_t)(24), (int8_t)(25), (int8_t)(26), (int8_t)(27), (int8_t)(28), (int8_t)(29), (int8_t)(30), (int8_t)(31), (int8_t)(32));
22068 v_weights_right = _mm_set_epi8((int8_t)(1), (int8_t)(2), (int8_t)(3), (int8_t)(4), (int8_t)(5), (int8_t)(6), (int8_t)(7), (int8_t)(8), (int8_t)(9), (int8_t)(10), (int8_t)(11), (int8_t)(12), (int8_t)(13), (int8_t)(14), (int8_t)(15), (int8_t)(16));
22069 v_s1 = ((self->private_impl.f_state) & 0xFFFF);
22070 v_s2 = ((self->private_impl.f_state) >> (32 - (16)));
22071 while (((uint64_t)(a_x.len)) > 0) {
22072 v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0);
22073 if (((uint64_t)(a_x.len)) > 5536) {
22074 v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536);
22075 a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536);
22076 }
22077 v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264)));
22078 v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
22079 v_v1 = _mm_setzero_si128();
22080 v_v2j = _mm_setzero_si128();
22081 v_v2k = _mm_setzero_si128();
22082 {
22083 wuffs_base__slice_u8 i_slice_p = a_x;
22084 v_p.ptr = i_slice_p.ptr;
22085 v_p.len = 32;
22086 uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
22087 while (v_p.ptr < i_end0_p) {
22088 v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr));
22089 v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16));
22090 v_v2j = _mm_add_epi32(v_v2j, v_v1);
22091 v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes));
22092 v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes));
22093 v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left)));
22094 v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right)));
22095 v_p.ptr += 32;
22096 }
22097 v_p.len = 0;
22098 }
22099 v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177)));
22100 v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78)));
22101 v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1)));
22102 v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5)));
22103 v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177)));
22104 v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78)));
22105 v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2)));
22106 v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
22107 if (v_tail_index < ((uint64_t)(a_x.len))) {
22108 {
22109 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
22110 v_p.ptr = i_slice_p.ptr;
22111 v_p.len = 1;
22112 uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
22113 while (v_p.ptr < i_end0_p) {
22114 v_s1 += ((uint32_t)(v_p.ptr[0]));
22115 v_s2 += v_s1;
22116 v_p.ptr += 1;
22117 }
22118 v_p.len = 0;
22119 }
22120 }
22121 v_s1 %= 65521;
22122 v_s2 %= 65521;
22123 a_x = v_remaining;
22124 }
22125 self->private_impl.f_state = (((v_s2 & 65535) << 16) | (v_s1 & 65535));
22126 return wuffs_base__make_empty_struct();
22127 }
22128 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
22129 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
22130
22131 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
22132
22133 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
22134
22135 // ---------------- Status Codes Implementations
22136
22137 const char wuffs_bmp__error__bad_header[] = "#bmp: bad header";
22138 const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression";
22139 const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file";
22140 const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read";
22141
22142 // ---------------- Private Consts
22143
22144 #define WUFFS_BMP__COMPRESSION_NONE 0
22145
22146 #define WUFFS_BMP__COMPRESSION_RLE8 1
22147
22148 #define WUFFS_BMP__COMPRESSION_RLE4 2
22149
22150 #define WUFFS_BMP__COMPRESSION_BITFIELDS 3
22151
22152 #define WUFFS_BMP__COMPRESSION_JPEG 4
22153
22154 #define WUFFS_BMP__COMPRESSION_PNG 5
22155
22156 #define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6
22157
22158 #define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256
22159
22160 #define WUFFS_BMP__RLE_STATE_NEUTRAL 0
22161
22162 #define WUFFS_BMP__RLE_STATE_RUN 1
22163
22164 #define WUFFS_BMP__RLE_STATE_ESCAPE 2
22165
22166 #define WUFFS_BMP__RLE_STATE_LITERAL 3
22167
22168 #define WUFFS_BMP__RLE_STATE_DELTA_X 4
22169
22170 #define WUFFS_BMP__RLE_STATE_DELTA_Y 5
22171
22172 // ---------------- Private Initializer Prototypes
22173
22174 // ---------------- Private Function Prototypes
22175
22176 static wuffs_base__status
22177 wuffs_bmp__decoder__swizzle_none(
22178 wuffs_bmp__decoder* self,
22179 wuffs_base__pixel_buffer* a_dst,
22180 wuffs_base__io_buffer* a_src);
22181
22182 static wuffs_base__status
22183 wuffs_bmp__decoder__swizzle_rle(
22184 wuffs_bmp__decoder* self,
22185 wuffs_base__pixel_buffer* a_dst,
22186 wuffs_base__io_buffer* a_src);
22187
22188 static wuffs_base__status
22189 wuffs_bmp__decoder__swizzle_bitfields(
22190 wuffs_bmp__decoder* self,
22191 wuffs_base__pixel_buffer* a_dst,
22192 wuffs_base__io_buffer* a_src);
22193
22194 static wuffs_base__status
22195 wuffs_bmp__decoder__swizzle_low_bit_depth(
22196 wuffs_bmp__decoder* self,
22197 wuffs_base__pixel_buffer* a_dst,
22198 wuffs_base__io_buffer* a_src);
22199
22200 static wuffs_base__status
22201 wuffs_bmp__decoder__read_palette(
22202 wuffs_bmp__decoder* self,
22203 wuffs_base__io_buffer* a_src);
22204
22205 static wuffs_base__status
22206 wuffs_bmp__decoder__process_masks(
22207 wuffs_bmp__decoder* self);
22208
22209 // ---------------- VTables
22210
22211 const wuffs_base__image_decoder__func_ptrs
22212 wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
22213 (wuffs_base__status(*)(void*,
22214 wuffs_base__pixel_buffer*,
22215 wuffs_base__io_buffer*,
22216 wuffs_base__pixel_blend,
22217 wuffs_base__slice_u8,
22218 wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame),
22219 (wuffs_base__status(*)(void*,
22220 wuffs_base__frame_config*,
22221 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config),
22222 (wuffs_base__status(*)(void*,
22223 wuffs_base__image_config*,
22224 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config),
22225 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect),
22226 (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops),
22227 (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs),
22228 (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames),
22229 (wuffs_base__status(*)(void*,
22230 uint64_t,
22231 uint64_t))(&wuffs_bmp__decoder__restart_frame),
22232 (wuffs_base__empty_struct(*)(void*,
22233 uint32_t,
22234 bool))(&wuffs_bmp__decoder__set_quirk_enabled),
22235 (wuffs_base__empty_struct(*)(void*,
22236 uint32_t,
22237 bool))(&wuffs_bmp__decoder__set_report_metadata),
22238 (wuffs_base__status(*)(void*,
22239 wuffs_base__io_buffer*,
22240 wuffs_base__more_information*,
22241 wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more),
22242 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len),
22243 };
22244
22245 // ---------------- Initializer Implementations
22246
22247 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_bmp__decoder__initialize(wuffs_bmp__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)22248 wuffs_bmp__decoder__initialize(
22249 wuffs_bmp__decoder* self,
22250 size_t sizeof_star_self,
22251 uint64_t wuffs_version,
22252 uint32_t options){
22253 if (!self) {
22254 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22255 }
22256 if (sizeof(*self) != sizeof_star_self) {
22257 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
22258 }
22259 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
22260 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
22261 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
22262 }
22263
22264 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
22265 // The whole point of this if-check is to detect an uninitialized *self.
22266 // We disable the warning on GCC. Clang-5.0 does not have this warning.
22267 #if !defined(__clang__) && defined(__GNUC__)
22268 #pragma GCC diagnostic push
22269 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
22270 #endif
22271 if (self->private_impl.magic != 0) {
22272 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
22273 }
22274 #if !defined(__clang__) && defined(__GNUC__)
22275 #pragma GCC diagnostic pop
22276 #endif
22277 } else {
22278 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
22279 memset(self, 0, sizeof(*self));
22280 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
22281 } else {
22282 memset(&(self->private_impl), 0, sizeof(self->private_impl));
22283 }
22284 }
22285
22286 self->private_impl.magic = WUFFS_BASE__MAGIC;
22287 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
22288 wuffs_base__image_decoder__vtable_name;
22289 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
22290 (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
22291 return wuffs_base__make_status(NULL);
22292 }
22293
22294 wuffs_bmp__decoder*
wuffs_bmp__decoder__alloc()22295 wuffs_bmp__decoder__alloc() {
22296 wuffs_bmp__decoder* x =
22297 (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
22298 if (!x) {
22299 return NULL;
22300 }
22301 if (wuffs_bmp__decoder__initialize(
22302 x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
22303 free(x);
22304 return NULL;
22305 }
22306 return x;
22307 }
22308
22309 size_t
sizeof__wuffs_bmp__decoder()22310 sizeof__wuffs_bmp__decoder() {
22311 return sizeof(wuffs_bmp__decoder);
22312 }
22313
22314 // ---------------- Function Implementations
22315
22316 // -------- func bmp.decoder.set_quirk_enabled
22317
22318 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_bmp__decoder__set_quirk_enabled(wuffs_bmp__decoder * self,uint32_t a_quirk,bool a_enabled)22319 wuffs_bmp__decoder__set_quirk_enabled(
22320 wuffs_bmp__decoder* self,
22321 uint32_t a_quirk,
22322 bool a_enabled) {
22323 return wuffs_base__make_empty_struct();
22324 }
22325
22326 // -------- func bmp.decoder.decode_image_config
22327
22328 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__decode_image_config(wuffs_bmp__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)22329 wuffs_bmp__decoder__decode_image_config(
22330 wuffs_bmp__decoder* self,
22331 wuffs_base__image_config* a_dst,
22332 wuffs_base__io_buffer* a_src) {
22333 if (!self) {
22334 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
22335 }
22336 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
22337 return wuffs_base__make_status(
22338 (self->private_impl.magic == WUFFS_BASE__DISABLED)
22339 ? wuffs_base__error__disabled_by_previous_error
22340 : wuffs_base__error__initialize_not_called);
22341 }
22342 if (!a_src) {
22343 self->private_impl.magic = WUFFS_BASE__DISABLED;
22344 return wuffs_base__make_status(wuffs_base__error__bad_argument);
22345 }
22346 if ((self->private_impl.active_coroutine != 0) &&
22347 (self->private_impl.active_coroutine != 1)) {
22348 self->private_impl.magic = WUFFS_BASE__DISABLED;
22349 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
22350 }
22351 self->private_impl.active_coroutine = 0;
22352 wuffs_base__status status = wuffs_base__make_status(NULL);
22353
22354 uint32_t v_magic = 0;
22355 uint32_t v_width = 0;
22356 uint32_t v_height = 0;
22357 uint32_t v_planes = 0;
22358 uint32_t v_dst_pixfmt = 0;
22359 uint32_t v_byte_width = 0;
22360
22361 const uint8_t* iop_a_src = NULL;
22362 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22363 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22364 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
22365 if (a_src) {
22366 io0_a_src = a_src->data.ptr;
22367 io1_a_src = io0_a_src + a_src->meta.ri;
22368 iop_a_src = io1_a_src;
22369 io2_a_src = io0_a_src + a_src->meta.wi;
22370 }
22371
22372 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
22373 switch (coro_susp_point) {
22374 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
22375
22376 if ((self->private_impl.f_call_sequence != 0) || (self->private_impl.f_io_redirect_fourcc == 1)) {
22377 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
22378 goto exit;
22379 } else if (self->private_impl.f_io_redirect_fourcc != 0) {
22380 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22381 goto ok;
22382 }
22383 {
22384 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
22385 uint32_t t_0;
22386 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22387 t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22388 iop_a_src += 2;
22389 } else {
22390 self->private_data.s_decode_image_config[0].scratch = 0;
22391 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
22392 while (true) {
22393 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22394 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22395 goto suspend;
22396 }
22397 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22398 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
22399 *scratch <<= 8;
22400 *scratch >>= 8;
22401 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
22402 if (num_bits_0 == 8) {
22403 t_0 = ((uint32_t)(*scratch));
22404 break;
22405 }
22406 num_bits_0 += 8;
22407 *scratch |= ((uint64_t)(num_bits_0)) << 56;
22408 }
22409 }
22410 v_magic = t_0;
22411 }
22412 if (v_magic != 19778) {
22413 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22414 goto exit;
22415 }
22416 self->private_data.s_decode_image_config[0].scratch = 8;
22417 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
22418 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22419 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22420 iop_a_src = io2_a_src;
22421 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22422 goto suspend;
22423 }
22424 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
22425 {
22426 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
22427 uint32_t t_1;
22428 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22429 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22430 iop_a_src += 4;
22431 } else {
22432 self->private_data.s_decode_image_config[0].scratch = 0;
22433 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
22434 while (true) {
22435 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22436 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22437 goto suspend;
22438 }
22439 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22440 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
22441 *scratch <<= 8;
22442 *scratch >>= 8;
22443 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
22444 if (num_bits_1 == 24) {
22445 t_1 = ((uint32_t)(*scratch));
22446 break;
22447 }
22448 num_bits_1 += 8;
22449 *scratch |= ((uint64_t)(num_bits_1)) << 56;
22450 }
22451 }
22452 self->private_impl.f_padding = t_1;
22453 }
22454 if (self->private_impl.f_padding < 14) {
22455 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22456 goto exit;
22457 }
22458 self->private_impl.f_padding -= 14;
22459 self->private_impl.f_io_redirect_pos = wuffs_base__u64__sat_add(((uint64_t)(self->private_impl.f_padding)), wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))));
22460 {
22461 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
22462 uint32_t t_2;
22463 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22464 t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22465 iop_a_src += 4;
22466 } else {
22467 self->private_data.s_decode_image_config[0].scratch = 0;
22468 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
22469 while (true) {
22470 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22471 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22472 goto suspend;
22473 }
22474 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22475 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
22476 *scratch <<= 8;
22477 *scratch >>= 8;
22478 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
22479 if (num_bits_2 == 24) {
22480 t_2 = ((uint32_t)(*scratch));
22481 break;
22482 }
22483 num_bits_2 += 8;
22484 *scratch |= ((uint64_t)(num_bits_2)) << 56;
22485 }
22486 }
22487 self->private_impl.f_bitmap_info_len = t_2;
22488 }
22489 if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) {
22490 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22491 goto exit;
22492 }
22493 self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len;
22494 if (self->private_impl.f_bitmap_info_len == 12) {
22495 {
22496 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
22497 uint32_t t_3;
22498 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22499 t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22500 iop_a_src += 2;
22501 } else {
22502 self->private_data.s_decode_image_config[0].scratch = 0;
22503 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
22504 while (true) {
22505 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22506 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22507 goto suspend;
22508 }
22509 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22510 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
22511 *scratch <<= 8;
22512 *scratch >>= 8;
22513 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
22514 if (num_bits_3 == 8) {
22515 t_3 = ((uint32_t)(*scratch));
22516 break;
22517 }
22518 num_bits_3 += 8;
22519 *scratch |= ((uint64_t)(num_bits_3)) << 56;
22520 }
22521 }
22522 self->private_impl.f_width = t_3;
22523 }
22524 {
22525 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
22526 uint32_t t_4;
22527 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22528 t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22529 iop_a_src += 2;
22530 } else {
22531 self->private_data.s_decode_image_config[0].scratch = 0;
22532 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
22533 while (true) {
22534 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22535 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22536 goto suspend;
22537 }
22538 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22539 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
22540 *scratch <<= 8;
22541 *scratch >>= 8;
22542 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
22543 if (num_bits_4 == 8) {
22544 t_4 = ((uint32_t)(*scratch));
22545 break;
22546 }
22547 num_bits_4 += 8;
22548 *scratch |= ((uint64_t)(num_bits_4)) << 56;
22549 }
22550 }
22551 self->private_impl.f_height = t_4;
22552 }
22553 {
22554 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
22555 uint32_t t_5;
22556 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22557 t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22558 iop_a_src += 2;
22559 } else {
22560 self->private_data.s_decode_image_config[0].scratch = 0;
22561 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
22562 while (true) {
22563 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22564 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22565 goto suspend;
22566 }
22567 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22568 uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
22569 *scratch <<= 8;
22570 *scratch >>= 8;
22571 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
22572 if (num_bits_5 == 8) {
22573 t_5 = ((uint32_t)(*scratch));
22574 break;
22575 }
22576 num_bits_5 += 8;
22577 *scratch |= ((uint64_t)(num_bits_5)) << 56;
22578 }
22579 }
22580 v_planes = t_5;
22581 }
22582 if (v_planes != 1) {
22583 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22584 goto exit;
22585 }
22586 {
22587 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
22588 uint32_t t_6;
22589 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22590 t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22591 iop_a_src += 2;
22592 } else {
22593 self->private_data.s_decode_image_config[0].scratch = 0;
22594 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
22595 while (true) {
22596 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22597 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22598 goto suspend;
22599 }
22600 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22601 uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
22602 *scratch <<= 8;
22603 *scratch >>= 8;
22604 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
22605 if (num_bits_6 == 8) {
22606 t_6 = ((uint32_t)(*scratch));
22607 break;
22608 }
22609 num_bits_6 += 8;
22610 *scratch |= ((uint64_t)(num_bits_6)) << 56;
22611 }
22612 }
22613 self->private_impl.f_bits_per_pixel = t_6;
22614 }
22615 } else if (self->private_impl.f_bitmap_info_len == 16) {
22616 {
22617 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
22618 uint32_t t_7;
22619 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22620 t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22621 iop_a_src += 4;
22622 } else {
22623 self->private_data.s_decode_image_config[0].scratch = 0;
22624 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
22625 while (true) {
22626 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22627 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22628 goto suspend;
22629 }
22630 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22631 uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
22632 *scratch <<= 8;
22633 *scratch >>= 8;
22634 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
22635 if (num_bits_7 == 24) {
22636 t_7 = ((uint32_t)(*scratch));
22637 break;
22638 }
22639 num_bits_7 += 8;
22640 *scratch |= ((uint64_t)(num_bits_7)) << 56;
22641 }
22642 }
22643 v_width = t_7;
22644 }
22645 if (v_width >= 2147483648) {
22646 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22647 goto exit;
22648 }
22649 self->private_impl.f_width = v_width;
22650 {
22651 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
22652 uint32_t t_8;
22653 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22654 t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22655 iop_a_src += 4;
22656 } else {
22657 self->private_data.s_decode_image_config[0].scratch = 0;
22658 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
22659 while (true) {
22660 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22661 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22662 goto suspend;
22663 }
22664 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22665 uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
22666 *scratch <<= 8;
22667 *scratch >>= 8;
22668 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
22669 if (num_bits_8 == 24) {
22670 t_8 = ((uint32_t)(*scratch));
22671 break;
22672 }
22673 num_bits_8 += 8;
22674 *scratch |= ((uint64_t)(num_bits_8)) << 56;
22675 }
22676 }
22677 v_height = t_8;
22678 }
22679 if (v_height >= 2147483648) {
22680 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22681 goto exit;
22682 }
22683 self->private_impl.f_height = v_height;
22684 {
22685 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
22686 uint32_t t_9;
22687 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22688 t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22689 iop_a_src += 2;
22690 } else {
22691 self->private_data.s_decode_image_config[0].scratch = 0;
22692 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
22693 while (true) {
22694 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22695 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22696 goto suspend;
22697 }
22698 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22699 uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
22700 *scratch <<= 8;
22701 *scratch >>= 8;
22702 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
22703 if (num_bits_9 == 8) {
22704 t_9 = ((uint32_t)(*scratch));
22705 break;
22706 }
22707 num_bits_9 += 8;
22708 *scratch |= ((uint64_t)(num_bits_9)) << 56;
22709 }
22710 }
22711 v_planes = t_9;
22712 }
22713 if (v_planes != 1) {
22714 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22715 goto exit;
22716 }
22717 {
22718 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
22719 uint32_t t_10;
22720 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22721 t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22722 iop_a_src += 2;
22723 } else {
22724 self->private_data.s_decode_image_config[0].scratch = 0;
22725 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
22726 while (true) {
22727 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22728 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22729 goto suspend;
22730 }
22731 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22732 uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
22733 *scratch <<= 8;
22734 *scratch >>= 8;
22735 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
22736 if (num_bits_10 == 8) {
22737 t_10 = ((uint32_t)(*scratch));
22738 break;
22739 }
22740 num_bits_10 += 8;
22741 *scratch |= ((uint64_t)(num_bits_10)) << 56;
22742 }
22743 }
22744 self->private_impl.f_bits_per_pixel = t_10;
22745 }
22746 } else {
22747 {
22748 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
22749 uint32_t t_11;
22750 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22751 t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22752 iop_a_src += 4;
22753 } else {
22754 self->private_data.s_decode_image_config[0].scratch = 0;
22755 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
22756 while (true) {
22757 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22758 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22759 goto suspend;
22760 }
22761 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22762 uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
22763 *scratch <<= 8;
22764 *scratch >>= 8;
22765 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
22766 if (num_bits_11 == 24) {
22767 t_11 = ((uint32_t)(*scratch));
22768 break;
22769 }
22770 num_bits_11 += 8;
22771 *scratch |= ((uint64_t)(num_bits_11)) << 56;
22772 }
22773 }
22774 v_width = t_11;
22775 }
22776 if (v_width >= 2147483648) {
22777 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22778 goto exit;
22779 }
22780 self->private_impl.f_width = v_width;
22781 {
22782 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
22783 uint32_t t_12;
22784 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22785 t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22786 iop_a_src += 4;
22787 } else {
22788 self->private_data.s_decode_image_config[0].scratch = 0;
22789 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
22790 while (true) {
22791 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22792 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22793 goto suspend;
22794 }
22795 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22796 uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
22797 *scratch <<= 8;
22798 *scratch >>= 8;
22799 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
22800 if (num_bits_12 == 24) {
22801 t_12 = ((uint32_t)(*scratch));
22802 break;
22803 }
22804 num_bits_12 += 8;
22805 *scratch |= ((uint64_t)(num_bits_12)) << 56;
22806 }
22807 }
22808 v_height = t_12;
22809 }
22810 if (v_height == 2147483648) {
22811 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
22812 goto exit;
22813 } else if (v_height >= 2147483648) {
22814 self->private_impl.f_height = (((uint32_t)(0 - v_height)) & 2147483647);
22815 self->private_impl.f_top_down = true;
22816 } else {
22817 self->private_impl.f_height = v_height;
22818 }
22819 {
22820 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
22821 uint32_t t_13;
22822 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22823 t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22824 iop_a_src += 2;
22825 } else {
22826 self->private_data.s_decode_image_config[0].scratch = 0;
22827 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
22828 while (true) {
22829 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22830 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22831 goto suspend;
22832 }
22833 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22834 uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56));
22835 *scratch <<= 8;
22836 *scratch >>= 8;
22837 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13;
22838 if (num_bits_13 == 8) {
22839 t_13 = ((uint32_t)(*scratch));
22840 break;
22841 }
22842 num_bits_13 += 8;
22843 *scratch |= ((uint64_t)(num_bits_13)) << 56;
22844 }
22845 }
22846 v_planes = t_13;
22847 }
22848 if (v_planes != 1) {
22849 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22850 goto exit;
22851 }
22852 {
22853 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
22854 uint32_t t_14;
22855 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
22856 t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
22857 iop_a_src += 2;
22858 } else {
22859 self->private_data.s_decode_image_config[0].scratch = 0;
22860 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31);
22861 while (true) {
22862 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22863 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22864 goto suspend;
22865 }
22866 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22867 uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56));
22868 *scratch <<= 8;
22869 *scratch >>= 8;
22870 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14;
22871 if (num_bits_14 == 8) {
22872 t_14 = ((uint32_t)(*scratch));
22873 break;
22874 }
22875 num_bits_14 += 8;
22876 *scratch |= ((uint64_t)(num_bits_14)) << 56;
22877 }
22878 }
22879 self->private_impl.f_bits_per_pixel = t_14;
22880 }
22881 {
22882 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
22883 uint32_t t_15;
22884 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22885 t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22886 iop_a_src += 4;
22887 } else {
22888 self->private_data.s_decode_image_config[0].scratch = 0;
22889 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
22890 while (true) {
22891 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22892 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22893 goto suspend;
22894 }
22895 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22896 uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56));
22897 *scratch <<= 8;
22898 *scratch >>= 8;
22899 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15;
22900 if (num_bits_15 == 24) {
22901 t_15 = ((uint32_t)(*scratch));
22902 break;
22903 }
22904 num_bits_15 += 8;
22905 *scratch |= ((uint64_t)(num_bits_15)) << 56;
22906 }
22907 }
22908 self->private_impl.f_compression = t_15;
22909 }
22910 if (self->private_impl.f_bits_per_pixel == 0) {
22911 if (self->private_impl.f_compression == 4) {
22912 self->private_impl.f_io_redirect_fourcc = 1246774599;
22913 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22914 goto ok;
22915 } else if (self->private_impl.f_compression == 5) {
22916 self->private_impl.f_io_redirect_fourcc = 1347307296;
22917 status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
22918 goto ok;
22919 }
22920 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22921 goto exit;
22922 }
22923 self->private_data.s_decode_image_config[0].scratch = 20;
22924 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34);
22925 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
22926 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
22927 iop_a_src = io2_a_src;
22928 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22929 goto suspend;
22930 }
22931 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
22932 if (self->private_impl.f_bitmap_info_len == 40) {
22933 if (self->private_impl.f_bits_per_pixel >= 16) {
22934 if (self->private_impl.f_padding >= 16) {
22935 self->private_impl.f_bitmap_info_len = 56;
22936 self->private_impl.f_padding -= 16;
22937 } else if (self->private_impl.f_padding >= 12) {
22938 self->private_impl.f_bitmap_info_len = 52;
22939 self->private_impl.f_padding -= 12;
22940 }
22941 }
22942 } else if ((self->private_impl.f_bitmap_info_len != 52) &&
22943 (self->private_impl.f_bitmap_info_len != 56) &&
22944 (self->private_impl.f_bitmap_info_len != 64) &&
22945 (self->private_impl.f_bitmap_info_len != 108) &&
22946 (self->private_impl.f_bitmap_info_len != 124)) {
22947 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
22948 goto exit;
22949 }
22950 if (self->private_impl.f_compression == 6) {
22951 self->private_impl.f_compression = 3;
22952 }
22953 if (self->private_impl.f_compression == 3) {
22954 if (self->private_impl.f_bitmap_info_len >= 52) {
22955 {
22956 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35);
22957 uint32_t t_16;
22958 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22959 t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22960 iop_a_src += 4;
22961 } else {
22962 self->private_data.s_decode_image_config[0].scratch = 0;
22963 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36);
22964 while (true) {
22965 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22966 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22967 goto suspend;
22968 }
22969 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22970 uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56));
22971 *scratch <<= 8;
22972 *scratch >>= 8;
22973 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16;
22974 if (num_bits_16 == 24) {
22975 t_16 = ((uint32_t)(*scratch));
22976 break;
22977 }
22978 num_bits_16 += 8;
22979 *scratch |= ((uint64_t)(num_bits_16)) << 56;
22980 }
22981 }
22982 self->private_impl.f_channel_masks[2] = t_16;
22983 }
22984 {
22985 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37);
22986 uint32_t t_17;
22987 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
22988 t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
22989 iop_a_src += 4;
22990 } else {
22991 self->private_data.s_decode_image_config[0].scratch = 0;
22992 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38);
22993 while (true) {
22994 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
22995 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
22996 goto suspend;
22997 }
22998 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
22999 uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56));
23000 *scratch <<= 8;
23001 *scratch >>= 8;
23002 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17;
23003 if (num_bits_17 == 24) {
23004 t_17 = ((uint32_t)(*scratch));
23005 break;
23006 }
23007 num_bits_17 += 8;
23008 *scratch |= ((uint64_t)(num_bits_17)) << 56;
23009 }
23010 }
23011 self->private_impl.f_channel_masks[1] = t_17;
23012 }
23013 {
23014 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39);
23015 uint32_t t_18;
23016 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
23017 t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23018 iop_a_src += 4;
23019 } else {
23020 self->private_data.s_decode_image_config[0].scratch = 0;
23021 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40);
23022 while (true) {
23023 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
23024 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23025 goto suspend;
23026 }
23027 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
23028 uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56));
23029 *scratch <<= 8;
23030 *scratch >>= 8;
23031 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18;
23032 if (num_bits_18 == 24) {
23033 t_18 = ((uint32_t)(*scratch));
23034 break;
23035 }
23036 num_bits_18 += 8;
23037 *scratch |= ((uint64_t)(num_bits_18)) << 56;
23038 }
23039 }
23040 self->private_impl.f_channel_masks[0] = t_18;
23041 }
23042 if (self->private_impl.f_bitmap_info_len >= 56) {
23043 {
23044 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41);
23045 uint32_t t_19;
23046 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
23047 t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23048 iop_a_src += 4;
23049 } else {
23050 self->private_data.s_decode_image_config[0].scratch = 0;
23051 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42);
23052 while (true) {
23053 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
23054 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23055 goto suspend;
23056 }
23057 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
23058 uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56));
23059 *scratch <<= 8;
23060 *scratch >>= 8;
23061 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19;
23062 if (num_bits_19 == 24) {
23063 t_19 = ((uint32_t)(*scratch));
23064 break;
23065 }
23066 num_bits_19 += 8;
23067 *scratch |= ((uint64_t)(num_bits_19)) << 56;
23068 }
23069 }
23070 self->private_impl.f_channel_masks[3] = t_19;
23071 }
23072 self->private_data.s_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56));
23073 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43);
23074 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23075 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23076 iop_a_src = io2_a_src;
23077 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23078 goto suspend;
23079 }
23080 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
23081 }
23082 if ((self->private_impl.f_channel_masks[0] == 255) && (self->private_impl.f_channel_masks[1] == 65280) && (self->private_impl.f_channel_masks[2] == 16711680)) {
23083 if (self->private_impl.f_bits_per_pixel == 24) {
23084 self->private_impl.f_compression = 0;
23085 } else if (self->private_impl.f_bits_per_pixel == 32) {
23086 if ((self->private_impl.f_channel_masks[3] == 0) || (self->private_impl.f_channel_masks[3] == 4278190080)) {
23087 self->private_impl.f_compression = 0;
23088 }
23089 }
23090 }
23091 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44);
23092 status = wuffs_bmp__decoder__process_masks(self);
23093 if (status.repr) {
23094 goto suspend;
23095 }
23096 }
23097 } else if (self->private_impl.f_bitmap_info_len >= 40) {
23098 self->private_data.s_decode_image_config[0].scratch = (self->private_impl.f_bitmap_info_len - 40);
23099 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45);
23100 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23101 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23102 iop_a_src = io2_a_src;
23103 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23104 goto suspend;
23105 }
23106 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
23107 } else {
23108 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23109 goto exit;
23110 }
23111 }
23112 if (self->private_impl.f_compression != 3) {
23113 if (self->private_impl.f_bits_per_pixel < 16) {
23114 if (a_src) {
23115 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23116 }
23117 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46);
23118 status = wuffs_bmp__decoder__read_palette(self, a_src);
23119 if (a_src) {
23120 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23121 }
23122 if (status.repr) {
23123 goto suspend;
23124 }
23125 }
23126 }
23127 if (self->private_impl.f_compression == 0) {
23128 if ((self->private_impl.f_bits_per_pixel == 1) || (self->private_impl.f_bits_per_pixel == 2) || (self->private_impl.f_bits_per_pixel == 4)) {
23129 self->private_impl.f_src_pixfmt = 2198077448;
23130 self->private_impl.f_compression = 256;
23131 } else if (self->private_impl.f_bits_per_pixel == 8) {
23132 self->private_impl.f_src_pixfmt = 2198077448;
23133 } else if (self->private_impl.f_bits_per_pixel == 16) {
23134 self->private_impl.f_compression = 3;
23135 self->private_impl.f_channel_masks[0] = 31;
23136 self->private_impl.f_channel_masks[1] = 992;
23137 self->private_impl.f_channel_masks[2] = 31744;
23138 self->private_impl.f_channel_masks[3] = 0;
23139 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47);
23140 status = wuffs_bmp__decoder__process_masks(self);
23141 if (status.repr) {
23142 goto suspend;
23143 }
23144 self->private_impl.f_src_pixfmt = 2164308923;
23145 } else if (self->private_impl.f_bits_per_pixel == 24) {
23146 self->private_impl.f_src_pixfmt = 2147485832;
23147 } else if (self->private_impl.f_bits_per_pixel == 32) {
23148 if (self->private_impl.f_channel_masks[3] == 0) {
23149 self->private_impl.f_src_pixfmt = 2415954056;
23150 } else {
23151 self->private_impl.f_src_pixfmt = 2164295816;
23152 }
23153 } else {
23154 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23155 goto exit;
23156 }
23157 } else if (self->private_impl.f_compression == 1) {
23158 if (self->private_impl.f_bits_per_pixel == 8) {
23159 self->private_impl.f_src_pixfmt = 2198077448;
23160 } else {
23161 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23162 goto exit;
23163 }
23164 } else if (self->private_impl.f_compression == 2) {
23165 if (self->private_impl.f_bits_per_pixel == 4) {
23166 self->private_impl.f_src_pixfmt = 2198077448;
23167 } else {
23168 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23169 goto exit;
23170 }
23171 } else if (self->private_impl.f_compression == 3) {
23172 if ((self->private_impl.f_bits_per_pixel == 16) || (self->private_impl.f_bits_per_pixel == 32)) {
23173 self->private_impl.f_src_pixfmt = 2164308923;
23174 } else {
23175 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23176 goto exit;
23177 }
23178 } else {
23179 status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
23180 goto exit;
23181 }
23182 if (((self->private_impl.f_bitmap_info_len < 40) || (self->private_impl.f_bitmap_info_len == 64)) &&
23183 (self->private_impl.f_bits_per_pixel != 1) &&
23184 (self->private_impl.f_bits_per_pixel != 4) &&
23185 (self->private_impl.f_bits_per_pixel != 8) &&
23186 (self->private_impl.f_bits_per_pixel != 24)) {
23187 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
23188 goto exit;
23189 }
23190 if (self->private_impl.f_bits_per_pixel == 1) {
23191 v_byte_width = ((self->private_impl.f_width >> 3) + (((self->private_impl.f_width & 7) + 7) >> 3));
23192 self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
23193 } else if (self->private_impl.f_bits_per_pixel == 2) {
23194 v_byte_width = ((self->private_impl.f_width >> 2) + (((self->private_impl.f_width & 3) + 3) >> 2));
23195 self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
23196 } else if (self->private_impl.f_bits_per_pixel == 4) {
23197 v_byte_width = ((self->private_impl.f_width >> 1) + (self->private_impl.f_width & 1));
23198 self->private_impl.f_pad_per_row = ((4 - (v_byte_width & 3)) & 3);
23199 } else if (self->private_impl.f_bits_per_pixel == 8) {
23200 self->private_impl.f_pad_per_row = ((4 - (self->private_impl.f_width & 3)) & 3);
23201 } else if (self->private_impl.f_bits_per_pixel == 16) {
23202 self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1) * 2);
23203 } else if (self->private_impl.f_bits_per_pixel == 24) {
23204 self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3);
23205 } else if (self->private_impl.f_bits_per_pixel == 32) {
23206 self->private_impl.f_pad_per_row = 0;
23207 }
23208 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
23209 if (a_dst != NULL) {
23210 v_dst_pixfmt = 2164295816;
23211 if ((self->private_impl.f_channel_num_bits[0] > 8) ||
23212 (self->private_impl.f_channel_num_bits[1] > 8) ||
23213 (self->private_impl.f_channel_num_bits[2] > 8) ||
23214 (self->private_impl.f_channel_num_bits[3] > 8)) {
23215 v_dst_pixfmt = 2164308923;
23216 }
23217 wuffs_base__image_config__set(
23218 a_dst,
23219 v_dst_pixfmt,
23220 0,
23221 self->private_impl.f_width,
23222 self->private_impl.f_height,
23223 self->private_impl.f_frame_config_io_position,
23224 (self->private_impl.f_channel_masks[3] == 0));
23225 }
23226 self->private_impl.f_call_sequence = 3;
23227
23228 ok:
23229 self->private_impl.p_decode_image_config[0] = 0;
23230 goto exit;
23231 }
23232
23233 goto suspend;
23234 suspend:
23235 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23236 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
23237
23238 goto exit;
23239 exit:
23240 if (a_src) {
23241 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23242 }
23243
23244 if (wuffs_base__status__is_error(&status)) {
23245 self->private_impl.magic = WUFFS_BASE__DISABLED;
23246 }
23247 return status;
23248 }
23249
23250 // -------- func bmp.decoder.decode_frame_config
23251
23252 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__decode_frame_config(wuffs_bmp__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)23253 wuffs_bmp__decoder__decode_frame_config(
23254 wuffs_bmp__decoder* self,
23255 wuffs_base__frame_config* a_dst,
23256 wuffs_base__io_buffer* a_src) {
23257 if (!self) {
23258 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23259 }
23260 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
23261 return wuffs_base__make_status(
23262 (self->private_impl.magic == WUFFS_BASE__DISABLED)
23263 ? wuffs_base__error__disabled_by_previous_error
23264 : wuffs_base__error__initialize_not_called);
23265 }
23266 if (!a_src) {
23267 self->private_impl.magic = WUFFS_BASE__DISABLED;
23268 return wuffs_base__make_status(wuffs_base__error__bad_argument);
23269 }
23270 if ((self->private_impl.active_coroutine != 0) &&
23271 (self->private_impl.active_coroutine != 2)) {
23272 self->private_impl.magic = WUFFS_BASE__DISABLED;
23273 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
23274 }
23275 self->private_impl.active_coroutine = 0;
23276 wuffs_base__status status = wuffs_base__make_status(NULL);
23277
23278 const uint8_t* iop_a_src = NULL;
23279 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23280 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23281 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23282 if (a_src) {
23283 io0_a_src = a_src->data.ptr;
23284 io1_a_src = io0_a_src + a_src->meta.ri;
23285 iop_a_src = io1_a_src;
23286 io2_a_src = io0_a_src + a_src->meta.wi;
23287 }
23288
23289 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
23290 switch (coro_susp_point) {
23291 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23292
23293 if (self->private_impl.f_call_sequence < 3) {
23294 if (a_src) {
23295 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23296 }
23297 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
23298 status = wuffs_bmp__decoder__decode_image_config(self, NULL, a_src);
23299 if (a_src) {
23300 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23301 }
23302 if (status.repr) {
23303 goto suspend;
23304 }
23305 } else if (self->private_impl.f_call_sequence == 3) {
23306 if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
23307 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
23308 goto exit;
23309 }
23310 } else if (self->private_impl.f_call_sequence == 4) {
23311 self->private_impl.f_call_sequence = 255;
23312 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
23313 goto ok;
23314 } else {
23315 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
23316 goto ok;
23317 }
23318 if (a_dst != NULL) {
23319 wuffs_base__frame_config__set(
23320 a_dst,
23321 wuffs_base__utility__make_rect_ie_u32(
23322 0,
23323 0,
23324 self->private_impl.f_width,
23325 self->private_impl.f_height),
23326 ((wuffs_base__flicks)(0)),
23327 0,
23328 self->private_impl.f_frame_config_io_position,
23329 0,
23330 true,
23331 false,
23332 4278190080);
23333 }
23334 self->private_impl.f_call_sequence = 4;
23335
23336 ok:
23337 self->private_impl.p_decode_frame_config[0] = 0;
23338 goto exit;
23339 }
23340
23341 goto suspend;
23342 suspend:
23343 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23344 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
23345
23346 goto exit;
23347 exit:
23348 if (a_src) {
23349 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23350 }
23351
23352 if (wuffs_base__status__is_error(&status)) {
23353 self->private_impl.magic = WUFFS_BASE__DISABLED;
23354 }
23355 return status;
23356 }
23357
23358 // -------- func bmp.decoder.decode_frame
23359
23360 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__decode_frame(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)23361 wuffs_bmp__decoder__decode_frame(
23362 wuffs_bmp__decoder* self,
23363 wuffs_base__pixel_buffer* a_dst,
23364 wuffs_base__io_buffer* a_src,
23365 wuffs_base__pixel_blend a_blend,
23366 wuffs_base__slice_u8 a_workbuf,
23367 wuffs_base__decode_frame_options* a_opts) {
23368 if (!self) {
23369 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
23370 }
23371 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
23372 return wuffs_base__make_status(
23373 (self->private_impl.magic == WUFFS_BASE__DISABLED)
23374 ? wuffs_base__error__disabled_by_previous_error
23375 : wuffs_base__error__initialize_not_called);
23376 }
23377 if (!a_dst || !a_src) {
23378 self->private_impl.magic = WUFFS_BASE__DISABLED;
23379 return wuffs_base__make_status(wuffs_base__error__bad_argument);
23380 }
23381 if ((self->private_impl.active_coroutine != 0) &&
23382 (self->private_impl.active_coroutine != 3)) {
23383 self->private_impl.magic = WUFFS_BASE__DISABLED;
23384 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
23385 }
23386 self->private_impl.active_coroutine = 0;
23387 wuffs_base__status status = wuffs_base__make_status(NULL);
23388
23389 wuffs_base__status v_status = wuffs_base__make_status(NULL);
23390
23391 const uint8_t* iop_a_src = NULL;
23392 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23393 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23394 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23395 if (a_src) {
23396 io0_a_src = a_src->data.ptr;
23397 io1_a_src = io0_a_src + a_src->meta.ri;
23398 iop_a_src = io1_a_src;
23399 io2_a_src = io0_a_src + a_src->meta.wi;
23400 }
23401
23402 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
23403 if (coro_susp_point) {
23404 v_status = self->private_data.s_decode_frame[0].v_status;
23405 }
23406 switch (coro_susp_point) {
23407 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
23408
23409 if (self->private_impl.f_call_sequence < 4) {
23410 if (a_src) {
23411 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23412 }
23413 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
23414 status = wuffs_bmp__decoder__decode_frame_config(self, NULL, a_src);
23415 if (a_src) {
23416 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23417 }
23418 if (status.repr) {
23419 goto suspend;
23420 }
23421 } else if (self->private_impl.f_call_sequence == 4) {
23422 } else {
23423 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
23424 goto ok;
23425 }
23426 self->private_data.s_decode_frame[0].scratch = self->private_impl.f_padding;
23427 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
23428 if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23429 self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23430 iop_a_src = io2_a_src;
23431 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23432 goto suspend;
23433 }
23434 iop_a_src += self->private_data.s_decode_frame[0].scratch;
23435 if ((self->private_impl.f_width > 0) && (self->private_impl.f_height > 0)) {
23436 self->private_impl.f_dst_x = 0;
23437 if (self->private_impl.f_top_down) {
23438 self->private_impl.f_dst_y = 0;
23439 self->private_impl.f_dst_y_inc = 1;
23440 } else {
23441 self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1));
23442 self->private_impl.f_dst_y_inc = 4294967295;
23443 }
23444 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
23445 wuffs_base__pixel_buffer__pixel_format(a_dst),
23446 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024)),
23447 wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
23448 wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
23449 a_blend);
23450 if ( ! wuffs_base__status__is_ok(&v_status)) {
23451 status = v_status;
23452 if (wuffs_base__status__is_error(&status)) {
23453 goto exit;
23454 } else if (wuffs_base__status__is_suspension(&status)) {
23455 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
23456 goto exit;
23457 }
23458 goto ok;
23459 }
23460 while (true) {
23461 if (self->private_impl.f_compression == 0) {
23462 if (a_src) {
23463 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23464 }
23465 v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src);
23466 if (a_src) {
23467 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23468 }
23469 } else if (self->private_impl.f_compression < 3) {
23470 if (a_src) {
23471 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23472 }
23473 v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src);
23474 if (a_src) {
23475 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23476 }
23477 } else if (self->private_impl.f_compression == 3) {
23478 if (a_src) {
23479 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23480 }
23481 v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src);
23482 if (a_src) {
23483 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23484 }
23485 } else {
23486 if (a_src) {
23487 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23488 }
23489 v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src);
23490 if (a_src) {
23491 iop_a_src = a_src->data.ptr + a_src->meta.ri;
23492 }
23493 }
23494 if (wuffs_base__status__is_ok(&v_status)) {
23495 goto label__0__break;
23496 } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) {
23497 status = v_status;
23498 if (wuffs_base__status__is_error(&status)) {
23499 goto exit;
23500 } else if (wuffs_base__status__is_suspension(&status)) {
23501 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
23502 goto exit;
23503 }
23504 goto ok;
23505 }
23506 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23507 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
23508 }
23509 label__0__break:;
23510 self->private_data.s_decode_frame[0].scratch = self->private_impl.f_pending_pad;
23511 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
23512 if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
23513 self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
23514 iop_a_src = io2_a_src;
23515 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
23516 goto suspend;
23517 }
23518 iop_a_src += self->private_data.s_decode_frame[0].scratch;
23519 self->private_impl.f_pending_pad = 0;
23520 }
23521 self->private_impl.f_call_sequence = 255;
23522
23523 ok:
23524 self->private_impl.p_decode_frame[0] = 0;
23525 goto exit;
23526 }
23527
23528 goto suspend;
23529 suspend:
23530 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
23531 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
23532 self->private_data.s_decode_frame[0].v_status = v_status;
23533
23534 goto exit;
23535 exit:
23536 if (a_src) {
23537 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23538 }
23539
23540 if (wuffs_base__status__is_error(&status)) {
23541 self->private_impl.magic = WUFFS_BASE__DISABLED;
23542 }
23543 return status;
23544 }
23545
23546 // -------- func bmp.decoder.swizzle_none
23547
23548 static wuffs_base__status
wuffs_bmp__decoder__swizzle_none(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)23549 wuffs_bmp__decoder__swizzle_none(
23550 wuffs_bmp__decoder* self,
23551 wuffs_base__pixel_buffer* a_dst,
23552 wuffs_base__io_buffer* a_src) {
23553 wuffs_base__status status = wuffs_base__make_status(NULL);
23554
23555 wuffs_base__pixel_format v_dst_pixfmt = {0};
23556 uint32_t v_dst_bits_per_pixel = 0;
23557 uint64_t v_dst_bytes_per_pixel = 0;
23558 uint64_t v_dst_bytes_per_row = 0;
23559 wuffs_base__slice_u8 v_dst_palette = {0};
23560 wuffs_base__table_u8 v_tab = {0};
23561 wuffs_base__slice_u8 v_dst = {0};
23562 uint64_t v_i = 0;
23563 uint64_t v_n = 0;
23564
23565 const uint8_t* iop_a_src = NULL;
23566 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23567 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23568 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23569 if (a_src) {
23570 io0_a_src = a_src->data.ptr;
23571 io1_a_src = io0_a_src + a_src->meta.ri;
23572 iop_a_src = io1_a_src;
23573 io2_a_src = io0_a_src + a_src->meta.wi;
23574 }
23575
23576 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23577 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23578 if ((v_dst_bits_per_pixel & 7) != 0) {
23579 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23580 goto exit;
23581 }
23582 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23583 v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23584 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23585 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23586 label__outer__continue:;
23587 while (true) {
23588 while (self->private_impl.f_pending_pad > 0) {
23589 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23590 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23591 goto ok;
23592 }
23593 self->private_impl.f_pending_pad -= 1;
23594 iop_a_src += 1;
23595 }
23596 label__inner__continue:;
23597 while (true) {
23598 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
23599 self->private_impl.f_dst_x = 0;
23600 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23601 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23602 if (self->private_impl.f_height > 0) {
23603 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23604 }
23605 goto label__outer__break;
23606 } else if (self->private_impl.f_pad_per_row != 0) {
23607 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23608 goto label__outer__continue;
23609 }
23610 }
23611 v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23612 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
23613 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
23614 }
23615 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23616 if (v_i >= ((uint64_t)(v_dst.len))) {
23617 goto label__inner__continue;
23618 }
23619 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
23620 &self->private_impl.f_swizzler,
23621 wuffs_base__slice_u8__subslice_i(v_dst, v_i),
23622 v_dst_palette,
23623 &iop_a_src,
23624 io2_a_src);
23625 if (v_n == 0) {
23626 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23627 goto ok;
23628 }
23629 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23630 }
23631 }
23632 label__outer__break:;
23633 status = wuffs_base__make_status(NULL);
23634 goto ok;
23635
23636 ok:
23637 goto exit;
23638 exit:
23639 if (a_src) {
23640 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23641 }
23642
23643 return status;
23644 }
23645
23646 // -------- func bmp.decoder.swizzle_rle
23647
23648 static wuffs_base__status
wuffs_bmp__decoder__swizzle_rle(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)23649 wuffs_bmp__decoder__swizzle_rle(
23650 wuffs_bmp__decoder* self,
23651 wuffs_base__pixel_buffer* a_dst,
23652 wuffs_base__io_buffer* a_src) {
23653 wuffs_base__status status = wuffs_base__make_status(NULL);
23654
23655 wuffs_base__pixel_format v_dst_pixfmt = {0};
23656 uint32_t v_dst_bits_per_pixel = 0;
23657 uint64_t v_dst_bytes_per_pixel = 0;
23658 uint64_t v_dst_bytes_per_row = 0;
23659 wuffs_base__slice_u8 v_dst_palette = {0};
23660 wuffs_base__table_u8 v_tab = {0};
23661 wuffs_base__slice_u8 v_row = {0};
23662 wuffs_base__slice_u8 v_dst = {0};
23663 uint64_t v_i = 0;
23664 uint64_t v_n = 0;
23665 uint32_t v_p0 = 0;
23666 uint8_t v_code = 0;
23667 uint8_t v_indexes[2] = {0};
23668 uint32_t v_rle_state = 0;
23669 uint32_t v_chunk_bits = 0;
23670 uint32_t v_chunk_count = 0;
23671
23672 const uint8_t* iop_a_src = NULL;
23673 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23674 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23675 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23676 if (a_src) {
23677 io0_a_src = a_src->data.ptr;
23678 io1_a_src = io0_a_src + a_src->meta.ri;
23679 iop_a_src = io1_a_src;
23680 io2_a_src = io0_a_src + a_src->meta.wi;
23681 }
23682
23683 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23684 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23685 if ((v_dst_bits_per_pixel & 7) != 0) {
23686 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23687 goto exit;
23688 }
23689 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23690 v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23691 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23692 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23693 v_rle_state = self->private_impl.f_rle_state;
23694 label__outer__continue:;
23695 while (true) {
23696 v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23697 if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23698 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23699 }
23700 label__middle__continue:;
23701 while (true) {
23702 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
23703 if (v_i <= ((uint64_t)(v_row.len))) {
23704 v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i);
23705 } else {
23706 v_dst = wuffs_base__utility__empty_slice_u8();
23707 }
23708 while (true) {
23709 label__inner__continue:;
23710 while (true) {
23711 if (v_rle_state == 0) {
23712 if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23713 goto label__goto_suspend__break;
23714 }
23715 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23716 iop_a_src += 1;
23717 if (v_code == 0) {
23718 v_rle_state = 2;
23719 goto label__inner__continue;
23720 }
23721 self->private_impl.f_rle_length = ((uint32_t)(v_code));
23722 v_rle_state = 1;
23723 goto label__inner__continue;
23724 } else if (v_rle_state == 1) {
23725 if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23726 goto label__goto_suspend__break;
23727 }
23728 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23729 iop_a_src += 1;
23730 if (self->private_impl.f_bits_per_pixel == 8) {
23731 v_p0 = 0;
23732 while (v_p0 < self->private_impl.f_rle_length) {
23733 self->private_data.f_scratch[v_p0] = v_code;
23734 v_p0 += 1;
23735 }
23736 } else {
23737 v_indexes[0] = ((uint8_t)((v_code >> 4)));
23738 v_indexes[1] = (v_code & 15);
23739 v_p0 = 0;
23740 while (v_p0 < self->private_impl.f_rle_length) {
23741 self->private_data.f_scratch[(v_p0 + 0)] = v_indexes[0];
23742 self->private_data.f_scratch[(v_p0 + 1)] = v_indexes[1];
23743 v_p0 += 2;
23744 }
23745 }
23746 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), self->private_impl.f_rle_length));
23747 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length);
23748 v_rle_state = 0;
23749 goto label__middle__continue;
23750 } else if (v_rle_state == 2) {
23751 if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23752 goto label__goto_suspend__break;
23753 }
23754 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23755 iop_a_src += 1;
23756 if (v_code < 2) {
23757 if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0)) {
23758 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23759 goto exit;
23760 }
23761 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u);
23762 self->private_impl.f_dst_x = 0;
23763 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23764 if (v_code > 0) {
23765 goto label__outer__break;
23766 }
23767 v_rle_state = 0;
23768 goto label__outer__continue;
23769 } else if (v_code == 2) {
23770 v_rle_state = 4;
23771 goto label__inner__continue;
23772 }
23773 self->private_impl.f_rle_length = ((uint32_t)(v_code));
23774 self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8) && ((v_code & 1) != 0));
23775 v_rle_state = 3;
23776 goto label__inner__continue;
23777 } else if (v_rle_state == 3) {
23778 if (self->private_impl.f_bits_per_pixel == 8) {
23779 v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
23780 &self->private_impl.f_swizzler,
23781 self->private_impl.f_rle_length,
23782 v_dst,
23783 v_dst_palette,
23784 &iop_a_src,
23785 io2_a_src);
23786 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
23787 wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)((v_n & 4294967295))));
23788 } else {
23789 v_chunk_count = ((self->private_impl.f_rle_length + 3) / 4);
23790 v_p0 = 0;
23791 while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2)) {
23792 v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
23793 iop_a_src += 2;
23794 self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((15 & (v_chunk_bits >> 12))));
23795 self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((15 & (v_chunk_bits >> 8))));
23796 self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((15 & (v_chunk_bits >> 4))));
23797 self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((15 & (v_chunk_bits >> 0))));
23798 v_p0 = ((v_p0 & 255) + 4);
23799 v_chunk_count -= 1;
23800 }
23801 v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length);
23802 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), v_p0));
23803 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0);
23804 wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0);
23805 }
23806 if (self->private_impl.f_rle_length > 0) {
23807 goto label__goto_suspend__break;
23808 }
23809 if (self->private_impl.f_rle_padded) {
23810 if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23811 goto label__goto_suspend__break;
23812 }
23813 iop_a_src += 1;
23814 self->private_impl.f_rle_padded = false;
23815 }
23816 v_rle_state = 0;
23817 goto label__middle__continue;
23818 } else if (v_rle_state == 4) {
23819 if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23820 goto label__goto_suspend__break;
23821 }
23822 self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23823 iop_a_src += 1;
23824 v_rle_state = 5;
23825 goto label__inner__continue;
23826 }
23827 if (((uint64_t)(io2_a_src - iop_a_src)) < 1) {
23828 goto label__goto_suspend__break;
23829 }
23830 v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
23831 iop_a_src += 1;
23832 if (self->private_impl.f_rle_delta_x > 0) {
23833 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, ((uint64_t)(self->private_impl.f_rle_delta_x)));
23834 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x)));
23835 self->private_impl.f_rle_delta_x = 0;
23836 if (self->private_impl.f_dst_x > self->private_impl.f_width) {
23837 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23838 goto exit;
23839 }
23840 }
23841 if (v_code > 0) {
23842 #if defined(__GNUC__)
23843 #pragma GCC diagnostic push
23844 #pragma GCC diagnostic ignored "-Wconversion"
23845 #endif
23846 v_code -= 1;
23847 #if defined(__GNUC__)
23848 #pragma GCC diagnostic pop
23849 #endif
23850 while (true) {
23851 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23852 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23853 status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
23854 goto exit;
23855 }
23856 v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23857 if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23858 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23859 }
23860 if (v_code <= 0) {
23861 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, ((uint64_t)(self->private_impl.f_dst_x)));
23862 goto label__0__break;
23863 }
23864 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
23865 #if defined(__GNUC__)
23866 #pragma GCC diagnostic push
23867 #pragma GCC diagnostic ignored "-Wconversion"
23868 #endif
23869 v_code -= 1;
23870 #if defined(__GNUC__)
23871 #pragma GCC diagnostic pop
23872 #endif
23873 }
23874 label__0__break:;
23875 }
23876 v_rle_state = 0;
23877 goto label__middle__continue;
23878 }
23879 }
23880 label__goto_suspend__break:;
23881 self->private_impl.f_rle_state = v_rle_state;
23882 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23883 goto ok;
23884 }
23885 }
23886 label__outer__break:;
23887 while (self->private_impl.f_dst_y < self->private_impl.f_height) {
23888 v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
23889 if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
23890 v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
23891 }
23892 wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
23893 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23894 }
23895 status = wuffs_base__make_status(NULL);
23896 goto ok;
23897
23898 ok:
23899 goto exit;
23900 exit:
23901 if (a_src) {
23902 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
23903 }
23904
23905 return status;
23906 }
23907
23908 // -------- func bmp.decoder.swizzle_bitfields
23909
23910 static wuffs_base__status
wuffs_bmp__decoder__swizzle_bitfields(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)23911 wuffs_bmp__decoder__swizzle_bitfields(
23912 wuffs_bmp__decoder* self,
23913 wuffs_base__pixel_buffer* a_dst,
23914 wuffs_base__io_buffer* a_src) {
23915 wuffs_base__status status = wuffs_base__make_status(NULL);
23916
23917 wuffs_base__pixel_format v_dst_pixfmt = {0};
23918 uint32_t v_dst_bits_per_pixel = 0;
23919 uint64_t v_dst_bytes_per_pixel = 0;
23920 uint64_t v_dst_bytes_per_row = 0;
23921 wuffs_base__slice_u8 v_dst_palette = {0};
23922 wuffs_base__table_u8 v_tab = {0};
23923 wuffs_base__slice_u8 v_dst = {0};
23924 uint64_t v_i = 0;
23925 uint64_t v_n = 0;
23926 uint32_t v_p0 = 0;
23927 uint32_t v_p1 = 0;
23928 uint32_t v_p1_temp = 0;
23929 uint32_t v_num_bits = 0;
23930 uint32_t v_c = 0;
23931 uint32_t v_c32 = 0;
23932 uint32_t v_channel = 0;
23933
23934 const uint8_t* iop_a_src = NULL;
23935 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23936 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23937 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
23938 if (a_src) {
23939 io0_a_src = a_src->data.ptr;
23940 io1_a_src = io0_a_src + a_src->meta.ri;
23941 iop_a_src = io1_a_src;
23942 io2_a_src = io0_a_src + a_src->meta.wi;
23943 }
23944
23945 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
23946 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
23947 if ((v_dst_bits_per_pixel & 7) != 0) {
23948 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
23949 goto exit;
23950 }
23951 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
23952 v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
23953 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
23954 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
23955 label__outer__continue:;
23956 while (true) {
23957 while (self->private_impl.f_pending_pad > 0) {
23958 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
23959 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
23960 goto ok;
23961 }
23962 self->private_impl.f_pending_pad -= 1;
23963 iop_a_src += 1;
23964 }
23965 label__inner__continue:;
23966 while (true) {
23967 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
23968 self->private_impl.f_dst_x = 0;
23969 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
23970 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
23971 if (self->private_impl.f_height > 0) {
23972 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23973 }
23974 goto label__outer__break;
23975 } else if (self->private_impl.f_pad_per_row != 0) {
23976 self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
23977 goto label__outer__continue;
23978 }
23979 }
23980 v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x));
23981 v_p1 = wuffs_base__u32__min(v_p1_temp, 256);
23982 v_p0 = 0;
23983 while (v_p0 < v_p1) {
23984 if (self->private_impl.f_bits_per_pixel == 16) {
23985 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
23986 goto label__0__break;
23987 }
23988 v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
23989 iop_a_src += 2;
23990 } else {
23991 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
23992 goto label__0__break;
23993 }
23994 v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
23995 iop_a_src += 4;
23996 }
23997 v_channel = 0;
23998 while (v_channel < 4) {
23999 if (self->private_impl.f_channel_num_bits[v_channel] == 0) {
24000 self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 0)] = 255;
24001 self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 1)] = 255;
24002 } else {
24003 v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]);
24004 v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel]));
24005 while (v_num_bits < 16) {
24006 v_c |= ((uint32_t)(v_c << v_num_bits));
24007 v_num_bits *= 2;
24008 }
24009 v_c >>= (v_num_bits - 16);
24010 self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 0)] = ((uint8_t)((255 & (v_c >> 0))));
24011 self->private_data.f_scratch[((8 * v_p0) + (2 * v_channel) + 1)] = ((uint8_t)((255 & (v_c >> 8))));
24012 }
24013 v_channel += 1;
24014 }
24015 v_p0 += 1;
24016 }
24017 label__0__break:;
24018 v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
24019 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
24020 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
24021 }
24022 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
24023 if (v_i >= ((uint64_t)(v_dst.len))) {
24024 goto label__inner__continue;
24025 }
24026 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), (8 * v_p0)));
24027 if (v_n == 0) {
24028 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
24029 goto ok;
24030 }
24031 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
24032 }
24033 }
24034 label__outer__break:;
24035 status = wuffs_base__make_status(NULL);
24036 goto ok;
24037
24038 ok:
24039 goto exit;
24040 exit:
24041 if (a_src) {
24042 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24043 }
24044
24045 return status;
24046 }
24047
24048 // -------- func bmp.decoder.swizzle_low_bit_depth
24049
24050 static wuffs_base__status
wuffs_bmp__decoder__swizzle_low_bit_depth(wuffs_bmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)24051 wuffs_bmp__decoder__swizzle_low_bit_depth(
24052 wuffs_bmp__decoder* self,
24053 wuffs_base__pixel_buffer* a_dst,
24054 wuffs_base__io_buffer* a_src) {
24055 wuffs_base__status status = wuffs_base__make_status(NULL);
24056
24057 wuffs_base__pixel_format v_dst_pixfmt = {0};
24058 uint32_t v_dst_bits_per_pixel = 0;
24059 uint64_t v_dst_bytes_per_pixel = 0;
24060 uint64_t v_dst_bytes_per_row = 0;
24061 wuffs_base__slice_u8 v_dst_palette = {0};
24062 wuffs_base__table_u8 v_tab = {0};
24063 wuffs_base__slice_u8 v_dst = {0};
24064 uint64_t v_i = 0;
24065 uint64_t v_n = 0;
24066 uint32_t v_p0 = 0;
24067 uint32_t v_chunk_bits = 0;
24068 uint32_t v_chunk_count = 0;
24069
24070 const uint8_t* iop_a_src = NULL;
24071 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24072 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24073 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24074 if (a_src) {
24075 io0_a_src = a_src->data.ptr;
24076 io1_a_src = io0_a_src + a_src->meta.ri;
24077 iop_a_src = io1_a_src;
24078 io2_a_src = io0_a_src + a_src->meta.wi;
24079 }
24080
24081 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
24082 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
24083 if ((v_dst_bits_per_pixel & 7) != 0) {
24084 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
24085 goto exit;
24086 }
24087 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
24088 v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
24089 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8((self->private_data.f_scratch) + 1024, 1024));
24090 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
24091 label__loop__continue:;
24092 while (true) {
24093 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
24094 self->private_impl.f_dst_x = 0;
24095 self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
24096 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
24097 goto label__loop__break;
24098 }
24099 }
24100 v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
24101 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
24102 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
24103 }
24104 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
24105 if (v_i >= ((uint64_t)(v_dst.len))) {
24106 goto label__loop__continue;
24107 }
24108 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
24109 v_p0 = 0;
24110 if (self->private_impl.f_bits_per_pixel == 1) {
24111 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31) / 32);
24112 v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16);
24113 while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
24114 v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
24115 iop_a_src += 4;
24116 self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((1 & (v_chunk_bits >> 31))));
24117 self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((1 & (v_chunk_bits >> 30))));
24118 self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((1 & (v_chunk_bits >> 29))));
24119 self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((1 & (v_chunk_bits >> 28))));
24120 self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((1 & (v_chunk_bits >> 27))));
24121 self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((1 & (v_chunk_bits >> 26))));
24122 self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((1 & (v_chunk_bits >> 25))));
24123 self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((1 & (v_chunk_bits >> 24))));
24124 self->private_data.f_scratch[(v_p0 + 8)] = ((uint8_t)((1 & (v_chunk_bits >> 23))));
24125 self->private_data.f_scratch[(v_p0 + 9)] = ((uint8_t)((1 & (v_chunk_bits >> 22))));
24126 self->private_data.f_scratch[(v_p0 + 10)] = ((uint8_t)((1 & (v_chunk_bits >> 21))));
24127 self->private_data.f_scratch[(v_p0 + 11)] = ((uint8_t)((1 & (v_chunk_bits >> 20))));
24128 self->private_data.f_scratch[(v_p0 + 12)] = ((uint8_t)((1 & (v_chunk_bits >> 19))));
24129 self->private_data.f_scratch[(v_p0 + 13)] = ((uint8_t)((1 & (v_chunk_bits >> 18))));
24130 self->private_data.f_scratch[(v_p0 + 14)] = ((uint8_t)((1 & (v_chunk_bits >> 17))));
24131 self->private_data.f_scratch[(v_p0 + 15)] = ((uint8_t)((1 & (v_chunk_bits >> 16))));
24132 self->private_data.f_scratch[(v_p0 + 16)] = ((uint8_t)((1 & (v_chunk_bits >> 15))));
24133 self->private_data.f_scratch[(v_p0 + 17)] = ((uint8_t)((1 & (v_chunk_bits >> 14))));
24134 self->private_data.f_scratch[(v_p0 + 18)] = ((uint8_t)((1 & (v_chunk_bits >> 13))));
24135 self->private_data.f_scratch[(v_p0 + 19)] = ((uint8_t)((1 & (v_chunk_bits >> 12))));
24136 self->private_data.f_scratch[(v_p0 + 20)] = ((uint8_t)((1 & (v_chunk_bits >> 11))));
24137 self->private_data.f_scratch[(v_p0 + 21)] = ((uint8_t)((1 & (v_chunk_bits >> 10))));
24138 self->private_data.f_scratch[(v_p0 + 22)] = ((uint8_t)((1 & (v_chunk_bits >> 9))));
24139 self->private_data.f_scratch[(v_p0 + 23)] = ((uint8_t)((1 & (v_chunk_bits >> 8))));
24140 self->private_data.f_scratch[(v_p0 + 24)] = ((uint8_t)((1 & (v_chunk_bits >> 7))));
24141 self->private_data.f_scratch[(v_p0 + 25)] = ((uint8_t)((1 & (v_chunk_bits >> 6))));
24142 self->private_data.f_scratch[(v_p0 + 26)] = ((uint8_t)((1 & (v_chunk_bits >> 5))));
24143 self->private_data.f_scratch[(v_p0 + 27)] = ((uint8_t)((1 & (v_chunk_bits >> 4))));
24144 self->private_data.f_scratch[(v_p0 + 28)] = ((uint8_t)((1 & (v_chunk_bits >> 3))));
24145 self->private_data.f_scratch[(v_p0 + 29)] = ((uint8_t)((1 & (v_chunk_bits >> 2))));
24146 self->private_data.f_scratch[(v_p0 + 30)] = ((uint8_t)((1 & (v_chunk_bits >> 1))));
24147 self->private_data.f_scratch[(v_p0 + 31)] = ((uint8_t)((1 & (v_chunk_bits >> 0))));
24148 v_p0 = ((v_p0 & 511) + 32);
24149 v_chunk_count -= 1;
24150 }
24151 } else if (self->private_impl.f_bits_per_pixel == 2) {
24152 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15) / 16);
24153 v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32);
24154 while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
24155 v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
24156 iop_a_src += 4;
24157 self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((3 & (v_chunk_bits >> 30))));
24158 self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((3 & (v_chunk_bits >> 28))));
24159 self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((3 & (v_chunk_bits >> 26))));
24160 self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((3 & (v_chunk_bits >> 24))));
24161 self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((3 & (v_chunk_bits >> 22))));
24162 self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((3 & (v_chunk_bits >> 20))));
24163 self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((3 & (v_chunk_bits >> 18))));
24164 self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((3 & (v_chunk_bits >> 16))));
24165 self->private_data.f_scratch[(v_p0 + 8)] = ((uint8_t)((3 & (v_chunk_bits >> 14))));
24166 self->private_data.f_scratch[(v_p0 + 9)] = ((uint8_t)((3 & (v_chunk_bits >> 12))));
24167 self->private_data.f_scratch[(v_p0 + 10)] = ((uint8_t)((3 & (v_chunk_bits >> 10))));
24168 self->private_data.f_scratch[(v_p0 + 11)] = ((uint8_t)((3 & (v_chunk_bits >> 8))));
24169 self->private_data.f_scratch[(v_p0 + 12)] = ((uint8_t)((3 & (v_chunk_bits >> 6))));
24170 self->private_data.f_scratch[(v_p0 + 13)] = ((uint8_t)((3 & (v_chunk_bits >> 4))));
24171 self->private_data.f_scratch[(v_p0 + 14)] = ((uint8_t)((3 & (v_chunk_bits >> 2))));
24172 self->private_data.f_scratch[(v_p0 + 15)] = ((uint8_t)((3 & (v_chunk_bits >> 0))));
24173 v_p0 = ((v_p0 & 511) + 16);
24174 v_chunk_count -= 1;
24175 }
24176 } else if (self->private_impl.f_bits_per_pixel == 4) {
24177 v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7) / 8);
24178 v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64);
24179 while ((v_chunk_count > 0) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
24180 v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
24181 iop_a_src += 4;
24182 self->private_data.f_scratch[(v_p0 + 0)] = ((uint8_t)((15 & (v_chunk_bits >> 28))));
24183 self->private_data.f_scratch[(v_p0 + 1)] = ((uint8_t)((15 & (v_chunk_bits >> 24))));
24184 self->private_data.f_scratch[(v_p0 + 2)] = ((uint8_t)((15 & (v_chunk_bits >> 20))));
24185 self->private_data.f_scratch[(v_p0 + 3)] = ((uint8_t)((15 & (v_chunk_bits >> 16))));
24186 self->private_data.f_scratch[(v_p0 + 4)] = ((uint8_t)((15 & (v_chunk_bits >> 12))));
24187 self->private_data.f_scratch[(v_p0 + 5)] = ((uint8_t)((15 & (v_chunk_bits >> 8))));
24188 self->private_data.f_scratch[(v_p0 + 6)] = ((uint8_t)((15 & (v_chunk_bits >> 4))));
24189 self->private_data.f_scratch[(v_p0 + 7)] = ((uint8_t)((15 & (v_chunk_bits >> 0))));
24190 v_p0 = ((v_p0 & 511) + 8);
24191 v_chunk_count -= 1;
24192 }
24193 }
24194 v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x));
24195 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 2048), v_p0));
24196 if (v_n == 0) {
24197 status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
24198 goto ok;
24199 }
24200 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
24201 }
24202 label__loop__break:;
24203 status = wuffs_base__make_status(NULL);
24204 goto ok;
24205
24206 ok:
24207 goto exit;
24208 exit:
24209 if (a_src) {
24210 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24211 }
24212
24213 return status;
24214 }
24215
24216 // -------- func bmp.decoder.frame_dirty_rect
24217
24218 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_bmp__decoder__frame_dirty_rect(const wuffs_bmp__decoder * self)24219 wuffs_bmp__decoder__frame_dirty_rect(
24220 const wuffs_bmp__decoder* self) {
24221 if (!self) {
24222 return wuffs_base__utility__empty_rect_ie_u32();
24223 }
24224 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24225 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24226 return wuffs_base__utility__empty_rect_ie_u32();
24227 }
24228
24229 return wuffs_base__utility__make_rect_ie_u32(
24230 0,
24231 0,
24232 self->private_impl.f_width,
24233 self->private_impl.f_height);
24234 }
24235
24236 // -------- func bmp.decoder.num_animation_loops
24237
24238 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_bmp__decoder__num_animation_loops(const wuffs_bmp__decoder * self)24239 wuffs_bmp__decoder__num_animation_loops(
24240 const wuffs_bmp__decoder* self) {
24241 if (!self) {
24242 return 0;
24243 }
24244 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24245 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24246 return 0;
24247 }
24248
24249 return 0;
24250 }
24251
24252 // -------- func bmp.decoder.num_decoded_frame_configs
24253
24254 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frame_configs(const wuffs_bmp__decoder * self)24255 wuffs_bmp__decoder__num_decoded_frame_configs(
24256 const wuffs_bmp__decoder* self) {
24257 if (!self) {
24258 return 0;
24259 }
24260 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24261 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24262 return 0;
24263 }
24264
24265 if (self->private_impl.f_call_sequence > 3) {
24266 return 1;
24267 }
24268 return 0;
24269 }
24270
24271 // -------- func bmp.decoder.num_decoded_frames
24272
24273 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_bmp__decoder__num_decoded_frames(const wuffs_bmp__decoder * self)24274 wuffs_bmp__decoder__num_decoded_frames(
24275 const wuffs_bmp__decoder* self) {
24276 if (!self) {
24277 return 0;
24278 }
24279 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24280 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24281 return 0;
24282 }
24283
24284 if (self->private_impl.f_call_sequence > 4) {
24285 return 1;
24286 }
24287 return 0;
24288 }
24289
24290 // -------- func bmp.decoder.restart_frame
24291
24292 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__restart_frame(wuffs_bmp__decoder * self,uint64_t a_index,uint64_t a_io_position)24293 wuffs_bmp__decoder__restart_frame(
24294 wuffs_bmp__decoder* self,
24295 uint64_t a_index,
24296 uint64_t a_io_position) {
24297 if (!self) {
24298 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24299 }
24300 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24301 return wuffs_base__make_status(
24302 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24303 ? wuffs_base__error__disabled_by_previous_error
24304 : wuffs_base__error__initialize_not_called);
24305 }
24306
24307 if (self->private_impl.f_call_sequence < 3) {
24308 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
24309 }
24310 if (a_index != 0) {
24311 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24312 }
24313 self->private_impl.f_call_sequence = 3;
24314 self->private_impl.f_frame_config_io_position = a_io_position;
24315 return wuffs_base__make_status(NULL);
24316 }
24317
24318 // -------- func bmp.decoder.set_report_metadata
24319
24320 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_bmp__decoder__set_report_metadata(wuffs_bmp__decoder * self,uint32_t a_fourcc,bool a_report)24321 wuffs_bmp__decoder__set_report_metadata(
24322 wuffs_bmp__decoder* self,
24323 uint32_t a_fourcc,
24324 bool a_report) {
24325 return wuffs_base__make_empty_struct();
24326 }
24327
24328 // -------- func bmp.decoder.tell_me_more
24329
24330 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_bmp__decoder__tell_me_more(wuffs_bmp__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)24331 wuffs_bmp__decoder__tell_me_more(
24332 wuffs_bmp__decoder* self,
24333 wuffs_base__io_buffer* a_dst,
24334 wuffs_base__more_information* a_minfo,
24335 wuffs_base__io_buffer* a_src) {
24336 if (!self) {
24337 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24338 }
24339 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24340 return wuffs_base__make_status(
24341 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24342 ? wuffs_base__error__disabled_by_previous_error
24343 : wuffs_base__error__initialize_not_called);
24344 }
24345 if (!a_dst || !a_src) {
24346 self->private_impl.magic = WUFFS_BASE__DISABLED;
24347 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24348 }
24349 if ((self->private_impl.active_coroutine != 0) &&
24350 (self->private_impl.active_coroutine != 4)) {
24351 self->private_impl.magic = WUFFS_BASE__DISABLED;
24352 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24353 }
24354 self->private_impl.active_coroutine = 0;
24355 wuffs_base__status status = wuffs_base__make_status(NULL);
24356
24357 if (self->private_impl.f_io_redirect_fourcc <= 1) {
24358 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
24359 goto exit;
24360 }
24361 if (a_minfo != NULL) {
24362 wuffs_base__more_information__set(a_minfo,
24363 1,
24364 self->private_impl.f_io_redirect_fourcc,
24365 0,
24366 self->private_impl.f_io_redirect_pos,
24367 18446744073709551615u);
24368 }
24369 self->private_impl.f_io_redirect_fourcc = 1;
24370
24371 goto ok;
24372 ok:
24373 goto exit;
24374 exit:
24375 if (wuffs_base__status__is_error(&status)) {
24376 self->private_impl.magic = WUFFS_BASE__DISABLED;
24377 }
24378 return status;
24379 }
24380
24381 // -------- func bmp.decoder.workbuf_len
24382
24383 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_bmp__decoder__workbuf_len(const wuffs_bmp__decoder * self)24384 wuffs_bmp__decoder__workbuf_len(
24385 const wuffs_bmp__decoder* self) {
24386 if (!self) {
24387 return wuffs_base__utility__empty_range_ii_u64();
24388 }
24389 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24390 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24391 return wuffs_base__utility__empty_range_ii_u64();
24392 }
24393
24394 return wuffs_base__utility__make_range_ii_u64(0, 0);
24395 }
24396
24397 // -------- func bmp.decoder.read_palette
24398
24399 static wuffs_base__status
wuffs_bmp__decoder__read_palette(wuffs_bmp__decoder * self,wuffs_base__io_buffer * a_src)24400 wuffs_bmp__decoder__read_palette(
24401 wuffs_bmp__decoder* self,
24402 wuffs_base__io_buffer* a_src) {
24403 wuffs_base__status status = wuffs_base__make_status(NULL);
24404
24405 uint32_t v_i = 0;
24406 uint32_t v_argb = 0;
24407
24408 const uint8_t* iop_a_src = NULL;
24409 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24410 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24411 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24412 if (a_src) {
24413 io0_a_src = a_src->data.ptr;
24414 io1_a_src = io0_a_src + a_src->meta.ri;
24415 iop_a_src = io1_a_src;
24416 io2_a_src = io0_a_src + a_src->meta.wi;
24417 }
24418
24419 uint32_t coro_susp_point = self->private_impl.p_read_palette[0];
24420 if (coro_susp_point) {
24421 v_i = self->private_data.s_read_palette[0].v_i;
24422 }
24423 switch (coro_susp_point) {
24424 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24425
24426 if (self->private_impl.f_bitmap_info_len == 12) {
24427 while ((v_i < 256) && (self->private_impl.f_padding >= 3)) {
24428 self->private_impl.f_padding -= 3;
24429 {
24430 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
24431 uint32_t t_0;
24432 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
24433 t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
24434 iop_a_src += 3;
24435 } else {
24436 self->private_data.s_read_palette[0].scratch = 0;
24437 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
24438 while (true) {
24439 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24440 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24441 goto suspend;
24442 }
24443 uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
24444 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
24445 *scratch <<= 8;
24446 *scratch >>= 8;
24447 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
24448 if (num_bits_0 == 16) {
24449 t_0 = ((uint32_t)(*scratch));
24450 break;
24451 }
24452 num_bits_0 += 8;
24453 *scratch |= ((uint64_t)(num_bits_0)) << 56;
24454 }
24455 }
24456 v_argb = t_0;
24457 }
24458 v_argb |= 4278190080;
24459 self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
24460 self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
24461 self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
24462 self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
24463 v_i += 1;
24464 }
24465 } else {
24466 while ((v_i < 256) && (self->private_impl.f_padding >= 4)) {
24467 self->private_impl.f_padding -= 4;
24468 {
24469 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
24470 uint32_t t_1;
24471 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
24472 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
24473 iop_a_src += 4;
24474 } else {
24475 self->private_data.s_read_palette[0].scratch = 0;
24476 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
24477 while (true) {
24478 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
24479 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24480 goto suspend;
24481 }
24482 uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
24483 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
24484 *scratch <<= 8;
24485 *scratch >>= 8;
24486 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
24487 if (num_bits_1 == 24) {
24488 t_1 = ((uint32_t)(*scratch));
24489 break;
24490 }
24491 num_bits_1 += 8;
24492 *scratch |= ((uint64_t)(num_bits_1)) << 56;
24493 }
24494 }
24495 v_argb = t_1;
24496 }
24497 v_argb |= 4278190080;
24498 self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
24499 self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
24500 self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
24501 self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
24502 v_i += 1;
24503 }
24504 }
24505 while (v_i < 256) {
24506 self->private_data.f_src_palette[((4 * v_i) + 0)] = 0;
24507 self->private_data.f_src_palette[((4 * v_i) + 1)] = 0;
24508 self->private_data.f_src_palette[((4 * v_i) + 2)] = 0;
24509 self->private_data.f_src_palette[((4 * v_i) + 3)] = 255;
24510 v_i += 1;
24511 }
24512
24513 goto ok;
24514 ok:
24515 self->private_impl.p_read_palette[0] = 0;
24516 goto exit;
24517 }
24518
24519 goto suspend;
24520 suspend:
24521 self->private_impl.p_read_palette[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
24522 self->private_data.s_read_palette[0].v_i = v_i;
24523
24524 goto exit;
24525 exit:
24526 if (a_src) {
24527 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
24528 }
24529
24530 return status;
24531 }
24532
24533 // -------- func bmp.decoder.process_masks
24534
24535 static wuffs_base__status
wuffs_bmp__decoder__process_masks(wuffs_bmp__decoder * self)24536 wuffs_bmp__decoder__process_masks(
24537 wuffs_bmp__decoder* self) {
24538 wuffs_base__status status = wuffs_base__make_status(NULL);
24539
24540 uint32_t v_i = 0;
24541 uint32_t v_mask = 0;
24542 uint32_t v_n = 0;
24543
24544 while (v_i < 4) {
24545 v_mask = self->private_impl.f_channel_masks[v_i];
24546 if (v_mask != 0) {
24547 v_n = 0;
24548 while ((v_mask & 1) == 0) {
24549 v_n += 1;
24550 v_mask >>= 1;
24551 }
24552 self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31)));
24553 v_n = 0;
24554 while ((v_mask & 1) == 1) {
24555 v_n += 1;
24556 v_mask >>= 1;
24557 }
24558 if ((v_mask != 0) || (v_n > 32)) {
24559 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
24560 goto exit;
24561 }
24562 self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n));
24563 } else if (v_i != 3) {
24564 status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
24565 goto exit;
24566 }
24567 v_i += 1;
24568 }
24569
24570 goto ok;
24571 ok:
24572 goto exit;
24573 exit:
24574 return status;
24575 }
24576
24577 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
24578
24579 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
24580
24581 // ---------------- Status Codes Implementations
24582
24583 const char wuffs_cbor__error__bad_input[] = "#cbor: bad input";
24584 const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth";
24585 const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O";
24586 const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length";
24587
24588 // ---------------- Private Consts
24589
24590 static const uint32_t
24591 WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
24592 8388612, 8388616, 8388610, 8388609,
24593 };
24594
24595 static const uint8_t
24596 WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
24597 1, 1, 1, 1, 1, 1, 1, 1,
24598 1, 1, 1, 1, 1, 1, 1, 1,
24599 1, 1, 1, 1, 1, 1, 1, 1,
24600 2, 3, 5, 9, 0, 0, 0, 1,
24601 };
24602
24603 // ---------------- Private Initializer Prototypes
24604
24605 // ---------------- Private Function Prototypes
24606
24607 // ---------------- VTables
24608
24609 const wuffs_base__token_decoder__func_ptrs
24610 wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = {
24611 (wuffs_base__status(*)(void*,
24612 wuffs_base__token_buffer*,
24613 wuffs_base__io_buffer*,
24614 wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens),
24615 (wuffs_base__empty_struct(*)(void*,
24616 uint32_t,
24617 bool))(&wuffs_cbor__decoder__set_quirk_enabled),
24618 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len),
24619 };
24620
24621 // ---------------- Initializer Implementations
24622
24623 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_cbor__decoder__initialize(wuffs_cbor__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)24624 wuffs_cbor__decoder__initialize(
24625 wuffs_cbor__decoder* self,
24626 size_t sizeof_star_self,
24627 uint64_t wuffs_version,
24628 uint32_t options){
24629 if (!self) {
24630 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24631 }
24632 if (sizeof(*self) != sizeof_star_self) {
24633 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
24634 }
24635 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
24636 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
24637 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
24638 }
24639
24640 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
24641 // The whole point of this if-check is to detect an uninitialized *self.
24642 // We disable the warning on GCC. Clang-5.0 does not have this warning.
24643 #if !defined(__clang__) && defined(__GNUC__)
24644 #pragma GCC diagnostic push
24645 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
24646 #endif
24647 if (self->private_impl.magic != 0) {
24648 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
24649 }
24650 #if !defined(__clang__) && defined(__GNUC__)
24651 #pragma GCC diagnostic pop
24652 #endif
24653 } else {
24654 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
24655 memset(self, 0, sizeof(*self));
24656 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
24657 } else {
24658 memset(&(self->private_impl), 0, sizeof(self->private_impl));
24659 }
24660 }
24661
24662 self->private_impl.magic = WUFFS_BASE__MAGIC;
24663 self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
24664 wuffs_base__token_decoder__vtable_name;
24665 self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
24666 (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder);
24667 return wuffs_base__make_status(NULL);
24668 }
24669
24670 wuffs_cbor__decoder*
wuffs_cbor__decoder__alloc()24671 wuffs_cbor__decoder__alloc() {
24672 wuffs_cbor__decoder* x =
24673 (wuffs_cbor__decoder*)(calloc(sizeof(wuffs_cbor__decoder), 1));
24674 if (!x) {
24675 return NULL;
24676 }
24677 if (wuffs_cbor__decoder__initialize(
24678 x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
24679 free(x);
24680 return NULL;
24681 }
24682 return x;
24683 }
24684
24685 size_t
sizeof__wuffs_cbor__decoder()24686 sizeof__wuffs_cbor__decoder() {
24687 return sizeof(wuffs_cbor__decoder);
24688 }
24689
24690 // ---------------- Function Implementations
24691
24692 // -------- func cbor.decoder.set_quirk_enabled
24693
24694 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_cbor__decoder__set_quirk_enabled(wuffs_cbor__decoder * self,uint32_t a_quirk,bool a_enabled)24695 wuffs_cbor__decoder__set_quirk_enabled(
24696 wuffs_cbor__decoder* self,
24697 uint32_t a_quirk,
24698 bool a_enabled) {
24699 return wuffs_base__make_empty_struct();
24700 }
24701
24702 // -------- func cbor.decoder.workbuf_len
24703
24704 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_cbor__decoder__workbuf_len(const wuffs_cbor__decoder * self)24705 wuffs_cbor__decoder__workbuf_len(
24706 const wuffs_cbor__decoder* self) {
24707 if (!self) {
24708 return wuffs_base__utility__empty_range_ii_u64();
24709 }
24710 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
24711 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
24712 return wuffs_base__utility__empty_range_ii_u64();
24713 }
24714
24715 return wuffs_base__utility__empty_range_ii_u64();
24716 }
24717
24718 // -------- func cbor.decoder.decode_tokens
24719
24720 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_cbor__decoder__decode_tokens(wuffs_cbor__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)24721 wuffs_cbor__decoder__decode_tokens(
24722 wuffs_cbor__decoder* self,
24723 wuffs_base__token_buffer* a_dst,
24724 wuffs_base__io_buffer* a_src,
24725 wuffs_base__slice_u8 a_workbuf) {
24726 if (!self) {
24727 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
24728 }
24729 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
24730 return wuffs_base__make_status(
24731 (self->private_impl.magic == WUFFS_BASE__DISABLED)
24732 ? wuffs_base__error__disabled_by_previous_error
24733 : wuffs_base__error__initialize_not_called);
24734 }
24735 if (!a_dst || !a_src) {
24736 self->private_impl.magic = WUFFS_BASE__DISABLED;
24737 return wuffs_base__make_status(wuffs_base__error__bad_argument);
24738 }
24739 if ((self->private_impl.active_coroutine != 0) &&
24740 (self->private_impl.active_coroutine != 1)) {
24741 self->private_impl.magic = WUFFS_BASE__DISABLED;
24742 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
24743 }
24744 self->private_impl.active_coroutine = 0;
24745 wuffs_base__status status = wuffs_base__make_status(NULL);
24746
24747 uint64_t v_string_length = 0;
24748 uint64_t v_n64 = 0;
24749 uint32_t v_depth = 0;
24750 uint32_t v_stack_byte = 0;
24751 uint32_t v_stack_bit = 0;
24752 uint32_t v_stack_val = 0;
24753 uint32_t v_token_length = 0;
24754 uint32_t v_vminor = 0;
24755 uint32_t v_vminor_alt = 0;
24756 uint32_t v_continued = 0;
24757 uint8_t v_c = 0;
24758 uint8_t v_c_major = 0;
24759 uint8_t v_c_minor = 0;
24760 bool v_tagged = false;
24761 uint8_t v_indefinite_string_major_type = 0;
24762
24763 wuffs_base__token* iop_a_dst = NULL;
24764 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24765 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24766 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24767 if (a_dst) {
24768 io0_a_dst = a_dst->data.ptr;
24769 io1_a_dst = io0_a_dst + a_dst->meta.wi;
24770 iop_a_dst = io1_a_dst;
24771 io2_a_dst = io0_a_dst + a_dst->data.len;
24772 if (a_dst->meta.closed) {
24773 io2_a_dst = iop_a_dst;
24774 }
24775 }
24776 const uint8_t* iop_a_src = NULL;
24777 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24778 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24779 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
24780 if (a_src) {
24781 io0_a_src = a_src->data.ptr;
24782 io1_a_src = io0_a_src + a_src->meta.ri;
24783 iop_a_src = io1_a_src;
24784 io2_a_src = io0_a_src + a_src->meta.wi;
24785 }
24786
24787 uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
24788 if (coro_susp_point) {
24789 v_string_length = self->private_data.s_decode_tokens[0].v_string_length;
24790 v_depth = self->private_data.s_decode_tokens[0].v_depth;
24791 v_token_length = self->private_data.s_decode_tokens[0].v_token_length;
24792 v_tagged = self->private_data.s_decode_tokens[0].v_tagged;
24793 v_indefinite_string_major_type = self->private_data.s_decode_tokens[0].v_indefinite_string_major_type;
24794 }
24795 switch (coro_susp_point) {
24796 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
24797
24798 if (self->private_impl.f_end_of_data) {
24799 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
24800 goto ok;
24801 }
24802 label__outer__continue:;
24803 while (true) {
24804 while (true) {
24805 while (true) {
24806 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
24807 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24808 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
24809 goto label__outer__continue;
24810 }
24811 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
24812 if (a_src && a_src->meta.closed) {
24813 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24814 goto exit;
24815 }
24816 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24817 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
24818 goto label__outer__continue;
24819 }
24820 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
24821 if ((v_indefinite_string_major_type != 0) && (v_indefinite_string_major_type != (v_c >> 5))) {
24822 if (v_c != 255) {
24823 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24824 goto exit;
24825 }
24826 v_vminor = 4194560;
24827 if (v_indefinite_string_major_type == 3) {
24828 v_vminor |= 19;
24829 }
24830 v_indefinite_string_major_type = 0;
24831 iop_a_src += 1;
24832 *iop_a_dst++ = wuffs_base__make_token(
24833 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24834 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24835 goto label__goto_parsed_a_leaf_value__break;
24836 }
24837 iop_a_src += 1;
24838 v_c_major = ((uint8_t)((v_c >> 5)));
24839 v_c_minor = (v_c & 31);
24840 if (v_c_minor < 24) {
24841 v_string_length = ((uint64_t)(v_c_minor));
24842 } else {
24843 while (true) {
24844 if (v_c_minor == 24) {
24845 if (((uint64_t)(io2_a_src - iop_a_src)) >= 1) {
24846 v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
24847 iop_a_src += 1;
24848 goto label__goto_have_string_length__break;
24849 }
24850 } else if (v_c_minor == 25) {
24851 if (((uint64_t)(io2_a_src - iop_a_src)) >= 2) {
24852 v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
24853 iop_a_src += 2;
24854 goto label__goto_have_string_length__break;
24855 }
24856 } else if (v_c_minor == 26) {
24857 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
24858 v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
24859 iop_a_src += 4;
24860 goto label__goto_have_string_length__break;
24861 }
24862 } else if (v_c_minor == 27) {
24863 if (((uint64_t)(io2_a_src - iop_a_src)) >= 8) {
24864 v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
24865 iop_a_src += 8;
24866 goto label__goto_have_string_length__break;
24867 }
24868 } else {
24869 v_string_length = 0;
24870 goto label__goto_have_string_length__break;
24871 }
24872 if (iop_a_src > io1_a_src) {
24873 iop_a_src--;
24874 if (a_src && a_src->meta.closed) {
24875 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24876 goto exit;
24877 }
24878 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24879 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
24880 v_c_major = 0;
24881 v_c_minor = 0;
24882 goto label__outer__continue;
24883 }
24884 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
24885 goto exit;
24886 }
24887 label__goto_have_string_length__break:;
24888 }
24889 if (v_c_major == 0) {
24890 if (v_c_minor < 26) {
24891 *iop_a_dst++ = wuffs_base__make_token(
24892 (((uint64_t)((14680064 | ((uint32_t)((v_string_length & 65535)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24893 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24894 goto label__goto_parsed_a_leaf_value__break;
24895 } else if (v_c_minor < 28) {
24896 *iop_a_dst++ = wuffs_base__make_token(
24897 (((uint64_t)((14680064 | ((uint32_t)((v_string_length >> 46)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24898 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24899 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24900 *iop_a_dst++ = wuffs_base__make_token(
24901 (~(v_string_length & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
24902 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24903 goto label__goto_parsed_a_leaf_value__break;
24904 }
24905 } else if (v_c_major == 1) {
24906 if (v_c_minor < 26) {
24907 *iop_a_dst++ = wuffs_base__make_token(
24908 (((uint64_t)((12582912 | (2097151 - ((uint32_t)((v_string_length & 65535))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24909 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24910 goto label__goto_parsed_a_leaf_value__break;
24911 } else if (v_c_minor < 28) {
24912 if (v_string_length < 9223372036854775808u) {
24913 *iop_a_dst++ = wuffs_base__make_token(
24914 (((uint64_t)((12582912 | (2097151 - ((uint32_t)((v_string_length >> 46))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24915 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24916 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24917 *iop_a_dst++ = wuffs_base__make_token(
24918 (~((18446744073709551615u - v_string_length) & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
24919 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24920 } else {
24921 *iop_a_dst++ = wuffs_base__make_token(
24922 (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
24923 (((uint64_t)(16777216)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24924 (((uint64_t)(9)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24925 }
24926 goto label__goto_parsed_a_leaf_value__break;
24927 }
24928 } else if (v_c_major == 2) {
24929 if (v_c_minor < 28) {
24930 if (v_string_length == 0) {
24931 *iop_a_dst++ = wuffs_base__make_token(
24932 (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24933 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24934 goto label__goto_parsed_a_leaf_value__break;
24935 }
24936 *iop_a_dst++ = wuffs_base__make_token(
24937 (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24938 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24939 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24940 } else if (v_c_minor == 31) {
24941 if (v_indefinite_string_major_type != 0) {
24942 goto label__goto_fail__break;
24943 }
24944 v_indefinite_string_major_type = 2;
24945 *iop_a_dst++ = wuffs_base__make_token(
24946 (((uint64_t)(4194560)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24947 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24948 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24949 goto label__outer__continue;
24950 } else {
24951 goto label__goto_fail__break;
24952 }
24953 label__0__continue:;
24954 while (true) {
24955 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
24956 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
24957 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
24958 goto label__0__continue;
24959 }
24960 v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src)));
24961 v_token_length = ((uint32_t)((v_n64 & 65535)));
24962 if (v_n64 > 65535) {
24963 v_token_length = 65535;
24964 } else if (v_token_length <= 0) {
24965 if (a_src && a_src->meta.closed) {
24966 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
24967 goto exit;
24968 }
24969 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
24970 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
24971 goto label__0__continue;
24972 }
24973 if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
24974 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
24975 goto exit;
24976 }
24977 v_string_length -= ((uint64_t)(v_token_length));
24978 v_continued = 0;
24979 if ((v_string_length > 0) || (v_indefinite_string_major_type > 0)) {
24980 v_continued = 1;
24981 }
24982 iop_a_src += v_token_length;
24983 *iop_a_dst++ = wuffs_base__make_token(
24984 (((uint64_t)(4194816)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24985 (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
24986 (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
24987 if (v_string_length > 0) {
24988 goto label__0__continue;
24989 } else if (v_indefinite_string_major_type > 0) {
24990 goto label__outer__continue;
24991 }
24992 goto label__goto_parsed_a_leaf_value__break;
24993 }
24994 } else if (v_c_major == 3) {
24995 if (v_c_minor < 28) {
24996 if (v_string_length == 0) {
24997 *iop_a_dst++ = wuffs_base__make_token(
24998 (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
24999 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25000 goto label__goto_parsed_a_leaf_value__break;
25001 }
25002 *iop_a_dst++ = wuffs_base__make_token(
25003 (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25004 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25005 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25006 } else if (v_c_minor == 31) {
25007 if (v_indefinite_string_major_type != 0) {
25008 goto label__goto_fail__break;
25009 }
25010 v_indefinite_string_major_type = 3;
25011 *iop_a_dst++ = wuffs_base__make_token(
25012 (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25013 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25014 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25015 goto label__outer__continue;
25016 } else {
25017 goto label__goto_fail__break;
25018 }
25019 label__1__continue:;
25020 while (true) {
25021 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
25022 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
25023 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
25024 goto label__1__continue;
25025 }
25026 v_n64 = wuffs_base__u64__min(v_string_length, 65535);
25027 v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src,
25028 ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64))))));
25029 v_token_length = ((uint32_t)((v_n64 & 65535)));
25030 if (v_token_length <= 0) {
25031 if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4)) {
25032 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
25033 goto exit;
25034 }
25035 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
25036 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
25037 goto label__1__continue;
25038 }
25039 if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
25040 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
25041 goto exit;
25042 }
25043 v_string_length -= ((uint64_t)(v_token_length));
25044 v_continued = 0;
25045 if ((v_string_length > 0) || (v_indefinite_string_major_type > 0)) {
25046 v_continued = 1;
25047 }
25048 iop_a_src += v_token_length;
25049 *iop_a_dst++ = wuffs_base__make_token(
25050 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25051 (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25052 (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25053 if (v_string_length > 0) {
25054 goto label__1__continue;
25055 } else if (v_indefinite_string_major_type > 0) {
25056 goto label__outer__continue;
25057 }
25058 goto label__goto_parsed_a_leaf_value__break;
25059 }
25060 } else if (v_c_major == 4) {
25061 if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0) {
25062 goto label__goto_fail__break;
25063 } else if (v_depth >= 1024) {
25064 v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
25065 while ((v_token_length > 0) && (iop_a_src > io1_a_src)) {
25066 iop_a_src--;
25067 v_token_length -= 1;
25068 }
25069 status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
25070 goto exit;
25071 }
25072 v_vminor = 2105361;
25073 v_vminor_alt = 2101282;
25074 if (v_depth > 0) {
25075 v_stack_byte = ((v_depth - 1) / 16);
25076 v_stack_bit = (((v_depth - 1) & 15) * 2);
25077 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25078 v_vminor = 2105377;
25079 v_vminor_alt = 2105378;
25080 } else {
25081 v_vminor = 2105409;
25082 v_vminor_alt = 2113570;
25083 }
25084 }
25085 *iop_a_dst++ = wuffs_base__make_token(
25086 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25087 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25088 if (v_c_minor == 0) {
25089 *iop_a_dst++ = wuffs_base__make_token(
25090 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25091 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25092 goto label__goto_parsed_a_leaf_value__break;
25093 }
25094 v_stack_byte = (v_depth / 16);
25095 v_stack_bit = ((v_depth & 15) * 2);
25096 self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(3)) << v_stack_bit));
25097 self->private_data.f_container_num_remaining[v_depth] = v_string_length;
25098 v_depth += 1;
25099 v_tagged = false;
25100 goto label__outer__continue;
25101 } else if (v_c_major == 5) {
25102 if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0) {
25103 goto label__goto_fail__break;
25104 } else if (v_depth >= 1024) {
25105 v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
25106 while ((v_token_length > 0) && (iop_a_src > io1_a_src)) {
25107 iop_a_src--;
25108 v_token_length -= 1;
25109 }
25110 status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
25111 goto exit;
25112 }
25113 v_vminor = 2113553;
25114 v_vminor_alt = 2101314;
25115 if (v_depth > 0) {
25116 v_stack_byte = ((v_depth - 1) / 16);
25117 v_stack_bit = (((v_depth - 1) & 15) * 2);
25118 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25119 v_vminor = 2113569;
25120 v_vminor_alt = 2105410;
25121 } else {
25122 v_vminor = 2113601;
25123 v_vminor_alt = 2113602;
25124 }
25125 }
25126 *iop_a_dst++ = wuffs_base__make_token(
25127 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25128 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25129 if (v_c_minor == 0) {
25130 *iop_a_dst++ = wuffs_base__make_token(
25131 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25132 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25133 goto label__goto_parsed_a_leaf_value__break;
25134 }
25135 v_stack_byte = (v_depth / 16);
25136 v_stack_bit = ((v_depth & 15) * 2);
25137 self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3)) << v_stack_bit);
25138 self->private_data.f_container_num_remaining[v_depth] = v_string_length;
25139 v_depth += 1;
25140 v_tagged = false;
25141 goto label__outer__continue;
25142 } else if (v_c_major == 6) {
25143 if (v_c_minor >= 28) {
25144 goto label__goto_fail__break;
25145 }
25146 if (v_string_length < 262144) {
25147 *iop_a_dst++ = wuffs_base__make_token(
25148 (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25149 (((uint64_t)((4194304 | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25150 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25151 } else {
25152 *iop_a_dst++ = wuffs_base__make_token(
25153 (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25154 (((uint64_t)((4194304 | ((uint32_t)((v_string_length >> 46)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25155 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
25156 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25157 *iop_a_dst++ = wuffs_base__make_token(
25158 (~(v_string_length & 70368744177663) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
25159 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25160 }
25161 v_tagged = true;
25162 goto label__outer__continue;
25163 } else if (v_c_major == 7) {
25164 if (v_c_minor < 20) {
25165 *iop_a_dst++ = wuffs_base__make_token(
25166 (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25167 (((uint64_t)((8388608 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25168 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25169 goto label__goto_parsed_a_leaf_value__break;
25170 } else if (v_c_minor < 24) {
25171 *iop_a_dst++ = wuffs_base__make_token(
25172 (((uint64_t)(WUFFS_CBOR__LITERALS[(v_c_minor & 3)])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25173 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25174 goto label__goto_parsed_a_leaf_value__break;
25175 } else if (v_c_minor == 24) {
25176 if (v_string_length < 24) {
25177 if ( ! (iop_a_src > io1_a_src)) {
25178 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
25179 goto exit;
25180 }
25181 iop_a_src--;
25182 goto label__goto_fail__break;
25183 }
25184 *iop_a_dst++ = wuffs_base__make_token(
25185 (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
25186 (((uint64_t)((8388608 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25187 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25188 goto label__goto_parsed_a_leaf_value__break;
25189 } else if (v_c_minor < 28) {
25190 *iop_a_dst++ = wuffs_base__make_token(
25191 (((uint64_t)(10490113)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25192 (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25193 goto label__goto_parsed_a_leaf_value__break;
25194 } else if (v_c_minor == 31) {
25195 if (v_tagged || (v_depth <= 0)) {
25196 goto label__goto_fail__break;
25197 }
25198 v_depth -= 1;
25199 if (self->private_data.f_container_num_remaining[v_depth] != 0) {
25200 goto label__goto_fail__break;
25201 }
25202 v_stack_byte = (v_depth / 16);
25203 v_stack_bit = ((v_depth & 15) * 2);
25204 v_stack_val = (3 & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit));
25205 if (v_stack_val == 1) {
25206 goto label__goto_fail__break;
25207 }
25208 if (v_stack_val != 3) {
25209 v_vminor_alt = 2097186;
25210 } else {
25211 v_vminor_alt = 2097218;
25212 }
25213 if (v_depth <= 0) {
25214 v_vminor_alt |= 4096;
25215 } else {
25216 v_stack_byte = ((v_depth - 1) / 16);
25217 v_stack_bit = (((v_depth - 1) & 15) * 2);
25218 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25219 v_vminor_alt |= 8192;
25220 } else {
25221 v_vminor_alt |= 16384;
25222 }
25223 }
25224 *iop_a_dst++ = wuffs_base__make_token(
25225 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25226 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25227 goto label__goto_parsed_a_leaf_value__break;
25228 }
25229 }
25230 goto label__goto_fail__break;
25231 }
25232 label__goto_fail__break:;
25233 if (iop_a_src > io1_a_src) {
25234 iop_a_src--;
25235 status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
25236 goto exit;
25237 }
25238 status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
25239 goto exit;
25240 }
25241 label__goto_parsed_a_leaf_value__break:;
25242 v_tagged = false;
25243 while (v_depth > 0) {
25244 v_stack_byte = ((v_depth - 1) / 16);
25245 v_stack_bit = (((v_depth - 1) & 15) * 2);
25246 self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1)) << (v_stack_bit + 1));
25247 if (1 == (3 & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) {
25248 goto label__outer__continue;
25249 }
25250 if (self->private_data.f_container_num_remaining[(v_depth - 1)] <= 0) {
25251 goto label__outer__continue;
25252 }
25253 self->private_data.f_container_num_remaining[(v_depth - 1)] -= 1;
25254 if (self->private_data.f_container_num_remaining[(v_depth - 1)] > 0) {
25255 goto label__outer__continue;
25256 }
25257 label__2__continue:;
25258 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
25259 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
25260 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
25261 goto label__2__continue;
25262 }
25263 v_depth -= 1;
25264 v_stack_byte = (v_depth / 16);
25265 v_stack_bit = ((v_depth & 15) * 2);
25266 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25267 v_vminor_alt = 2097186;
25268 } else {
25269 v_vminor_alt = 2097218;
25270 }
25271 if (v_depth <= 0) {
25272 v_vminor_alt |= 4096;
25273 } else {
25274 v_stack_byte = ((v_depth - 1) / 16);
25275 v_stack_bit = (((v_depth - 1) & 15) * 2);
25276 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
25277 v_vminor_alt |= 8192;
25278 } else {
25279 v_vminor_alt |= 16384;
25280 }
25281 }
25282 *iop_a_dst++ = wuffs_base__make_token(
25283 (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
25284 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
25285 }
25286 goto label__outer__break;
25287 }
25288 label__outer__break:;
25289 self->private_impl.f_end_of_data = true;
25290
25291 ok:
25292 self->private_impl.p_decode_tokens[0] = 0;
25293 goto exit;
25294 }
25295
25296 goto suspend;
25297 suspend:
25298 self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
25299 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
25300 self->private_data.s_decode_tokens[0].v_string_length = v_string_length;
25301 self->private_data.s_decode_tokens[0].v_depth = v_depth;
25302 self->private_data.s_decode_tokens[0].v_token_length = v_token_length;
25303 self->private_data.s_decode_tokens[0].v_tagged = v_tagged;
25304 self->private_data.s_decode_tokens[0].v_indefinite_string_major_type = v_indefinite_string_major_type;
25305
25306 goto exit;
25307 exit:
25308 if (a_dst) {
25309 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
25310 }
25311 if (a_src) {
25312 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
25313 }
25314
25315 if (wuffs_base__status__is_error(&status)) {
25316 self->private_impl.magic = WUFFS_BASE__DISABLED;
25317 }
25318 return status;
25319 }
25320
25321 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
25322
25323 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
25324
25325 // ---------------- Status Codes Implementations
25326
25327 // ---------------- Private Consts
25328
25329 static const uint32_t
25330 WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = {
25331 {
25332 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
25333 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
25334 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
25335 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
25336 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
25337 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
25338 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
25339 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
25340 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
25341 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
25342 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
25343 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
25344 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
25345 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
25346 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
25347 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
25348 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
25349 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
25350 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
25351 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
25352 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
25353 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
25354 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
25355 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
25356 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
25357 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
25358 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
25359 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
25360 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
25361 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
25362 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
25363 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117,
25364 }, {
25365 0, 421212481, 842424962, 724390851, 1684849924, 2105013317, 1448781702, 1329698503,
25366 3369699848, 3519200073, 4210026634, 3824474571, 2897563404, 3048111693, 2659397006, 2274893007,
25367 1254232657, 1406739216, 2029285587, 1643069842, 783210325, 934667796, 479770071, 92505238,
25368 2182846553, 2600511768, 2955803355, 2838940570, 3866582365, 4285295644, 3561045983, 3445231262,
25369 2508465314, 2359236067, 2813478432, 3198777185, 4058571174, 3908292839, 3286139684, 3670389349,
25370 1566420650, 1145479147, 1869335592, 1987116393, 959540142, 539646703, 185010476, 303839341,
25371 3745920755, 3327985586, 3983561841, 4100678960, 3140154359, 2721170102, 2300350837, 2416418868,
25372 396344571, 243568058, 631889529, 1018359608, 1945336319, 1793607870, 1103436669, 1490954812,
25373 4034481925, 3915546180, 3259968903, 3679722694, 2484439553, 2366552896, 2787371139, 3208174018,
25374 950060301, 565965900, 177645455, 328046286, 1556873225, 1171730760, 1861902987, 2011255754,
25375 3132841300, 2745199637, 2290958294, 2442530455, 3738671184, 3352078609, 3974232786, 4126854035,
25376 1919080284, 1803150877, 1079293406, 1498383519, 370020952, 253043481, 607678682, 1025720731,
25377 1711106983, 2095471334, 1472923941, 1322268772, 26324643, 411738082, 866634785, 717028704,
25378 2904875439, 3024081134, 2668790573, 2248782444, 3376948395, 3495106026, 4219356713, 3798300520,
25379 792689142, 908347575, 487136116, 68299317, 1263779058, 1380486579, 2036719216, 1618931505,
25380 3890672638, 4278043327, 3587215740, 3435896893, 2206873338, 2593195963, 2981909624, 2829542713,
25381 998479947, 580430090, 162921161, 279890824, 1609522511, 1190423566, 1842954189, 1958874764,
25382 4082766403, 3930137346, 3245109441, 3631694208, 2536953671, 2385372678, 2768287173, 3155920004,
25383 1900120602, 1750776667, 1131931800, 1517083097, 355290910, 204897887, 656092572, 1040194781,
25384 3113746450, 2692952403, 2343461520, 2461357009, 3723805974, 3304059991, 4022511508, 4141455061,
25385 2919742697, 3072101800, 2620513899, 2234183466, 3396041197, 3547351212, 4166851439, 3779471918,
25386 1725839073, 2143618976, 1424512099, 1307796770, 45282277, 464110244, 813994343, 698327078,
25387 3838160568, 4259225593, 3606301754, 3488152955, 2158586812, 2578602749, 2996767038, 2877569151,
25388 740041904, 889656817, 506086962, 120682355, 1215357364, 1366020341, 2051441462, 1667084919,
25389 3422213966, 3538019855, 4190942668, 3772220557, 2945847882, 3062702859, 2644537544, 2226864521,
25390 52649286, 439905287, 823476164, 672009861, 1733269570, 2119477507, 1434057408, 1281543041,
25391 2167981343, 2552493150, 3004082077, 2853541596, 3847487515, 4233048410, 3613549209, 3464057816,
25392 1239502615, 1358593622, 2077699477, 1657543892, 764250643, 882293586, 532408465, 111204816,
25393 1585378284, 1197851309, 1816695150, 1968414767, 974272232, 587794345, 136598634, 289367339,
25394 2527558116, 2411481253, 2760973158, 3179948583, 4073438432, 3956313505, 3237863010, 3655790371,
25395 347922877, 229101820, 646611775, 1066513022, 1892689081, 1774917112, 1122387515, 1543337850,
25396 3697634229, 3313392372, 3998419255, 4148705398, 3087642289, 2702352368, 2319436851, 2468674930,
25397 }, {
25398 0, 29518391, 59036782, 38190681, 118073564, 114017003, 76381362, 89069189,
25399 236147128, 265370511, 228034006, 206958561, 152762724, 148411219, 178138378, 190596925,
25400 472294256, 501532999, 530741022, 509615401, 456068012, 451764635, 413917122, 426358261,
25401 305525448, 334993663, 296822438, 275991697, 356276756, 352202787, 381193850, 393929805,
25402 944588512, 965684439, 1003065998, 973863097, 1061482044, 1049003019, 1019230802, 1023561829,
25403 912136024, 933002607, 903529270, 874031361, 827834244, 815125939, 852716522, 856752605,
25404 611050896, 631869351, 669987326, 640506825, 593644876, 580921211, 551983394, 556069653,
25405 712553512, 733666847, 704405574, 675154545, 762387700, 749958851, 787859610, 792175277,
25406 1889177024, 1901651959, 1931368878, 1927033753, 2006131996, 1985040171, 1947726194, 1976933189,
25407 2122964088, 2135668303, 2098006038, 2093965857, 2038461604, 2017599123, 2047123658, 2076625661,
25408 1824272048, 1836991623, 1866005214, 1861914857, 1807058540, 1786244187, 1748062722, 1777547317,
25409 1655668488, 1668093247, 1630251878, 1625932113, 1705433044, 1684323811, 1713505210, 1742760333,
25410 1222101792, 1226154263, 1263738702, 1251046777, 1339974652, 1310460363, 1281013650, 1301863845,
25411 1187289752, 1191637167, 1161842422, 1149379777, 1103966788, 1074747507, 1112139306, 1133218845,
25412 1425107024, 1429406311, 1467333694, 1454888457, 1408811148, 1379576507, 1350309090, 1371438805,
25413 1524775400, 1528845279, 1499917702, 1487177649, 1575719220, 1546255107, 1584350554, 1605185389,
25414 3778354048, 3774312887, 3803303918, 3816007129, 3862737756, 3892238699, 3854067506, 3833203973,
25415 4012263992, 4007927823, 3970080342, 3982554209, 3895452388, 3924658387, 3953866378, 3932773565,
25416 4245928176, 4241609415, 4271336606, 4283762345, 4196012076, 4225268251, 4187931714, 4166823541,
25417 4076923208, 4072833919, 4035198246, 4047918865, 4094247316, 4123732899, 4153251322, 4132437965,
25418 3648544096, 3636082519, 3673983246, 3678331705, 3732010428, 3753090955, 3723829714, 3694611429,
25419 3614117080, 3601426159, 3572488374, 3576541825, 3496125444, 3516976691, 3555094634, 3525581405,
25420 3311336976, 3298595879, 3336186494, 3340255305, 3260503756, 3281337595, 3251864226, 3222399125,
25421 3410866088, 3398419871, 3368647622, 3372945905, 3427010420, 3448139075, 3485520666, 3456284973,
25422 2444203584, 2423127159, 2452308526, 2481530905, 2527477404, 2539934891, 2502093554, 2497740997,
25423 2679949304, 2659102159, 2620920726, 2650438049, 2562027300, 2574714131, 2603727690, 2599670141,
25424 2374579504, 2353749767, 2383274334, 2412743529, 2323684844, 2336421851, 2298759554, 2294686645,
25425 2207933576, 2186809023, 2149495014, 2178734801, 2224278612, 2236720739, 2266437690, 2262135309,
25426 2850214048, 2820717207, 2858812622, 2879680249, 2934667388, 2938704459, 2909776914, 2897069605,
25427 2817622296, 2788420399, 2759153014, 2780249921, 2700618180, 2704950259, 2742877610, 2730399645,
25428 3049550800, 3020298727, 3057690558, 3078802825, 2999835404, 3004150075, 2974355298, 2961925461,
25429 3151438440, 3121956959, 3092510214, 3113327665, 3168701108, 3172786307, 3210370778, 3197646061,
25430 }, {
25431 0, 3099354981, 2852767883, 313896942, 2405603159, 937357362, 627793884, 2648127673,
25432 3316918511, 2097696650, 1874714724, 3607201537, 1255587768, 4067088605, 3772741427, 1482887254,
25433 1343838111, 3903140090, 4195393300, 1118632049, 3749429448, 1741137837, 1970407491, 3452858150,
25434 2511175536, 756094997, 1067759611, 2266550430, 449832999, 2725482306, 2965774508, 142231497,
25435 2687676222, 412010587, 171665333, 2995192016, 793786473, 2548850444, 2237264098, 1038456711,
25436 1703315409, 3711623348, 3482275674, 1999841343, 3940814982, 1381529571, 1089329165, 4166106984,
25437 4029413537, 1217896388, 1512189994, 3802027855, 2135519222, 3354724499, 3577784189, 1845280792,
25438 899665998, 2367928107, 2677414085, 657096608, 3137160985, 37822588, 284462994, 2823350519,
25439 2601801789, 598228824, 824021174, 2309093331, 343330666, 2898962447, 3195996129, 113467524,
25440 1587572946, 3860600759, 4104763481, 1276501820, 3519211397, 1769898208, 2076913422, 3279374443,
25441 3406630818, 1941006535, 1627703081, 3652755532, 1148164341, 4241751952, 3999682686, 1457141531,
25442 247015245, 3053797416, 2763059142, 470583459, 2178658330, 963106687, 735213713, 2473467892,
25443 992409347, 2207944806, 2435792776, 697522413, 3024379988, 217581361, 508405983, 2800865210,
25444 4271038444, 1177467017, 1419450215, 3962007554, 1911572667, 3377213406, 3690561584, 1665525589,
25445 1799331996, 3548628985, 3241568279, 2039091058, 3831314379, 1558270126, 1314193216, 4142438437,
25446 2928380019, 372764438, 75645176, 3158189981, 568925988, 2572515393, 2346768303, 861712586,
25447 3982079547, 1441124702, 1196457648, 4293663189, 1648042348, 3666298377, 3358779879, 1888390786,
25448 686661332, 2421291441, 2196002399, 978858298, 2811169155, 523464422, 226935048, 3040519789,
25449 3175145892, 100435649, 390670639, 2952089162, 841119475, 2325614998, 2553003640, 546822429,
25450 2029308235, 3225988654, 3539796416, 1782671013, 4153826844, 1328167289, 1570739863, 3844338162,
25451 1298864389, 4124540512, 3882013070, 1608431339, 3255406162, 2058742071, 1744848601, 3501990332,
25452 2296328682, 811816591, 584513889, 2590678532, 129869501, 3204563416, 2914283062, 352848211,
25453 494030490, 2781751807, 3078325777, 264757620, 2450577869, 715964072, 941166918, 2158327331,
25454 3636881013, 1618608400, 1926213374, 3396585883, 1470427426, 4011365959, 4255988137, 1158766284,
25455 1984818694, 3471935843, 3695453837, 1693991400, 4180638033, 1100160564, 1395044826, 3952793279,
25456 3019491049, 189112716, 435162722, 2706139399, 1016811966, 2217162459, 2526189877, 774831696,
25457 643086745, 2666061564, 2354934034, 887166583, 2838900430, 294275499, 54519365, 3145957664,
25458 3823145334, 1532818963, 1240029693, 4048895640, 1820460577, 3560857924, 3331051178, 2117577167,
25459 3598663992, 1858283101, 2088143283, 3301633750, 1495127663, 3785470218, 4078182116, 1269332353,
25460 332098007, 2876706482, 3116540252, 25085497, 2628386432, 605395429, 916469259, 2384220526,
25461 2254837415, 1054503362, 745528876, 2496903497, 151290352, 2981684885, 2735556987, 464596510,
25462 1137851976, 4218313005, 3923506883, 1365741990, 3434129695, 1946996346, 1723425172, 3724871409,
25463 }, {
25464 0, 1029712304, 2059424608, 1201699536, 4118849216, 3370159984, 2403399072, 2988497936,
25465 812665793, 219177585, 1253054625, 2010132753, 3320900865, 4170237105, 3207642721, 2186319825,
25466 1625331586, 1568718386, 438355170, 658566482, 2506109250, 2818578674, 4020265506, 3535817618,
25467 1351670851, 1844508147, 709922595, 389064339, 2769320579, 2557498163, 3754961379, 3803185235,
25468 3250663172, 4238411444, 3137436772, 2254525908, 876710340, 153198708, 1317132964, 1944187668,
25469 4054934725, 3436268917, 2339452837, 3054575125, 70369797, 961670069, 2129760613, 1133623509,
25470 2703341702, 2621542710, 3689016294, 3867263574, 1419845190, 1774270454, 778128678, 318858390,
25471 2438067015, 2888948471, 3952189479, 3606153623, 1691440519, 1504803895, 504432359, 594620247,
25472 1492342857, 1704161785, 573770537, 525542041, 2910060169, 2417219385, 3618876905, 3939730521,
25473 1753420680, 1440954936, 306397416, 790849880, 2634265928, 2690882808, 3888375336, 3668168600,
25474 940822475, 91481723, 1121164459, 2142483739, 3448989963, 4042473659, 3075684971, 2318603227,
25475 140739594, 889433530, 1923340138, 1338244826, 4259521226, 3229813626, 2267247018, 3124975642,
25476 2570221389, 2756861693, 3824297005, 3734113693, 1823658381, 1372780605, 376603373, 722643805,
25477 2839690380, 2485261628, 3548540908, 4007806556, 1556257356, 1638052860, 637716780, 459464860,
25478 4191346895, 3300051327, 2199040943, 3195181599, 206718479, 825388991, 1989285231, 1274166495,
25479 3382881038, 4106388158, 3009607790, 2382549470, 1008864718, 21111934, 1189240494, 2072147742,
25480 2984685714, 2357631266, 3408323570, 4131834434, 1147541074, 2030452706, 1051084082, 63335554,
25481 2174155603, 3170292451, 4216760371, 3325460867, 1947622803, 1232499747, 248909555, 867575619,
25482 3506841360, 3966111392, 2881909872, 2527485376, 612794832, 434546784, 1581699760, 1663499008,
25483 3782634705, 3692447073, 2612412337, 2799048193, 351717905, 697754529, 1849071985, 1398190273,
25484 1881644950, 1296545318, 182963446, 931652934, 2242328918, 3100053734, 4284967478, 3255255942,
25485 1079497815, 2100821479, 983009079, 133672583, 3050795671, 2293717799, 3474399735, 4067887175,
25486 281479188, 765927844, 1778867060, 1466397380, 3846680276, 3626469220, 2676489652, 2733102084,
25487 548881365, 500656741, 1517752501, 1729575173, 3577210133, 3898068133, 2952246901, 2459410373,
25488 3910527195, 3564487019, 2480257979, 2931134987, 479546907, 569730987, 1716854139, 1530213579,
25489 3647316762, 3825568426, 2745561210, 2663766474, 753206746, 293940330, 1445287610, 1799716618,
25490 2314567513, 3029685993, 4080348217, 3461678473, 2088098201, 1091956777, 112560889, 1003856713,
25491 3112514712, 2229607720, 3276105720, 4263857736, 1275433560, 1902492648, 918929720, 195422344,
25492 685033439, 364179055, 1377080511, 1869921551, 3713294623, 3761522863, 2811507327, 2599689167,
25493 413436958, 633644462, 1650777982, 1594160846, 3978570462, 3494118254, 2548332990, 2860797966,
25494 1211387997, 1968470509, 854852413, 261368461, 3182753437, 2161434413, 3346310653, 4195650637,
25495 2017729436, 1160000044, 42223868, 1071931724, 2378480988, 2963576044, 4144295484, 3395602316,
25496 }, {
25497 0, 3411858341, 1304994059, 2257875630, 2609988118, 1355649459, 3596215069, 486879416,
25498 3964895853, 655315400, 2711298918, 1791488195, 2009251963, 3164476382, 973758832, 4048990933,
25499 64357019, 3364540734, 1310630800, 2235723829, 2554806413, 1394316072, 3582976390, 517157411,
25500 4018503926, 618222419, 2722963965, 1762783832, 1947517664, 3209171269, 970744811, 4068520014,
25501 128714038, 3438335635, 1248109629, 2167961496, 2621261600, 1466012805, 3522553387, 447296910,
25502 3959392091, 547575038, 2788632144, 1835791861, 1886307661, 3140622056, 1034314822, 4143626211,
25503 75106221, 3475428360, 1236444838, 2196665603, 2682996155, 1421317662, 3525567664, 427767573,
25504 3895035328, 594892389, 2782995659, 1857943406, 1941489622, 3101955187, 1047553757, 4113347960,
25505 257428076, 3288652233, 1116777319, 2311878850, 2496219258, 1603640287, 3640781169, 308099796,
25506 3809183745, 676813732, 2932025610, 1704983215, 2023410199, 3016104370, 894593820, 4262377657,
25507 210634999, 3352484690, 1095150076, 2316991065, 2535410401, 1547934020, 3671583722, 294336591,
25508 3772615322, 729897279, 2903845777, 1716123700, 2068629644, 2953845545, 914647431, 4258839074,
25509 150212442, 3282623743, 1161604689, 2388688372, 2472889676, 1480171241, 3735940167, 368132066,
25510 3836185911, 805002898, 2842635324, 1647574937, 2134298401, 3026852996, 855535146, 4188192143,
25511 186781121, 3229539940, 1189784778, 2377547631, 2427670487, 1542429810, 3715886812, 371670393,
25512 3882979244, 741170185, 2864262823, 1642462466, 2095107514, 3082559007, 824732849, 4201955092,
25513 514856152, 3589064573, 1400419795, 2552522358, 2233554638, 1316849003, 3370776517, 62202976,
25514 4075001525, 968836368, 3207280574, 1954014235, 1769133219, 2720925446, 616199592, 4024870413,
25515 493229635, 3594175974, 1353627464, 2616354029, 2264355925, 1303087088, 3409966430, 6498043,
25516 4046820398, 979978123, 3170710821, 2007099008, 1789187640, 2717386141, 661419827, 3962610838,
25517 421269998, 3527459403, 1423225061, 2676515648, 2190300152, 1238466653, 3477467891, 68755798,
25518 4115633027, 1041448998, 3095868040, 1943789869, 1860096405, 2776760880, 588673182, 3897205563,
25519 449450869, 3516317904, 1459794558, 2623431131, 2170245475, 1242006214, 3432247400, 131015629,
25520 4137259288, 1036337853, 3142660115, 1879958454, 1829294862, 2790523051, 549483013, 3952910752,
25521 300424884, 3669282065, 1545650111, 2541513754, 2323209378, 1092980487, 3350330793, 216870412,
25522 4256931033, 921128828, 2960342482, 2066738807, 1714085583, 2910195050, 736264132, 3770592353,
25523 306060335, 3647131530, 1610005796, 2494197377, 2309971513, 1123257756, 3295149874, 255536279,
25524 4268596802, 892423655, 3013951305, 2029645036, 1711070292, 2929725425, 674528607, 3815288570,
25525 373562242, 3709388839, 1535949449, 2429577516, 2379569556, 1183418929, 3223189663, 188820282,
25526 4195850735, 827017802, 3084859620, 2089020225, 1636228089, 2866415708, 743340786, 3876759895,
25527 361896217, 3738094268, 1482340370, 2466671543, 2382584591, 1163888810, 3284924932, 144124321,
25528 4190215028, 849168593, 3020503679, 2136336858, 1649465698, 2836138695, 798521449, 3838094284,
25529 }, {
25530 0, 2792819636, 2543784233, 837294749, 4098827283, 1379413927, 1674589498, 3316072078,
25531 871321191, 2509784531, 2758827854, 34034938, 3349178996, 1641505216, 1346337629, 4131942633,
25532 1742642382, 3249117050, 4030828007, 1446413907, 2475800797, 904311657, 68069876, 2725880384,
25533 1412551337, 4064729373, 3283010432, 1708771380, 2692675258, 101317902, 937551763, 2442587175,
25534 3485284764, 1774858792, 1478633653, 4266992385, 1005723023, 2642744891, 2892827814, 169477906,
25535 4233263099, 1512406095, 1808623314, 3451546982, 136139752, 2926205020, 2676114113, 972376437,
25536 2825102674, 236236518, 1073525883, 2576072655, 1546420545, 4200303349, 3417542760, 1841601500,
25537 2609703733, 1039917185, 202635804, 2858742184, 1875103526, 3384067218, 4166835727, 1579931067,
25538 1141601657, 3799809741, 3549717584, 1977839588, 2957267306, 372464350, 668680259, 2175552503,
25539 2011446046, 3516084394, 3766168119, 1175200131, 2209029901, 635180217, 338955812, 2990736784,
25540 601221559, 2242044419, 3024812190, 306049834, 3617246628, 1911408144, 1074125965, 3866285881,
25541 272279504, 3058543716, 2275784441, 567459149, 3832906691, 1107462263, 1944752874, 3583875422,
25542 2343980261, 767641425, 472473036, 3126744696, 2147051766, 3649987394, 3899029983, 1309766251,
25543 3092841090, 506333494, 801510315, 2310084639, 1276520081, 3932237093, 3683203000, 2113813516,
25544 3966292011, 1243601823, 2079834370, 3716205238, 405271608, 3192979340, 2411259153, 701492901,
25545 3750207052, 2045810168, 1209569125, 4000285905, 734575199, 2378150379, 3159862134, 438345922,
25546 2283203314, 778166598, 529136603, 3120492655, 2086260449, 3660498261, 3955679176, 1303499900,
25547 3153699989, 495890209, 744928700, 2316418568, 1337360518, 3921775410, 3626602927, 2120129051,
25548 4022892092, 1237286280, 2018993941, 3726666913, 461853231, 3186645403, 2350400262, 711936178,
25549 3693557851, 2052076527, 1270360434, 3989775046, 677911624, 2384402428, 3220639073, 427820757,
25550 1202443118, 3789347034, 3493118535, 1984154099, 3018127229, 362020041, 612099668, 2181885408,
25551 1950653705, 3526596285, 3822816288, 1168934804, 2148251930, 645706414, 395618355, 2984485767,
25552 544559008, 2248295444, 3085590153, 295523645, 3560598451, 1917673479, 1134918298, 3855773998,
25553 328860103, 3052210803, 2214924526, 577903450, 3889505748, 1101147744, 1883911421, 3594338121,
25554 3424493451, 1785369663, 1535282850, 4260726038, 944946072, 2653270060, 2949491377, 163225861,
25555 4294103532, 1501944408, 1752023237, 3457862513, 196998655, 2915761739, 2619532502, 978710370,
25556 2881684293, 229902577, 1012666988, 2586515928, 1603020630, 4193987810, 3356702335, 1852063179,
25557 2553040162, 1046169238, 263412747, 2848217023, 1818454321, 3390333573, 4227627032, 1569420204,
25558 60859927, 2782375331, 2487203646, 843627658, 4159668740, 1368951216, 1617990445, 3322386585,
25559 810543216, 2520310724, 2815490393, 27783917, 3288386659, 1652017111, 1402985802, 4125677310,
25560 1685994201, 3255382381, 4091620336, 1435902020, 2419138250, 910562686, 128847843, 2715354199,
25561 1469150398, 4058414858, 3222168983, 1719234083, 2749255853, 94984985, 876691844, 2453031472,
25562 }, {
25563 0, 3433693342, 1109723005, 2391738339, 2219446010, 1222643300, 3329165703, 180685081,
25564 3555007413, 525277995, 2445286600, 1567235158, 1471092047, 2600801745, 361370162, 3642757804,
25565 2092642603, 2953916853, 1050555990, 4063508168, 4176560081, 878395215, 3134470316, 1987983410,
25566 2942184094, 1676945920, 3984272867, 567356797, 722740324, 3887998202, 1764827929, 2778407815,
25567 4185285206, 903635656, 3142804779, 2012833205, 2101111980, 2979425330, 1058630609, 4088621903,
25568 714308067, 3862526333, 1756790430, 2753330688, 2933487385, 1651734407, 3975966820, 542535930,
25569 2244825981, 1231508451, 3353891840, 188896414, 25648519, 3442302233, 1134713594, 2399689316,
25570 1445480648, 2592229462, 336416693, 3634843435, 3529655858, 516441772, 2420588879, 1559052753,
25571 698204909, 3845636723, 1807271312, 2803025166, 2916600855, 1635634313, 4025666410, 593021940,
25572 4202223960, 919787974, 3093159461, 1962401467, 2117261218, 2996361020, 1008193759, 4038971457,
25573 1428616134, 2576151384, 386135227, 3685348389, 3513580860, 499580322, 2471098945, 1608776415,
25574 2260985971, 1248454893, 3303468814, 139259792, 42591881, 3458459159, 1085071860, 2349261162,
25575 3505103035, 474062885, 2463016902, 1583654744, 1419882049, 2550902495, 377792828, 3660491170,
25576 51297038, 3483679632, 1093385331, 2374089965, 2269427188, 1273935210, 3311514249, 164344343,
25577 2890961296, 1627033870, 4000683757, 585078387, 672833386, 3836780532, 1782552599, 2794821769,
25578 2142603813, 3005188795, 1032883544, 4047146438, 4227826911, 928351297, 3118105506, 1970307900,
25579 1396409818, 2677114180, 287212199, 3719594553, 3614542624, 467372990, 2505346141, 1509854403,
25580 2162073199, 1282711281, 3271268626, 240228748, 76845205, 3359543307, 1186043880, 2317064054,
25581 796964081, 3811226735, 1839575948, 2702160658, 2882189835, 1734392469, 3924802934, 625327592,
25582 4234522436, 818917338, 3191908409, 1927981223, 2016387518, 3028656416, 973776579, 4137723485,
25583 2857232268, 1726474002, 3899187441, 616751215, 772270454, 3803048424, 1814228491, 2693328533,
25584 2041117753, 3036871847, 999160644, 4146592730, 4259508931, 826864221, 3217552830, 1936586016,
25585 3606501031, 442291769, 2496909786, 1484378436, 1388107869, 2652297411, 278519584, 3694387134,
25586 85183762, 3384397196, 1194773103, 2342308593, 2170143720, 1307820918, 3279733909, 265733131,
25587 2057717559, 3054258089, 948125770, 4096344276, 4276898253, 843467091, 3167309488, 1885556270,
25588 2839764098, 1709792284, 3949353983, 667704161, 755585656, 3785577190, 1865176325, 2743489947,
25589 102594076, 3401021058, 1144549729, 2291298815, 2186770662, 1325234296, 3228729243, 215514885,
25590 3589828009, 424832311, 2547870420, 1534552650, 1370645331, 2635621325, 328688686, 3745342640,
25591 2211456353, 1333405183, 3254067740, 224338562, 127544219, 3408931589, 1170156774, 2299866232,
25592 1345666772, 2627681866, 303053225, 3736746295, 3565105198, 416624816, 2522494803, 1525692365,
25593 4285207626, 868291796, 3176010551, 1910772649, 2065767088, 3079346734, 956571085, 4121828691,
25594 747507711, 3760459617, 1856702594, 2717976604, 2831417605, 1684930971, 3940615800, 642451174,
25595 },
25596 {
25597 0, 393942083, 787884166, 965557445, 1575768332, 1251427663, 1931114890, 1684106697,
25598 3151536664, 2896410203, 2502855326, 2186649309, 3862229780, 4048545623, 3368213394, 3753496529,
25599 2898281073, 3149616690, 2184604407, 2504883892, 4046197629, 3864463166, 3755621371, 3366006712,
25600 387506281, 6550570, 971950319, 781573292, 1257550181, 1569695014, 1677892067, 1937345952,
25601 2196865699, 2508887776, 2886183461, 3145514598, 3743273903, 3362179052, 4058774313, 3868258154,
25602 958996667, 777139448, 400492605, 10755198, 1690661303, 1941857780, 1244879153, 1565019506,
25603 775012562, 961205393, 13101140, 398261271, 1943900638, 1688634781, 1563146584, 1246801179,
25604 2515100362, 2190636681, 3139390028, 2892258831, 3355784134, 3749586821, 3874691904, 4052225795,
25605 3734110983, 3387496260, 4033096577, 3877584834, 2206093835, 2483373640, 2911402637, 3136515790,
25606 1699389727, 1915860316, 1270647193, 1556585946, 950464531, 803071056, 374397077, 19647702,
25607 1917993334, 1697207605, 1554278896, 1272937907, 800985210, 952435769, 21510396, 372452543,
25608 3381322606, 3740399405, 3883715560, 4027047851, 2489758306, 2199758369, 3130039012, 2917895847,
25609 1550025124, 1259902439, 1922410786, 1710144865, 26202280, 385139947, 796522542, 939715693,
25610 3887801276, 4039129087, 3377269562, 3728088953, 3126293168, 2905368307, 2493602358, 2212122229,
25611 4037264341, 3889747862, 3730172755, 3375300368, 2907673305, 3124004506, 2209987167, 2495786524,
25612 1266377165, 1543533966, 1703758155, 1928748296, 379007169, 32253058, 945887303, 790236164,
25613 1716846671, 1898845196, 1218652361, 1608006794, 1002000707, 750929152, 357530053, 36990342,
25614 3717046871, 3405166100, 4084959953, 3825245842, 2153902939, 2535122712, 2929187805, 3119304606,
25615 3398779454, 3723384445, 3831720632, 4078468859, 2541294386, 2147616625, 3113171892, 2935238647,
25616 1900929062, 1714877541, 1606142112, 1220599011, 748794154, 1004184937, 39295404, 355241455,
25617 3835986668, 4091516591, 3394415210, 3710500393, 3108557792, 2922629027, 2545875814, 2160455461,
25618 1601970420, 1208431799, 1904871538, 1727077425, 43020792, 367748539, 744905086, 991776061,
25619 1214562461, 1595921630, 1720903707, 1911159896, 361271697, 49513938, 998160663, 738569556,
25620 4089209477, 3838277318, 3712633347, 3392233024, 2924491657, 3106613194, 2158369551, 2547846988,
25621 3100050248, 2948339467, 2519804878, 2169126797, 3844821572, 4065347079, 3420289730, 3701894785,
25622 52404560, 342144275, 770279894, 982687125, 1593045084, 1233708063, 1879431386, 1736363161,
25623 336019769, 58479994, 988899775, 764050940, 1240141877, 1586496630, 1729968307, 1885744368,
25624 2950685473, 3097818978, 2166999975, 2522013668, 4063474221, 3846743662, 3703937707, 3418263272,
25625 976650731, 760059304, 348170605, 62635310, 1742393575, 1889649828, 1227683937, 1582820386,
25626 2179867635, 2526361520, 2937588597, 3093503798, 3691148031, 3413731004, 4076100217, 3851374138,
25627 2532754330, 2173556697, 3087067932, 2944139103, 3407516310, 3697379029, 3857496592, 4070026835,
25628 758014338, 978679233, 64506116, 346250567, 1891774606, 1740186829, 1580472328, 1229917259,
25629 }, {
25630 0, 4022496062, 83218493, 3946298115, 166436986, 3861498692, 220098631, 3806075769,
25631 332873972, 4229245898, 388141257, 4175494135, 440197262, 4127099824, 516501683, 4044053389,
25632 665747944, 3362581206, 593187285, 3432594155, 776282514, 3246869164, 716239279, 3312622225,
25633 880394524, 3686509090, 814485793, 3746462239, 1033003366, 3528460888, 963096923, 3601193573,
25634 1331495888, 2694801646, 1269355501, 2758457555, 1186374570, 2843003028, 1111716759, 2910918825,
25635 1552565028, 3007850522, 1484755737, 3082680359, 1432478558, 3131279456, 1368666979, 3193329757,
25636 1760789048, 2268195078, 1812353541, 2210675003, 1628971586, 2396670332, 1710092927, 2318375233,
25637 2066006732, 2498144754, 2144408305, 2417195471, 1926193846, 2634877320, 1983558283, 2583222709,
25638 2662991776, 1903717534, 2588923805, 1972223139, 2538711002, 2022952164, 2477029351, 2087066841,
25639 2372749140, 1655647338, 2308478825, 1717238871, 2223433518, 1799654416, 2155034387, 1873894445,
25640 3105130056, 1456926070, 3185661557, 1378041163, 2969511474, 1597852940, 3020617231, 1539874097,
25641 2864957116, 1157737858, 2922780289, 1106542015, 2737333958, 1290407416, 2816325371, 1210047941,
25642 3521578096, 1042640718, 3574781005, 986759027, 3624707082, 936300340, 3707335735, 859512585,
25643 3257943172, 770846650, 3334837433, 688390023, 3420185854, 605654976, 3475911875, 552361981,
25644 4132013464, 428600998, 4072428965, 494812827, 4288816610, 274747100, 4216845791, 345349857,
25645 3852387692, 173846098, 3781891409, 245988975, 3967116566, 62328360, 3900749099, 121822741,
25646 3859089665, 164061759, 3807435068, 221426178, 4025395579, 2933317, 3944446278, 81334904,
25647 4124199413, 437265099, 4045904328, 518386422, 4231653775, 335250097, 4174133682, 386814604,
25648 3249244393, 778691543, 3311294676, 714879978, 3359647891, 662848429, 3434477742, 595039120,
25649 3531393053, 1035903779, 3599308832, 961245982, 3684132967, 877986649, 3747788890, 815846244,
25650 2841119441, 1184522735, 2913852140, 1114616274, 2696129195, 1332855189, 2756082326, 1266946472,
25651 3129952805, 1431118107, 3195705880, 1371074854, 3009735263, 1554415969, 3079748194, 1481855324,
25652 2398522169, 1630855175, 2315475716, 1707159610, 2266835779, 1759461501, 2213084030, 1814728768,
25653 2636237773, 1927520499, 2580814832, 1981182158, 2496293815, 2064121993, 2420095882, 2147340468,
25654 2025787041, 2541577631, 2085281436, 2475210146, 1901375195, 2660681189, 1973518054, 2590184920,
25655 1801997909, 2225743211, 1872600680, 2153772374, 1652813359, 2369881361, 1719025170, 2310296876,
25656 1594986313, 2966676599, 1541693300, 3022402634, 1459236659, 3107472397, 1376780046, 3184366640,
25657 1288097725, 2734990467, 1211309952, 2817619134, 1160605639, 2867791097, 1104723962, 2920993988,
25658 937561457, 3626001999, 857201996, 3704993394, 1040821515, 3519792693, 989625654, 3577615880,
25659 607473029, 3421972155, 549494200, 3473077894, 769584639, 3256649409, 690699714, 3337180924,
25660 273452185, 4287555495, 347692196, 4219156378, 430386403, 4133832669, 491977950, 4069562336,
25661 60542061, 3965298515, 124656720, 3903616878, 175139863, 3853649705, 243645482, 3779581716,
25662 }, {
25663 0, 3247366080, 1483520449, 2581751297, 2967040898, 1901571138, 3904227907, 691737987,
25664 3133399365, 2068659845, 3803142276, 589399876, 169513671, 3415493895, 1383475974, 2482566342,
25665 2935407819, 1870142219, 4137319690, 924099274, 506443593, 3751897225, 1178799752, 2278412616,
25666 339027342, 3585866318, 1280941135, 2379694991, 2766951948, 1700956620, 4236308429, 1024339981,
25667 2258407383, 1192382487, 3740284438, 528411094, 910556245, 4157285269, 1848198548, 2946996820,
25668 1012887186, 4258378066, 1681119059, 2780629139, 2357599504, 1292419792, 3572147409, 358906641,
25669 678054684, 3924071644, 1879503581, 2978491677, 2561882270, 1497229150, 3235873119, 22109855,
25670 2460592729, 1395094937, 3401913240, 189516888, 577821147, 3825075739, 2048679962, 3146956762,
25671 3595049455, 398902831, 2384764974, 1336573934, 1720805997, 2803873197, 1056822188, 4285729900,
25672 1821112490, 2902796138, 887570795, 4117339819, 3696397096, 500978920, 2218668777, 1169222953,
25673 2025774372, 3106931428, 550659301, 3780950821, 3362238118, 166293862, 2416645991, 1367722151,
25674 3262987361, 66315169, 2584839584, 1537170016, 1923370979, 3005911075, 717813282, 3947244002,
25675 1356109368, 2438613496, 146288633, 3375820857, 3759007162, 562248314, 3093388411, 2045739963,
25676 3927406461, 731490493, 2994458300, 1945440636, 1523451135, 2604718911, 44219710, 3274466046,
25677 4263662323, 1068272947, 2790189874, 1740649714, 1325080945, 2406874801, 379033776, 3608758128,
25678 1155642294, 2238671990, 479005303, 3708016055, 4097359924, 901128180, 2891217397, 1843045941,
25679 2011248031, 3060787807, 797805662, 3993195422, 3342353949, 112630237, 2673147868, 1591353372,
25680 3441611994, 212601626, 2504944923, 1421914843, 2113644376, 3161815192, 630660761, 3826893145,
25681 3642224980, 412692116, 2172340373, 1089836885, 1775141590, 2822790422, 832715543, 4029474007,
25682 1674842129, 2723860433, 1001957840, 4197873168, 3540870035, 310623315, 2338445906, 1257178514,
25683 4051548744, 821257608, 2836464521, 1755307081, 1101318602, 2150241802, 432566283, 3628511179,
25684 1270766349, 2318435533, 332587724, 3529260300, 4217841807, 988411727, 2735444302, 1652903566,
25685 1602977411, 2651169091, 132630338, 3328776322, 4015131905, 786223809, 3074340032, 1991273216,
25686 3846741958, 616972294, 3173262855, 2091579847, 1435626564, 2485072772, 234706309, 3430124101,
25687 2712218736, 1613231024, 4190475697, 944458353, 292577266, 3506339890, 1226630707, 2291284467,
25688 459984181, 3672380149, 1124496628, 2189994804, 2880683703, 1782407543, 4091479926, 844224694,
25689 257943739, 3469817723, 1462980986, 2529005242, 3213269817, 2114471161, 3890881272, 644152632,
25690 3046902270, 1947391550, 3991973951, 746483711, 88439420, 3301680572, 1563018173, 2628197501,
25691 657826727, 3871046759, 2136545894, 3201811878, 2548879397, 1449267173, 3481299428, 235845156,
25692 2650161890, 1551408418, 3315268387, 68429027, 758067552, 3970035360, 1967360161, 3033356129,
25693 2311284588, 1213053100, 3517963949, 270598509, 958010606, 4170500910, 1635167535, 2700636911,
25694 855672361, 4069415401, 1802256360, 2866995240, 2212099499, 1113008747, 3686091882, 440112042,
25695 }, {
25696 0, 2611301487, 3963330207, 2006897392, 50740095, 2560849680, 4013794784, 1956178319,
25697 101480190, 2645113489, 3929532513, 1905435662, 84561281, 2662269422, 3912356638, 1922342769,
25698 202960380, 2545787283, 3760419683, 2072395532, 253679235, 2495322860, 3810871324, 2021655667,
25699 169122562, 2444351341, 3861841309, 2106214898, 152215677, 2461527058, 3844685538, 2123133581,
25700 405920760, 2207553431, 4094313831, 1873742088, 456646791, 2157096168, 4144791064, 1823027831,
25701 507358470, 2241388905, 4060492697, 1772322806, 490444409, 2258557462, 4043311334, 1789215881,
25702 338245124, 2408348267, 4161972379, 1672996084, 388959611, 2357870868, 4212429796, 1622269835,
25703 304431354, 2306870421, 4263435877, 1706791434, 287538053, 2324051946, 4246267162, 1723705717,
25704 811841520, 2881944479, 3696765295, 1207788800, 862293135, 2831204576, 3747484176, 1157324415,
25705 913293582, 2915732833, 3662962577, 1106318334, 896137841, 2932651550, 3646055662, 1123494017,
25706 1014716940, 2816349795, 3493905555, 1273334012, 1065181555, 2765630748, 3544645612, 1222882179,
25707 980888818, 2714919069, 3595350637, 1307180546, 963712909, 2731826146, 3578431762, 1324336509,
25708 676490248, 3019317351, 3295277719, 1607253752, 726947703, 2968591128, 3345992168, 1556776327,
25709 777919222, 3053147801, 3261432937, 1505806342, 760750473, 3070062054, 3244539670, 1522987897,
25710 608862708, 3220163995, 3362856811, 1406423812, 659339915, 3169449700, 3413582868, 1355966587,
25711 575076106, 3118709605, 3464325525, 1440228858, 557894773, 3135602714, 3447411434, 1457397381,
25712 1623683040, 4217512847, 2365387135, 391757072, 1673614495, 4167309552, 2415577600, 341804655,
25713 1724586270, 4251866481, 2331019137, 290835438, 1707942497, 4268256782, 2314648830, 307490961,
25714 1826587164, 4152020595, 2162433155, 457265388, 1876539747, 4101829900, 2212636668, 407333779,
25715 1792275682, 4051089549, 2263378557, 491595282, 1775619997, 4067460082, 2246988034, 508239213,
25716 2029433880, 3813931127, 2496473735, 258500328, 2079362919, 3763716872, 2546668024, 208559511,
25717 2130363110, 3848244873, 2462145657, 157552662, 2113730969, 3864638966, 2445764358, 174205801,
25718 1961777636, 4014675339, 2564147067, 57707284, 2011718299, 3964481268, 2614361092, 7778411,
25719 1927425818, 3913769845, 2665066885, 92077546, 1910772837, 3930150922, 2648673018, 108709525,
25720 1352980496, 3405878399, 3164554895, 658115296, 1403183983, 3355946752, 3214507504, 607924639,
25721 1453895406, 3440239233, 3130208369, 557218846, 1437504913, 3456883198, 3113552654, 573589345,
25722 1555838444, 3340335491, 2961681267, 723707676, 1606028947, 3290383100, 3011612684, 673504355,
25723 1521500946, 3239382909, 3062619533, 758026722, 1505130605, 3256038402, 3045975794, 774417053,
25724 1217725416, 3543158663, 2762906999, 1057739032, 1267939479, 3493229816, 2812847624, 1007544935,
25725 1318679830, 3577493881, 2728586121, 956803046, 1302285929, 3594125830, 2711933174, 973184153,
25726 1150152212, 3743982203, 2830528651, 856898788, 1200346475, 3694041348, 2880457716, 806684571,
25727 1115789546, 3643069573, 2931426933, 891243034, 1099408277, 3659722746, 2914794762, 907637093,
25728 }, {
25729 0, 3717650821, 1616688459, 3184159950, 3233376918, 489665299, 2699419613, 2104690264,
25730 1510200173, 2274691816, 979330598, 3888758691, 2595928571, 1194090622, 4209380528, 661706037,
25731 3020400346, 1771143007, 3562738577, 164481556, 1958661196, 2837976521, 350386439, 3379863682,
25732 3993269687, 865250354, 2388181244, 1406015865, 784146209, 4079732388, 1323412074, 2474079215,
25733 3011398645, 1860735600, 3542286014, 246687547, 1942430051, 2924607718, 328963112, 3456978349,
25734 3917322392, 887832861, 2300653011, 1421341782, 700772878, 4099025803, 1234716485, 2483986112,
25735 125431087, 3673109674, 1730500708, 3132326369, 3351283641, 441867836, 2812031730, 2047535991,
25736 1568292418, 2163009479, 1025936137, 3769651852, 2646824148, 1079348561, 4255113631, 537475098,
25737 3180171691, 1612400686, 3721471200, 4717925, 2100624189, 2694980280, 493375094, 3237910515,
25738 3884860102, 974691139, 2278750093, 1514417672, 657926224, 4204917205, 1198234907, 2600289438,
25739 160053105, 3558665972, 1775665722, 3024116671, 3375586791, 346391650, 2842683564, 1962488105,
25740 1401545756, 2384412057, 869618007, 3997403346, 2469432970, 1319524111, 4083956673, 788193860,
25741 250862174, 3546612699, 1856990997, 3006903952, 3461001416, 333211981, 2920678787, 1937824774,
25742 1425017139, 2305216694, 883735672, 3912918525, 2487837605, 1239398944, 4095071982, 696455019,
25743 3136584836, 1734518017, 3668494799, 121507914, 2051872274, 2816200599, 437363545, 3347544796,
25744 3774328809, 1029797484, 2158697122, 1564328743, 542033279, 4258798842, 1074950196, 2642717105,
25745 2691310871, 2113731730, 3224801372, 497043929, 1624461185, 3175454212, 9435850, 3709412175,
25746 4201248378, 671035391, 2587181873, 1201904308, 986750188, 3880142185, 1519135143, 2266689570,
25747 342721485, 3388693064, 1949382278, 2846355203, 3570723163, 155332830, 3028835344, 1763607957,
25748 1315852448, 2482538789, 775087595, 4087626862, 2396469814, 1396827059, 4002123645, 857560824,
25749 320106210, 3464673127, 1934154665, 2933785132, 3551331444, 238804465, 3018961215, 1852270778,
25750 1226292623, 2491507722, 692783300, 4108177729, 2309936921, 1412959900, 3924976210, 879016919,
25751 2803091512, 2055541181, 3343875443, 450471158, 1739236014, 3124525867, 133568485, 3663777376,
25752 4245691221, 545702608, 2639048222, 1088059291, 1034514883, 3762268230, 1576387720, 2153979149,
25753 501724348, 3228659001, 2109407735, 2687359090, 3713981994, 13109167, 3171052385, 1620357860,
25754 1206151121, 2591211092, 666423962, 4197321503, 2271022407, 1523307714, 3875649548, 982999433,
25755 2850034278, 1953942499, 3384583981, 338329256, 1767471344, 3033506165, 151375291, 3566408766,
25756 4091789579, 779425934, 2478797888, 1311354309, 861580189, 4006375960, 1392910038, 2391852883,
25757 2929327945, 1930372812, 3469036034, 324244359, 1847629279, 3015068762, 243015828, 3555391761,
25758 4103744548, 688715169, 2496043375, 1229996266, 874727090, 3920994103, 1417671673, 2313759356,
25759 446585235, 3339223062, 2059594968, 2807313757, 3660002053, 129100416, 3128657486, 1743609803,
25760 1084066558, 2634765179, 549535669, 4250396208, 2149900392, 1571961325, 3765982499, 1039043750,
25761 }, {
25762 0, 2635063670, 3782132909, 2086741467, 430739227, 2225303149, 4173482934, 1707977408,
25763 861478454, 2924937024, 3526875803, 1329085421, 720736557, 3086643291, 3415954816, 1452586230,
25764 1722956908, 4223524122, 2279405761, 450042295, 2132718455, 3792785921, 2658170842, 58693292,
25765 1441473114, 3370435372, 3028674295, 696911745, 1279765825, 3511176247, 2905172460, 807831706,
25766 3445913816, 1349228974, 738901109, 2969918723, 3569940419, 1237784245, 900084590, 2829701656,
25767 4265436910, 1664255896, 525574723, 2187084597, 3885099509, 2057177219, 117386584, 2616249390,
25768 2882946228, 920233410, 1253605401, 3619119471, 2994391983, 796207833, 1393823490, 3457937012,
25769 2559531650, 92322804, 2044829231, 3840835417, 2166609305, 472659183, 1615663412, 4249022530,
25770 1102706673, 3702920839, 2698457948, 1037619754, 1477802218, 3306854812, 3111894087, 611605809,
25771 1927342535, 4025419953, 2475568490, 243387420, 1800169180, 4131620778, 2317525617, 388842247,
25772 655084445, 3120835307, 3328511792, 1533734470, 1051149446, 2745738736, 3754524715, 1120297309,
25773 340972971, 2304586973, 4114354438, 1748234352, 234773168, 2431761350, 3968900637, 1906278251,
25774 2363330345, 299003487, 1840466820, 4038896370, 2507210802, 142532932, 1948239007, 3910149609,
25775 3213136159, 579563625, 1592415666, 3286611140, 2787646980, 992477042, 1195825833, 3662232543,
25776 3933188933, 2002801203, 184645608, 2517538462, 4089658462, 1858919720, 313391347, 2409765253,
25777 3644239219, 1144605701, 945318366, 2773977256, 3231326824, 1570095902, 569697989, 3170568115,
25778 2205413346, 511446676, 1646078799, 4279421497, 2598330617, 131105167, 2075239508, 3871229218,
25779 2955604436, 757403810, 1363424633, 3427521551, 2844163791, 881434553, 1223211618, 3588709140,
25780 3854685070, 2026779384, 78583587, 2577462869, 4235025557, 1633861091, 486774840, 2148301134,
25781 3600338360, 1268198606, 938871061, 2868504675, 3476308643, 1379640277, 777684494, 3008718712,
25782 1310168890, 3541595724, 2943964055, 846639841, 1471879201, 3400857943, 3067468940, 735723002,
25783 2102298892, 3762382970, 2619362721, 19901655, 1692534295, 4193118049, 2240594618, 411247564,
25784 681945942, 3047836192, 3385552891, 1422167693, 822682701, 2886124859, 3496468704, 1298661782,
25785 469546336, 2264093718, 4203901389, 1738379451, 38812283, 2673859341, 3812556502, 2117148576,
25786 3268024339, 1606809957, 598006974, 3198893512, 3680933640, 1181316734, 973624229, 2802299603,
25787 4052944421, 1822222163, 285065864, 2381456382, 3896478014, 1966106696, 156323219, 2489232613,
25788 2759337087, 964150537, 1159127250, 3625517476, 3184831332, 551242258, 1555722185, 3249901247,
25789 2535537225, 170842943, 1984954084, 3946848146, 2391651666, 327308324, 1877176831, 4075589769,
25790 263086283, 2460058045, 4005602406, 1942963472, 369291216, 2332888742, 4151061373, 1784924683,
25791 1022852861, 2717425547, 3717839440, 1083595558, 626782694, 3092517008, 3291821387, 1497027645,
25792 1763466407, 4094934481, 2289211402, 360544636, 1890636732, 3988730570, 2447251217, 215086695,
25793 1514488465, 3343557607, 3140191804, 639919946, 1139395978, 3739626748, 2726758695, 1065936977,
25794 }, {
25795 0, 3120290792, 2827399569, 293431929, 2323408227, 864534155, 586863858, 2600537882,
25796 3481914503, 1987188591, 1729068310, 3740575486, 1173727716, 4228805132, 3983743093, 1418249117,
25797 1147313999, 4254680231, 3974377182, 1428157750, 3458136620, 2011505092, 1721256893, 3747844181,
25798 2347455432, 839944224, 594403929, 2593536433, 26687147, 3094146371, 2836498234, 283794642,
25799 2294627998, 826205558, 541298447, 2578994407, 45702141, 3141697557, 2856315500, 331624836,
25800 1196225049, 4273416689, 4023010184, 1446090848, 3442513786, 1959480466, 1706436331, 3696098563,
25801 3433538001, 1968994873, 1679888448, 3722103720, 1188807858, 4280295258, 3999102243, 1470541515,
25802 53374294, 3134568126, 2879970503, 307431215, 2303854645, 816436189, 567589284, 2553242188,
25803 3405478781, 1929420949, 1652411116, 3682996484, 1082596894, 4185703926, 3892424591, 1375368295,
25804 91404282, 3163122706, 2918450795, 336584067, 2400113305, 922028401, 663249672, 2658384096,
25805 2392450098, 929185754, 639587747, 2682555979, 82149713, 3172883129, 2892181696, 362343208,
25806 1091578037, 4176212829, 3918960932, 1349337804, 3412872662, 1922537022, 1676344391, 3658557359,
25807 1111377379, 4224032267, 3937989746, 1396912026, 3359776896, 1908013928, 1623494929, 3644803833,
25808 2377615716, 877417100, 623982837, 2630542109, 130804743, 3190831087, 2941083030, 381060734,
25809 106748588, 3215393092, 2933549885, 388083925, 2350956495, 903570471, 614862430, 2640172470,
25810 3386185259, 1882115523, 1632872378, 3634920530, 1135178568, 4199721120, 3945775833, 1389631793,
25811 1317531835, 4152109907, 3858841898, 1610259138, 3304822232, 2097172016, 1820140617, 3582394273,
25812 2165193788, 955639764, 696815021, 2423477829, 192043359, 2995356343, 2750736590, 437203750,
25813 182808564, 3005133852, 2724453989, 462947725, 2157513367, 962777471, 673168134, 2447663342,
25814 3312231283, 2090301595, 1844056802, 3557935370, 1326499344, 4142603768, 3885397889, 1584245865,
25815 3326266917, 2142836173, 1858371508, 3611272284, 1279175494, 4123357358, 3837270743, 1564721471,
25816 164299426, 2955991370, 2706223923, 414607579, 2209834945, 978107433, 724686416, 2462715320,
25817 2183156074, 1004243586, 715579643, 2472360723, 140260361, 2980573153, 2698675608, 421617264,
25818 1302961645, 4099032581, 3845074044, 1557460884, 3352688782, 2116952934, 1867729183, 3601371895,
25819 2222754758, 1032278062, 754596439, 2499928511, 234942117, 3086693709, 2793824052, 528319708,
25820 1274365761, 4061043881, 3816027856, 1518873912, 3246989858, 2020800970, 1762628531, 3505670235,
25821 3223196809, 2045103969, 1754834200, 3512958704, 1247965674, 4086934018, 3806642299, 1528765331,
25822 261609486, 3060532198, 2802936223, 518697591, 2246819181, 1007707781, 762121468, 2492913428,
25823 213497176, 3041029808, 2755593417, 499441441, 2261110843, 1061030867, 776167850, 2545465922,
25824 3274734047, 2060165687, 1807140942, 3528266662, 1229724860, 4038575956, 3788156205, 1479636677,
25825 1222322711, 4045468159, 3764231046, 1504067694, 3265744756, 2069664924, 1780612837, 3554288909,
25826 2270357136, 1051278712, 802445057, 2519698665, 221152243, 3033880603, 2779263586, 475261322,
25827 }, {
25828 0, 2926088593, 2275419491, 701019378, 3560000647, 2052709654, 1402038756, 4261017717,
25829 1930665807, 3715829470, 4105419308, 1524313021, 2804077512, 155861593, 545453739, 2397726522,
25830 3861331614, 1213181711, 1636244477, 3488582252, 840331801, 2625561480, 3048626042, 467584747,
25831 2503254481, 995897408, 311723186, 3170637091, 1090907478, 4016929991, 3332753461, 1758288292,
25832 390036349, 3109546732, 2426363422, 1056427919, 3272488954, 1835443819, 1152258713, 3938878216,
25833 1680663602, 3393484195, 3817652561, 1306808512, 2954733749, 510998820, 935169494, 2580880455,
25834 4044899811, 1601229938, 1991794816, 3637571857, 623446372, 2336332021, 2726898695, 216120726,
25835 2181814956, 744704829, 95158223, 2881711710, 1446680107, 4166125498, 3516576584, 2146575065,
25836 780072698, 2148951915, 2849952665, 129384968, 4199529085, 1411853292, 2112855838, 3548843663,
25837 1567451573, 4077254692, 3670887638, 1957027143, 2304517426, 657765539, 251396177, 2694091200,
25838 3361327204, 1714510325, 1341779207, 3784408214, 476611811, 2986349938, 2613617024, 899690513,
25839 3142211371, 354600634, 1021997640, 2458051545, 1870338988, 3239283261, 3906682575, 1186180958,
25840 960597383, 2536053782, 3202459876, 277428597, 3983589632, 1125666961, 1792074851, 3300423154,
25841 1246892744, 3829039961, 3455203243, 1671079482, 2657312335, 806080478, 432241452, 3081497277,
25842 3748049689, 1896751752, 1489409658, 4138600427, 190316446, 2772397583, 2365053693, 580864876,
25843 2893360214, 35503559, 735381813, 2243795108, 2017747153, 3593269568, 4293150130, 1368183843,
25844 1560145396, 4069882981, 3680356503, 1966430470, 2295112051, 648294626, 258769936, 2701399425,
25845 804156091, 2173100842, 2823706584, 103204425, 4225711676, 1438101421, 2088704863, 3524758222,
25846 3134903146, 347226875, 1031468553, 2467456920, 1860935661, 3229814396, 3914054286, 1193487135,
25847 3385412645, 1738661300, 1315531078, 3758225623, 502792354, 3012596019, 2589468097, 875607120,
25848 1271043721, 3853125400, 3429020650, 1644831355, 2683558414, 832261023, 408158061, 3057348348,
25849 953223622, 2528745559, 3211865253, 286899508, 3974120769, 1116263632, 1799381026, 3307794867,
25850 2917509143, 59586950, 709201268, 2217549029, 2043995280, 3619452161, 4269064691, 1344032866,
25851 3740677976, 1889445577, 1498812987, 4148069290, 180845535, 2762992206, 2372361916, 588238637,
25852 1921194766, 3706423967, 4112727661, 1531686908, 2796705673, 148555288, 554857194, 2407195515,
25853 26248257, 2952271312, 2251333922, 676868275, 3584149702, 2076793175, 1375858085, 4234771508,
25854 2493785488, 986493953, 319029491, 3178008930, 1083533591, 4009621638, 3342158964, 1767759333,
25855 3887577823, 1239362382, 1612160956, 3464433197, 864482904, 2649647049, 3022443323, 441336490,
25856 1706844275, 3419730402, 3793503504, 1282724993, 2978819316, 535149925, 908921239, 2554697734,
25857 380632892, 3100077741, 2433735263, 1063734222, 3265180603, 1828069930, 1161729752, 3948283721,
25858 2207997677, 770953084, 71007118, 2857626143, 1470763626, 4190274555, 3490330377, 2120394392,
25859 4035494306, 1591758899, 1999168705, 3644880208, 616140069, 2328960180, 2736367686, 225524183,
25860 },
25861 };
25862
25863 static const uint8_t
25864 WUFFS_CRC32__IEEE_X86_SSE42_K1K2[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25865 212, 43, 68, 84, 1, 0, 0, 0,
25866 150, 21, 228, 198, 1, 0, 0, 0,
25867 };
25868
25869 static const uint8_t
25870 WUFFS_CRC32__IEEE_X86_SSE42_K3K4[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25871 208, 151, 25, 117, 1, 0, 0, 0,
25872 158, 0, 170, 204, 0, 0, 0, 0,
25873 };
25874
25875 static const uint8_t
25876 WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25877 36, 97, 205, 99, 1, 0, 0, 0,
25878 0, 0, 0, 0, 0, 0, 0, 0,
25879 };
25880
25881 static const uint8_t
25882 WUFFS_CRC32__IEEE_X86_SSE42_PXMU[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
25883 65, 6, 113, 219, 1, 0, 0, 0,
25884 65, 22, 1, 247, 1, 0, 0, 0,
25885 };
25886
25887 // ---------------- Private Initializer Prototypes
25888
25889 // ---------------- Private Function Prototypes
25890
25891 static wuffs_base__empty_struct
25892 wuffs_crc32__ieee_hasher__up(
25893 wuffs_crc32__ieee_hasher* self,
25894 wuffs_base__slice_u8 a_x);
25895
25896 static wuffs_base__empty_struct
25897 wuffs_crc32__ieee_hasher__up__choosy_default(
25898 wuffs_crc32__ieee_hasher* self,
25899 wuffs_base__slice_u8 a_x);
25900
25901 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25902 static wuffs_base__empty_struct
25903 wuffs_crc32__ieee_hasher__up_arm_crc32(
25904 wuffs_crc32__ieee_hasher* self,
25905 wuffs_base__slice_u8 a_x);
25906 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
25907
25908 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25909 static wuffs_base__empty_struct
25910 wuffs_crc32__ieee_hasher__up_x86_avx2(
25911 wuffs_crc32__ieee_hasher* self,
25912 wuffs_base__slice_u8 a_x);
25913 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25914
25915 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25916 static wuffs_base__empty_struct
25917 wuffs_crc32__ieee_hasher__up_x86_sse42(
25918 wuffs_crc32__ieee_hasher* self,
25919 wuffs_base__slice_u8 a_x);
25920 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
25921
25922 // ---------------- VTables
25923
25924 const wuffs_base__hasher_u32__func_ptrs
25925 wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
25926 (wuffs_base__empty_struct(*)(void*,
25927 uint32_t,
25928 bool))(&wuffs_crc32__ieee_hasher__set_quirk_enabled),
25929 (uint32_t(*)(void*,
25930 wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32),
25931 };
25932
25933 // ---------------- Initializer Implementations
25934
25935 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_crc32__ieee_hasher__initialize(wuffs_crc32__ieee_hasher * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)25936 wuffs_crc32__ieee_hasher__initialize(
25937 wuffs_crc32__ieee_hasher* self,
25938 size_t sizeof_star_self,
25939 uint64_t wuffs_version,
25940 uint32_t options){
25941 if (!self) {
25942 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
25943 }
25944 if (sizeof(*self) != sizeof_star_self) {
25945 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
25946 }
25947 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
25948 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
25949 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
25950 }
25951
25952 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
25953 // The whole point of this if-check is to detect an uninitialized *self.
25954 // We disable the warning on GCC. Clang-5.0 does not have this warning.
25955 #if !defined(__clang__) && defined(__GNUC__)
25956 #pragma GCC diagnostic push
25957 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
25958 #endif
25959 if (self->private_impl.magic != 0) {
25960 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
25961 }
25962 #if !defined(__clang__) && defined(__GNUC__)
25963 #pragma GCC diagnostic pop
25964 #endif
25965 } else {
25966 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
25967 memset(self, 0, sizeof(*self));
25968 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
25969 } else {
25970 memset(&(self->private_impl), 0, sizeof(self->private_impl));
25971 }
25972 }
25973
25974 self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default;
25975
25976 self->private_impl.magic = WUFFS_BASE__MAGIC;
25977 self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
25978 wuffs_base__hasher_u32__vtable_name;
25979 self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
25980 (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32);
25981 return wuffs_base__make_status(NULL);
25982 }
25983
25984 wuffs_crc32__ieee_hasher*
wuffs_crc32__ieee_hasher__alloc()25985 wuffs_crc32__ieee_hasher__alloc() {
25986 wuffs_crc32__ieee_hasher* x =
25987 (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
25988 if (!x) {
25989 return NULL;
25990 }
25991 if (wuffs_crc32__ieee_hasher__initialize(
25992 x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
25993 free(x);
25994 return NULL;
25995 }
25996 return x;
25997 }
25998
25999 size_t
sizeof__wuffs_crc32__ieee_hasher()26000 sizeof__wuffs_crc32__ieee_hasher() {
26001 return sizeof(wuffs_crc32__ieee_hasher);
26002 }
26003
26004 // ---------------- Function Implementations
26005
26006 // -------- func crc32.ieee_hasher.set_quirk_enabled
26007
26008 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__set_quirk_enabled(wuffs_crc32__ieee_hasher * self,uint32_t a_quirk,bool a_enabled)26009 wuffs_crc32__ieee_hasher__set_quirk_enabled(
26010 wuffs_crc32__ieee_hasher* self,
26011 uint32_t a_quirk,
26012 bool a_enabled) {
26013 return wuffs_base__make_empty_struct();
26014 }
26015
26016 // -------- func crc32.ieee_hasher.update_u32
26017
26018 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_crc32__ieee_hasher__update_u32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26019 wuffs_crc32__ieee_hasher__update_u32(
26020 wuffs_crc32__ieee_hasher* self,
26021 wuffs_base__slice_u8 a_x) {
26022 if (!self) {
26023 return 0;
26024 }
26025 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26026 return 0;
26027 }
26028
26029 if (self->private_impl.f_state == 0) {
26030 self->private_impl.choosy_up = (
26031 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
26032 wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 :
26033 #endif
26034 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26035 wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_crc32__ieee_hasher__up_x86_avx2 :
26036 #endif
26037 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26038 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 :
26039 #endif
26040 self->private_impl.choosy_up);
26041 }
26042 wuffs_crc32__ieee_hasher__up(self, a_x);
26043 return self->private_impl.f_state;
26044 }
26045
26046 // -------- func crc32.ieee_hasher.up
26047
26048 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26049 wuffs_crc32__ieee_hasher__up(
26050 wuffs_crc32__ieee_hasher* self,
26051 wuffs_base__slice_u8 a_x) {
26052 return (*self->private_impl.choosy_up)(self, a_x);
26053 }
26054
26055 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up__choosy_default(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26056 wuffs_crc32__ieee_hasher__up__choosy_default(
26057 wuffs_crc32__ieee_hasher* self,
26058 wuffs_base__slice_u8 a_x) {
26059 uint32_t v_s = 0;
26060 wuffs_base__slice_u8 v_p = {0};
26061
26062 v_s = (4294967295 ^ self->private_impl.f_state);
26063 {
26064 wuffs_base__slice_u8 i_slice_p = a_x;
26065 v_p.ptr = i_slice_p.ptr;
26066 v_p.len = 16;
26067 uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
26068 while (v_p.ptr < i_end0_p) {
26069 v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
26070 (((uint32_t)(v_p.ptr[1])) << 8) |
26071 (((uint32_t)(v_p.ptr[2])) << 16) |
26072 (((uint32_t)(v_p.ptr[3])) << 24));
26073 v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
26074 WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
26075 WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
26076 WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
26077 WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
26078 WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
26079 WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
26080 WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
26081 WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
26082 WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
26083 WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
26084 WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
26085 WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
26086 WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
26087 WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
26088 WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
26089 v_p.ptr += 16;
26090 v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
26091 (((uint32_t)(v_p.ptr[1])) << 8) |
26092 (((uint32_t)(v_p.ptr[2])) << 16) |
26093 (((uint32_t)(v_p.ptr[3])) << 24));
26094 v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
26095 WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
26096 WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
26097 WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
26098 WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
26099 WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
26100 WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
26101 WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
26102 WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
26103 WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
26104 WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
26105 WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
26106 WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
26107 WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
26108 WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
26109 WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
26110 v_p.ptr += 16;
26111 }
26112 v_p.len = 16;
26113 uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16);
26114 while (v_p.ptr < i_end1_p) {
26115 v_s ^= ((((uint32_t)(v_p.ptr[0])) << 0) |
26116 (((uint32_t)(v_p.ptr[1])) << 8) |
26117 (((uint32_t)(v_p.ptr[2])) << 16) |
26118 (((uint32_t)(v_p.ptr[3])) << 24));
26119 v_s = (WUFFS_CRC32__IEEE_TABLE[0][v_p.ptr[15]] ^
26120 WUFFS_CRC32__IEEE_TABLE[1][v_p.ptr[14]] ^
26121 WUFFS_CRC32__IEEE_TABLE[2][v_p.ptr[13]] ^
26122 WUFFS_CRC32__IEEE_TABLE[3][v_p.ptr[12]] ^
26123 WUFFS_CRC32__IEEE_TABLE[4][v_p.ptr[11]] ^
26124 WUFFS_CRC32__IEEE_TABLE[5][v_p.ptr[10]] ^
26125 WUFFS_CRC32__IEEE_TABLE[6][v_p.ptr[9]] ^
26126 WUFFS_CRC32__IEEE_TABLE[7][v_p.ptr[8]] ^
26127 WUFFS_CRC32__IEEE_TABLE[8][v_p.ptr[7]] ^
26128 WUFFS_CRC32__IEEE_TABLE[9][v_p.ptr[6]] ^
26129 WUFFS_CRC32__IEEE_TABLE[10][v_p.ptr[5]] ^
26130 WUFFS_CRC32__IEEE_TABLE[11][v_p.ptr[4]] ^
26131 WUFFS_CRC32__IEEE_TABLE[12][(255 & (v_s >> 24))] ^
26132 WUFFS_CRC32__IEEE_TABLE[13][(255 & (v_s >> 16))] ^
26133 WUFFS_CRC32__IEEE_TABLE[14][(255 & (v_s >> 8))] ^
26134 WUFFS_CRC32__IEEE_TABLE[15][(255 & (v_s >> 0))]);
26135 v_p.ptr += 16;
26136 }
26137 v_p.len = 1;
26138 uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
26139 while (v_p.ptr < i_end2_p) {
26140 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26141 v_p.ptr += 1;
26142 }
26143 v_p.len = 0;
26144 }
26145 self->private_impl.f_state = (4294967295 ^ v_s);
26146 return wuffs_base__make_empty_struct();
26147 }
26148
26149 // ‼ WUFFS MULTI-FILE SECTION +arm_crc32
26150 // -------- func crc32.ieee_hasher.up_arm_crc32
26151
26152 #if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
26153 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_arm_crc32(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26154 wuffs_crc32__ieee_hasher__up_arm_crc32(
26155 wuffs_crc32__ieee_hasher* self,
26156 wuffs_base__slice_u8 a_x) {
26157 wuffs_base__slice_u8 v_p = {0};
26158 uint32_t v_s = 0;
26159
26160 v_s = (4294967295 ^ self->private_impl.f_state);
26161 while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
26162 v_s = __crc32b(v_s, a_x.ptr[0]);
26163 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
26164 }
26165 {
26166 wuffs_base__slice_u8 i_slice_p = a_x;
26167 v_p.ptr = i_slice_p.ptr;
26168 v_p.len = 8;
26169 uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128);
26170 while (v_p.ptr < i_end0_p) {
26171 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26172 v_p.ptr += 8;
26173 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26174 v_p.ptr += 8;
26175 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26176 v_p.ptr += 8;
26177 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26178 v_p.ptr += 8;
26179 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26180 v_p.ptr += 8;
26181 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26182 v_p.ptr += 8;
26183 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26184 v_p.ptr += 8;
26185 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26186 v_p.ptr += 8;
26187 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26188 v_p.ptr += 8;
26189 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26190 v_p.ptr += 8;
26191 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26192 v_p.ptr += 8;
26193 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26194 v_p.ptr += 8;
26195 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26196 v_p.ptr += 8;
26197 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26198 v_p.ptr += 8;
26199 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26200 v_p.ptr += 8;
26201 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26202 v_p.ptr += 8;
26203 }
26204 v_p.len = 8;
26205 uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
26206 while (v_p.ptr < i_end1_p) {
26207 v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
26208 v_p.ptr += 8;
26209 }
26210 v_p.len = 1;
26211 uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
26212 while (v_p.ptr < i_end2_p) {
26213 v_s = __crc32b(v_s, v_p.ptr[0]);
26214 v_p.ptr += 1;
26215 }
26216 v_p.len = 0;
26217 }
26218 self->private_impl.f_state = (4294967295 ^ v_s);
26219 return wuffs_base__make_empty_struct();
26220 }
26221 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
26222 // ‼ WUFFS MULTI-FILE SECTION -arm_crc32
26223
26224 // ‼ WUFFS MULTI-FILE SECTION +x86_avx2
26225 // -------- func crc32.ieee_hasher.up_x86_avx2
26226
26227 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26228 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
26229 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_avx2(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26230 wuffs_crc32__ieee_hasher__up_x86_avx2(
26231 wuffs_crc32__ieee_hasher* self,
26232 wuffs_base__slice_u8 a_x) {
26233 uint32_t v_s = 0;
26234 wuffs_base__slice_u8 v_p = {0};
26235 __m128i v_k = {0};
26236 __m128i v_x0 = {0};
26237 __m128i v_x1 = {0};
26238 __m128i v_x2 = {0};
26239 __m128i v_x3 = {0};
26240 __m128i v_y0 = {0};
26241 __m128i v_y1 = {0};
26242 __m128i v_y2 = {0};
26243 __m128i v_y3 = {0};
26244 uint64_t v_tail_index = 0;
26245
26246 v_s = (4294967295 ^ self->private_impl.f_state);
26247 while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
26248 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ a_x.ptr[0])] ^ (v_s >> 8));
26249 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
26250 }
26251 if (((uint64_t)(a_x.len)) < 64) {
26252 {
26253 wuffs_base__slice_u8 i_slice_p = a_x;
26254 v_p.ptr = i_slice_p.ptr;
26255 v_p.len = 1;
26256 uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26257 while (v_p.ptr < i_end0_p) {
26258 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26259 v_p.ptr += 1;
26260 }
26261 v_p.len = 0;
26262 }
26263 self->private_impl.f_state = (4294967295 ^ v_s);
26264 return wuffs_base__make_empty_struct();
26265 }
26266 v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0));
26267 v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16));
26268 v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32));
26269 v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48));
26270 v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
26271 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
26272 {
26273 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64);
26274 v_p.ptr = i_slice_p.ptr;
26275 v_p.len = 64;
26276 uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
26277 while (v_p.ptr < i_end0_p) {
26278 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26279 v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26280 v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0));
26281 v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0));
26282 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26283 v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17));
26284 v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17));
26285 v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17));
26286 v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0)));
26287 v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16)));
26288 v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32)));
26289 v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48)));
26290 v_p.ptr += 64;
26291 }
26292 v_p.len = 0;
26293 }
26294 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
26295 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26296 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26297 v_x0 = _mm_xor_si128(v_x0, v_x1);
26298 v_x0 = _mm_xor_si128(v_x0, v_y0);
26299 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26300 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26301 v_x0 = _mm_xor_si128(v_x0, v_x2);
26302 v_x0 = _mm_xor_si128(v_x0, v_y0);
26303 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26304 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26305 v_x0 = _mm_xor_si128(v_x0, v_x3);
26306 v_x0 = _mm_xor_si128(v_x0, v_y0);
26307 v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16));
26308 v_x2 = _mm_set_epi32((int32_t)(0), (int32_t)(4294967295), (int32_t)(0), (int32_t)(4294967295));
26309 v_x0 = _mm_srli_si128(v_x0, (int32_t)(8));
26310 v_x0 = _mm_xor_si128(v_x0, v_x1);
26311 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
26312 v_x1 = _mm_srli_si128(v_x0, (int32_t)(4));
26313 v_x0 = _mm_and_si128(v_x0, v_x2);
26314 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26315 v_x0 = _mm_xor_si128(v_x0, v_x1);
26316 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
26317 v_x1 = _mm_and_si128(v_x0, v_x2);
26318 v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16));
26319 v_x1 = _mm_and_si128(v_x1, v_x2);
26320 v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26321 v_x0 = _mm_xor_si128(v_x0, v_x1);
26322 v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1))));
26323 v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
26324 if (v_tail_index < ((uint64_t)(a_x.len))) {
26325 {
26326 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
26327 v_p.ptr = i_slice_p.ptr;
26328 v_p.len = 1;
26329 uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26330 while (v_p.ptr < i_end0_p) {
26331 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26332 v_p.ptr += 1;
26333 }
26334 v_p.len = 0;
26335 }
26336 }
26337 self->private_impl.f_state = (4294967295 ^ v_s);
26338 return wuffs_base__make_empty_struct();
26339 }
26340 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26341 // ‼ WUFFS MULTI-FILE SECTION -x86_avx2
26342
26343 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
26344 // -------- func crc32.ieee_hasher.up_x86_sse42
26345
26346 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26347 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
26348 static wuffs_base__empty_struct
wuffs_crc32__ieee_hasher__up_x86_sse42(wuffs_crc32__ieee_hasher * self,wuffs_base__slice_u8 a_x)26349 wuffs_crc32__ieee_hasher__up_x86_sse42(
26350 wuffs_crc32__ieee_hasher* self,
26351 wuffs_base__slice_u8 a_x) {
26352 uint32_t v_s = 0;
26353 wuffs_base__slice_u8 v_p = {0};
26354 __m128i v_k = {0};
26355 __m128i v_x0 = {0};
26356 __m128i v_x1 = {0};
26357 __m128i v_x2 = {0};
26358 __m128i v_x3 = {0};
26359 __m128i v_y0 = {0};
26360 __m128i v_y1 = {0};
26361 __m128i v_y2 = {0};
26362 __m128i v_y3 = {0};
26363 uint64_t v_tail_index = 0;
26364
26365 v_s = (4294967295 ^ self->private_impl.f_state);
26366 while ((((uint64_t)(a_x.len)) > 0) && ((15 & ((uint32_t)(0xFFF & (uintptr_t)(a_x.ptr)))) != 0)) {
26367 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ a_x.ptr[0])] ^ (v_s >> 8));
26368 a_x = wuffs_base__slice_u8__subslice_i(a_x, 1);
26369 }
26370 if (((uint64_t)(a_x.len)) < 64) {
26371 {
26372 wuffs_base__slice_u8 i_slice_p = a_x;
26373 v_p.ptr = i_slice_p.ptr;
26374 v_p.len = 1;
26375 uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26376 while (v_p.ptr < i_end0_p) {
26377 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26378 v_p.ptr += 1;
26379 }
26380 v_p.len = 0;
26381 }
26382 self->private_impl.f_state = (4294967295 ^ v_s);
26383 return wuffs_base__make_empty_struct();
26384 }
26385 v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0));
26386 v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16));
26387 v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32));
26388 v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48));
26389 v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
26390 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
26391 {
26392 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64);
26393 v_p.ptr = i_slice_p.ptr;
26394 v_p.len = 64;
26395 uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
26396 while (v_p.ptr < i_end0_p) {
26397 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26398 v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26399 v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0));
26400 v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0));
26401 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26402 v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17));
26403 v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17));
26404 v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17));
26405 v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0)));
26406 v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16)));
26407 v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32)));
26408 v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48)));
26409 v_p.ptr += 64;
26410 }
26411 v_p.len = 0;
26412 }
26413 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
26414 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26415 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26416 v_x0 = _mm_xor_si128(v_x0, v_x1);
26417 v_x0 = _mm_xor_si128(v_x0, v_y0);
26418 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26419 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26420 v_x0 = _mm_xor_si128(v_x0, v_x2);
26421 v_x0 = _mm_xor_si128(v_x0, v_y0);
26422 v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26423 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17));
26424 v_x0 = _mm_xor_si128(v_x0, v_x3);
26425 v_x0 = _mm_xor_si128(v_x0, v_y0);
26426 v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16));
26427 v_x2 = _mm_set_epi32((int32_t)(0), (int32_t)(4294967295), (int32_t)(0), (int32_t)(4294967295));
26428 v_x0 = _mm_srli_si128(v_x0, (int32_t)(8));
26429 v_x0 = _mm_xor_si128(v_x0, v_x1);
26430 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
26431 v_x1 = _mm_srli_si128(v_x0, (int32_t)(4));
26432 v_x0 = _mm_and_si128(v_x0, v_x2);
26433 v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0));
26434 v_x0 = _mm_xor_si128(v_x0, v_x1);
26435 v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
26436 v_x1 = _mm_and_si128(v_x0, v_x2);
26437 v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16));
26438 v_x1 = _mm_and_si128(v_x1, v_x2);
26439 v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0));
26440 v_x0 = _mm_xor_si128(v_x0, v_x1);
26441 v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1))));
26442 v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
26443 if (v_tail_index < ((uint64_t)(a_x.len))) {
26444 {
26445 wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
26446 v_p.ptr = i_slice_p.ptr;
26447 v_p.len = 1;
26448 uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
26449 while (v_p.ptr < i_end0_p) {
26450 v_s = (WUFFS_CRC32__IEEE_TABLE[0][(((uint8_t)((v_s & 255))) ^ v_p.ptr[0])] ^ (v_s >> 8));
26451 v_p.ptr += 1;
26452 }
26453 v_p.len = 0;
26454 }
26455 }
26456 self->private_impl.f_state = (4294967295 ^ v_s);
26457 return wuffs_base__make_empty_struct();
26458 }
26459 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26460 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
26461
26462 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
26463
26464 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
26465
26466 // ---------------- Status Codes Implementations
26467
26468 const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)";
26469 const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)";
26470 const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count";
26471 const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition";
26472 const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code";
26473 const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length";
26474 const char wuffs_deflate__error__bad_block[] = "#deflate: bad block";
26475 const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance";
26476 const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count";
26477 const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count";
26478 const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length";
26479 const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code";
26480 const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes";
26481 const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state";
26482 const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O";
26483 const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance";
26484 const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits";
26485
26486 // ---------------- Private Consts
26487
26488 static const uint8_t
26489 WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = {
26490 16, 17, 18, 0, 8, 7, 9, 6,
26491 10, 5, 11, 4, 12, 3, 13, 2,
26492 14, 1, 15,
26493 };
26494
26495 static const uint8_t
26496 WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
26497 0, 128, 64, 192, 32, 160, 96, 224,
26498 16, 144, 80, 208, 48, 176, 112, 240,
26499 8, 136, 72, 200, 40, 168, 104, 232,
26500 24, 152, 88, 216, 56, 184, 120, 248,
26501 4, 132, 68, 196, 36, 164, 100, 228,
26502 20, 148, 84, 212, 52, 180, 116, 244,
26503 12, 140, 76, 204, 44, 172, 108, 236,
26504 28, 156, 92, 220, 60, 188, 124, 252,
26505 2, 130, 66, 194, 34, 162, 98, 226,
26506 18, 146, 82, 210, 50, 178, 114, 242,
26507 10, 138, 74, 202, 42, 170, 106, 234,
26508 26, 154, 90, 218, 58, 186, 122, 250,
26509 6, 134, 70, 198, 38, 166, 102, 230,
26510 22, 150, 86, 214, 54, 182, 118, 246,
26511 14, 142, 78, 206, 46, 174, 110, 238,
26512 30, 158, 94, 222, 62, 190, 126, 254,
26513 1, 129, 65, 193, 33, 161, 97, 225,
26514 17, 145, 81, 209, 49, 177, 113, 241,
26515 9, 137, 73, 201, 41, 169, 105, 233,
26516 25, 153, 89, 217, 57, 185, 121, 249,
26517 5, 133, 69, 197, 37, 165, 101, 229,
26518 21, 149, 85, 213, 53, 181, 117, 245,
26519 13, 141, 77, 205, 45, 173, 109, 237,
26520 29, 157, 93, 221, 61, 189, 125, 253,
26521 3, 131, 67, 195, 35, 163, 99, 227,
26522 19, 147, 83, 211, 51, 179, 115, 243,
26523 11, 139, 75, 203, 43, 171, 107, 235,
26524 27, 155, 91, 219, 59, 187, 123, 251,
26525 7, 135, 71, 199, 39, 167, 103, 231,
26526 23, 151, 87, 215, 55, 183, 119, 247,
26527 15, 143, 79, 207, 47, 175, 111, 239,
26528 31, 159, 95, 223, 63, 191, 127, 255,
26529 };
26530
26531 static const uint32_t
26532 WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
26533 1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104, 1073743360, 1073743616,
26534 1073743888, 1073744400, 1073744912, 1073745424, 1073745952, 1073746976, 1073748000, 1073749024,
26535 1073750064, 1073752112, 1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560,
26536 1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728, 134217728, 134217728,
26537 };
26538
26539 static const uint32_t
26540 WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
26541 1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376, 1073743904, 1073744928,
26542 1073745968, 1073748016, 1073750080, 1073754176, 1073758288, 1073766480, 1073774688, 1073791072,
26543 1073807472, 1073840240, 1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416,
26544 1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488, 134217728, 134217728,
26545 };
26546
26547 #define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024
26548
26549 #define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023
26550
26551 // ---------------- Private Initializer Prototypes
26552
26553 // ---------------- Private Function Prototypes
26554
26555 static wuffs_base__status
26556 wuffs_deflate__decoder__decode_blocks(
26557 wuffs_deflate__decoder* self,
26558 wuffs_base__io_buffer* a_dst,
26559 wuffs_base__io_buffer* a_src);
26560
26561 static wuffs_base__status
26562 wuffs_deflate__decoder__decode_uncompressed(
26563 wuffs_deflate__decoder* self,
26564 wuffs_base__io_buffer* a_dst,
26565 wuffs_base__io_buffer* a_src);
26566
26567 static wuffs_base__status
26568 wuffs_deflate__decoder__init_fixed_huffman(
26569 wuffs_deflate__decoder* self);
26570
26571 static wuffs_base__status
26572 wuffs_deflate__decoder__init_dynamic_huffman(
26573 wuffs_deflate__decoder* self,
26574 wuffs_base__io_buffer* a_src);
26575
26576 static wuffs_base__status
26577 wuffs_deflate__decoder__init_huff(
26578 wuffs_deflate__decoder* self,
26579 uint32_t a_which,
26580 uint32_t a_n_codes0,
26581 uint32_t a_n_codes1,
26582 uint32_t a_base_symbol);
26583
26584 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26585 static wuffs_base__status
26586 wuffs_deflate__decoder__decode_huffman_bmi2(
26587 wuffs_deflate__decoder* self,
26588 wuffs_base__io_buffer* a_dst,
26589 wuffs_base__io_buffer* a_src);
26590 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26591
26592 static wuffs_base__status
26593 wuffs_deflate__decoder__decode_huffman_fast32(
26594 wuffs_deflate__decoder* self,
26595 wuffs_base__io_buffer* a_dst,
26596 wuffs_base__io_buffer* a_src);
26597
26598 static wuffs_base__status
26599 wuffs_deflate__decoder__decode_huffman_fast64(
26600 wuffs_deflate__decoder* self,
26601 wuffs_base__io_buffer* a_dst,
26602 wuffs_base__io_buffer* a_src);
26603
26604 static wuffs_base__status
26605 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
26606 wuffs_deflate__decoder* self,
26607 wuffs_base__io_buffer* a_dst,
26608 wuffs_base__io_buffer* a_src);
26609
26610 static wuffs_base__status
26611 wuffs_deflate__decoder__decode_huffman_slow(
26612 wuffs_deflate__decoder* self,
26613 wuffs_base__io_buffer* a_dst,
26614 wuffs_base__io_buffer* a_src);
26615
26616 // ---------------- VTables
26617
26618 const wuffs_base__io_transformer__func_ptrs
26619 wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = {
26620 (wuffs_base__empty_struct(*)(void*,
26621 uint32_t,
26622 bool))(&wuffs_deflate__decoder__set_quirk_enabled),
26623 (wuffs_base__status(*)(void*,
26624 wuffs_base__io_buffer*,
26625 wuffs_base__io_buffer*,
26626 wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io),
26627 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len),
26628 };
26629
26630 // ---------------- Initializer Implementations
26631
26632 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_deflate__decoder__initialize(wuffs_deflate__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)26633 wuffs_deflate__decoder__initialize(
26634 wuffs_deflate__decoder* self,
26635 size_t sizeof_star_self,
26636 uint64_t wuffs_version,
26637 uint32_t options){
26638 if (!self) {
26639 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
26640 }
26641 if (sizeof(*self) != sizeof_star_self) {
26642 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
26643 }
26644 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
26645 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
26646 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
26647 }
26648
26649 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
26650 // The whole point of this if-check is to detect an uninitialized *self.
26651 // We disable the warning on GCC. Clang-5.0 does not have this warning.
26652 #if !defined(__clang__) && defined(__GNUC__)
26653 #pragma GCC diagnostic push
26654 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
26655 #endif
26656 if (self->private_impl.magic != 0) {
26657 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
26658 }
26659 #if !defined(__clang__) && defined(__GNUC__)
26660 #pragma GCC diagnostic pop
26661 #endif
26662 } else {
26663 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
26664 memset(self, 0, sizeof(*self));
26665 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
26666 } else {
26667 memset(&(self->private_impl), 0, sizeof(self->private_impl));
26668 }
26669 }
26670
26671 self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default;
26672
26673 self->private_impl.magic = WUFFS_BASE__MAGIC;
26674 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
26675 wuffs_base__io_transformer__vtable_name;
26676 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
26677 (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer);
26678 return wuffs_base__make_status(NULL);
26679 }
26680
26681 wuffs_deflate__decoder*
wuffs_deflate__decoder__alloc()26682 wuffs_deflate__decoder__alloc() {
26683 wuffs_deflate__decoder* x =
26684 (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
26685 if (!x) {
26686 return NULL;
26687 }
26688 if (wuffs_deflate__decoder__initialize(
26689 x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
26690 free(x);
26691 return NULL;
26692 }
26693 return x;
26694 }
26695
26696 size_t
sizeof__wuffs_deflate__decoder()26697 sizeof__wuffs_deflate__decoder() {
26698 return sizeof(wuffs_deflate__decoder);
26699 }
26700
26701 // ---------------- Function Implementations
26702
26703 // -------- func deflate.decoder.add_history
26704
26705 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_deflate__decoder__add_history(wuffs_deflate__decoder * self,wuffs_base__slice_u8 a_hist)26706 wuffs_deflate__decoder__add_history(
26707 wuffs_deflate__decoder* self,
26708 wuffs_base__slice_u8 a_hist) {
26709 if (!self) {
26710 return wuffs_base__make_empty_struct();
26711 }
26712 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26713 return wuffs_base__make_empty_struct();
26714 }
26715
26716 wuffs_base__slice_u8 v_s = {0};
26717 uint64_t v_n_copied = 0;
26718 uint32_t v_already_full = 0;
26719
26720 v_s = a_hist;
26721 if (((uint64_t)(v_s.len)) >= 32768) {
26722 v_s = wuffs_base__slice_u8__suffix(v_s, 32768);
26723 wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
26724 self->private_impl.f_history_index = 32768;
26725 } else {
26726 v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), (self->private_impl.f_history_index & 32767)), v_s);
26727 if (v_n_copied < ((uint64_t)(v_s.len))) {
26728 v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied);
26729 v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
26730 self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767))) + 32768);
26731 } else {
26732 v_already_full = 0;
26733 if (self->private_impl.f_history_index >= 32768) {
26734 v_already_full = 32768;
26735 }
26736 self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767) + ((uint32_t)((v_n_copied & 32767))) + v_already_full);
26737 }
26738 }
26739 wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8((self->private_data.f_history) + 32768, 257), wuffs_base__make_slice_u8(self->private_data.f_history, 33025));
26740 return wuffs_base__make_empty_struct();
26741 }
26742
26743 // -------- func deflate.decoder.set_quirk_enabled
26744
26745 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_deflate__decoder__set_quirk_enabled(wuffs_deflate__decoder * self,uint32_t a_quirk,bool a_enabled)26746 wuffs_deflate__decoder__set_quirk_enabled(
26747 wuffs_deflate__decoder* self,
26748 uint32_t a_quirk,
26749 bool a_enabled) {
26750 return wuffs_base__make_empty_struct();
26751 }
26752
26753 // -------- func deflate.decoder.workbuf_len
26754
26755 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder * self)26756 wuffs_deflate__decoder__workbuf_len(
26757 const wuffs_deflate__decoder* self) {
26758 if (!self) {
26759 return wuffs_base__utility__empty_range_ii_u64();
26760 }
26761 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
26762 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
26763 return wuffs_base__utility__empty_range_ii_u64();
26764 }
26765
26766 return wuffs_base__utility__make_range_ii_u64(1, 1);
26767 }
26768
26769 // -------- func deflate.decoder.transform_io
26770
26771 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_deflate__decoder__transform_io(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)26772 wuffs_deflate__decoder__transform_io(
26773 wuffs_deflate__decoder* self,
26774 wuffs_base__io_buffer* a_dst,
26775 wuffs_base__io_buffer* a_src,
26776 wuffs_base__slice_u8 a_workbuf) {
26777 if (!self) {
26778 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
26779 }
26780 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
26781 return wuffs_base__make_status(
26782 (self->private_impl.magic == WUFFS_BASE__DISABLED)
26783 ? wuffs_base__error__disabled_by_previous_error
26784 : wuffs_base__error__initialize_not_called);
26785 }
26786 if (!a_dst || !a_src) {
26787 self->private_impl.magic = WUFFS_BASE__DISABLED;
26788 return wuffs_base__make_status(wuffs_base__error__bad_argument);
26789 }
26790 if ((self->private_impl.active_coroutine != 0) &&
26791 (self->private_impl.active_coroutine != 1)) {
26792 self->private_impl.magic = WUFFS_BASE__DISABLED;
26793 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
26794 }
26795 self->private_impl.active_coroutine = 0;
26796 wuffs_base__status status = wuffs_base__make_status(NULL);
26797
26798 uint64_t v_mark = 0;
26799 wuffs_base__status v_status = wuffs_base__make_status(NULL);
26800
26801 uint8_t* iop_a_dst = NULL;
26802 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26803 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26804 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26805 if (a_dst) {
26806 io0_a_dst = a_dst->data.ptr;
26807 io1_a_dst = io0_a_dst + a_dst->meta.wi;
26808 iop_a_dst = io1_a_dst;
26809 io2_a_dst = io0_a_dst + a_dst->data.len;
26810 if (a_dst->meta.closed) {
26811 io2_a_dst = iop_a_dst;
26812 }
26813 }
26814
26815 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
26816 switch (coro_susp_point) {
26817 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26818
26819 self->private_impl.choosy_decode_huffman_fast64 = (
26820 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
26821 wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 :
26822 #endif
26823 self->private_impl.choosy_decode_huffman_fast64);
26824 while (true) {
26825 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
26826 {
26827 if (a_dst) {
26828 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
26829 }
26830 wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
26831 v_status = t_0;
26832 if (a_dst) {
26833 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
26834 }
26835 }
26836 if ( ! wuffs_base__status__is_suspension(&v_status)) {
26837 status = v_status;
26838 if (wuffs_base__status__is_error(&status)) {
26839 goto exit;
26840 } else if (wuffs_base__status__is_suspension(&status)) {
26841 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
26842 goto exit;
26843 }
26844 goto ok;
26845 }
26846 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_transformed_history_count, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))));
26847 wuffs_deflate__decoder__add_history(self, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
26848 status = v_status;
26849 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
26850 }
26851
26852 ok:
26853 self->private_impl.p_transform_io[0] = 0;
26854 goto exit;
26855 }
26856
26857 goto suspend;
26858 suspend:
26859 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
26860 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
26861
26862 goto exit;
26863 exit:
26864 if (a_dst) {
26865 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
26866 }
26867
26868 if (wuffs_base__status__is_error(&status)) {
26869 self->private_impl.magic = WUFFS_BASE__DISABLED;
26870 }
26871 return status;
26872 }
26873
26874 // -------- func deflate.decoder.decode_blocks
26875
26876 static wuffs_base__status
wuffs_deflate__decoder__decode_blocks(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)26877 wuffs_deflate__decoder__decode_blocks(
26878 wuffs_deflate__decoder* self,
26879 wuffs_base__io_buffer* a_dst,
26880 wuffs_base__io_buffer* a_src) {
26881 wuffs_base__status status = wuffs_base__make_status(NULL);
26882
26883 uint32_t v_final = 0;
26884 uint32_t v_b0 = 0;
26885 uint32_t v_type = 0;
26886 wuffs_base__status v_status = wuffs_base__make_status(NULL);
26887
26888 const uint8_t* iop_a_src = NULL;
26889 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26890 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26891 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
26892 if (a_src) {
26893 io0_a_src = a_src->data.ptr;
26894 io1_a_src = io0_a_src + a_src->meta.ri;
26895 iop_a_src = io1_a_src;
26896 io2_a_src = io0_a_src + a_src->meta.wi;
26897 }
26898
26899 uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0];
26900 if (coro_susp_point) {
26901 v_final = self->private_data.s_decode_blocks[0].v_final;
26902 }
26903 switch (coro_susp_point) {
26904 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
26905
26906 label__outer__continue:;
26907 while (v_final == 0) {
26908 while (self->private_impl.f_n_bits < 3) {
26909 {
26910 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
26911 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
26912 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
26913 goto suspend;
26914 }
26915 uint32_t t_0 = *iop_a_src++;
26916 v_b0 = t_0;
26917 }
26918 self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3));
26919 self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3) + 8);
26920 }
26921 v_final = (self->private_impl.f_bits & 1);
26922 v_type = ((self->private_impl.f_bits >> 1) & 3);
26923 self->private_impl.f_bits >>= 3;
26924 self->private_impl.f_n_bits -= 3;
26925 if (v_type == 0) {
26926 if (a_src) {
26927 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26928 }
26929 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
26930 status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
26931 if (a_src) {
26932 iop_a_src = a_src->data.ptr + a_src->meta.ri;
26933 }
26934 if (status.repr) {
26935 goto suspend;
26936 }
26937 goto label__outer__continue;
26938 } else if (v_type == 1) {
26939 v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
26940 if ( ! wuffs_base__status__is_ok(&v_status)) {
26941 status = v_status;
26942 if (wuffs_base__status__is_error(&status)) {
26943 goto exit;
26944 } else if (wuffs_base__status__is_suspension(&status)) {
26945 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
26946 goto exit;
26947 }
26948 goto ok;
26949 }
26950 } else if (v_type == 2) {
26951 if (a_src) {
26952 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26953 }
26954 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
26955 status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
26956 if (a_src) {
26957 iop_a_src = a_src->data.ptr + a_src->meta.ri;
26958 }
26959 if (status.repr) {
26960 goto suspend;
26961 }
26962 } else {
26963 status = wuffs_base__make_status(wuffs_deflate__error__bad_block);
26964 goto exit;
26965 }
26966 self->private_impl.f_end_of_block = false;
26967 while (true) {
26968 if (sizeof(void*) == 4) {
26969 if (a_src) {
26970 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26971 }
26972 v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src);
26973 if (a_src) {
26974 iop_a_src = a_src->data.ptr + a_src->meta.ri;
26975 }
26976 } else {
26977 if (a_src) {
26978 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26979 }
26980 v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src);
26981 if (a_src) {
26982 iop_a_src = a_src->data.ptr + a_src->meta.ri;
26983 }
26984 }
26985 if (wuffs_base__status__is_error(&v_status)) {
26986 status = v_status;
26987 goto exit;
26988 }
26989 if (self->private_impl.f_end_of_block) {
26990 goto label__outer__continue;
26991 }
26992 if (a_src) {
26993 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
26994 }
26995 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
26996 status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
26997 if (a_src) {
26998 iop_a_src = a_src->data.ptr + a_src->meta.ri;
26999 }
27000 if (status.repr) {
27001 goto suspend;
27002 }
27003 if (self->private_impl.f_end_of_block) {
27004 goto label__outer__continue;
27005 }
27006 }
27007 }
27008
27009 ok:
27010 self->private_impl.p_decode_blocks[0] = 0;
27011 goto exit;
27012 }
27013
27014 goto suspend;
27015 suspend:
27016 self->private_impl.p_decode_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
27017 self->private_data.s_decode_blocks[0].v_final = v_final;
27018
27019 goto exit;
27020 exit:
27021 if (a_src) {
27022 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27023 }
27024
27025 return status;
27026 }
27027
27028 // -------- func deflate.decoder.decode_uncompressed
27029
27030 static wuffs_base__status
wuffs_deflate__decoder__decode_uncompressed(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)27031 wuffs_deflate__decoder__decode_uncompressed(
27032 wuffs_deflate__decoder* self,
27033 wuffs_base__io_buffer* a_dst,
27034 wuffs_base__io_buffer* a_src) {
27035 wuffs_base__status status = wuffs_base__make_status(NULL);
27036
27037 uint32_t v_length = 0;
27038 uint32_t v_n_copied = 0;
27039
27040 uint8_t* iop_a_dst = NULL;
27041 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27042 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27043 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27044 if (a_dst) {
27045 io0_a_dst = a_dst->data.ptr;
27046 io1_a_dst = io0_a_dst + a_dst->meta.wi;
27047 iop_a_dst = io1_a_dst;
27048 io2_a_dst = io0_a_dst + a_dst->data.len;
27049 if (a_dst->meta.closed) {
27050 io2_a_dst = iop_a_dst;
27051 }
27052 }
27053 const uint8_t* iop_a_src = NULL;
27054 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27055 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27056 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27057 if (a_src) {
27058 io0_a_src = a_src->data.ptr;
27059 io1_a_src = io0_a_src + a_src->meta.ri;
27060 iop_a_src = io1_a_src;
27061 io2_a_src = io0_a_src + a_src->meta.wi;
27062 }
27063
27064 uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0];
27065 if (coro_susp_point) {
27066 v_length = self->private_data.s_decode_uncompressed[0].v_length;
27067 }
27068 switch (coro_susp_point) {
27069 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
27070
27071 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27072 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27073 goto exit;
27074 }
27075 self->private_impl.f_n_bits = 0;
27076 self->private_impl.f_bits = 0;
27077 {
27078 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
27079 uint32_t t_0;
27080 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
27081 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
27082 iop_a_src += 4;
27083 } else {
27084 self->private_data.s_decode_uncompressed[0].scratch = 0;
27085 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
27086 while (true) {
27087 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27088 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27089 goto suspend;
27090 }
27091 uint64_t* scratch = &self->private_data.s_decode_uncompressed[0].scratch;
27092 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
27093 *scratch <<= 8;
27094 *scratch >>= 8;
27095 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
27096 if (num_bits_0 == 24) {
27097 t_0 = ((uint32_t)(*scratch));
27098 break;
27099 }
27100 num_bits_0 += 8;
27101 *scratch |= ((uint64_t)(num_bits_0)) << 56;
27102 }
27103 }
27104 v_length = t_0;
27105 }
27106 if ((((v_length) & 0xFFFF) + ((v_length) >> (32 - (16)))) != 65535) {
27107 status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length);
27108 goto exit;
27109 }
27110 v_length = ((v_length) & 0xFFFF);
27111 while (true) {
27112 v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_reader(
27113 &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
27114 if (v_length <= v_n_copied) {
27115 status = wuffs_base__make_status(NULL);
27116 goto ok;
27117 }
27118 v_length -= v_n_copied;
27119 if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0) {
27120 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
27121 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
27122 } else {
27123 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27124 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
27125 }
27126 }
27127
27128 ok:
27129 self->private_impl.p_decode_uncompressed[0] = 0;
27130 goto exit;
27131 }
27132
27133 goto suspend;
27134 suspend:
27135 self->private_impl.p_decode_uncompressed[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
27136 self->private_data.s_decode_uncompressed[0].v_length = v_length;
27137
27138 goto exit;
27139 exit:
27140 if (a_dst) {
27141 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
27142 }
27143 if (a_src) {
27144 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27145 }
27146
27147 return status;
27148 }
27149
27150 // -------- func deflate.decoder.init_fixed_huffman
27151
27152 static wuffs_base__status
wuffs_deflate__decoder__init_fixed_huffman(wuffs_deflate__decoder * self)27153 wuffs_deflate__decoder__init_fixed_huffman(
27154 wuffs_deflate__decoder* self) {
27155 uint32_t v_i = 0;
27156 wuffs_base__status v_status = wuffs_base__make_status(NULL);
27157
27158 while (v_i < 144) {
27159 self->private_data.f_code_lengths[v_i] = 8;
27160 v_i += 1;
27161 }
27162 while (v_i < 256) {
27163 self->private_data.f_code_lengths[v_i] = 9;
27164 v_i += 1;
27165 }
27166 while (v_i < 280) {
27167 self->private_data.f_code_lengths[v_i] = 7;
27168 v_i += 1;
27169 }
27170 while (v_i < 288) {
27171 self->private_data.f_code_lengths[v_i] = 8;
27172 v_i += 1;
27173 }
27174 while (v_i < 320) {
27175 self->private_data.f_code_lengths[v_i] = 5;
27176 v_i += 1;
27177 }
27178 v_status = wuffs_deflate__decoder__init_huff(self,
27179 0,
27180 0,
27181 288,
27182 257);
27183 if (wuffs_base__status__is_error(&v_status)) {
27184 return v_status;
27185 }
27186 v_status = wuffs_deflate__decoder__init_huff(self,
27187 1,
27188 288,
27189 320,
27190 0);
27191 if (wuffs_base__status__is_error(&v_status)) {
27192 return v_status;
27193 }
27194 return wuffs_base__make_status(NULL);
27195 }
27196
27197 // -------- func deflate.decoder.init_dynamic_huffman
27198
27199 static wuffs_base__status
wuffs_deflate__decoder__init_dynamic_huffman(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_src)27200 wuffs_deflate__decoder__init_dynamic_huffman(
27201 wuffs_deflate__decoder* self,
27202 wuffs_base__io_buffer* a_src) {
27203 wuffs_base__status status = wuffs_base__make_status(NULL);
27204
27205 uint32_t v_bits = 0;
27206 uint32_t v_n_bits = 0;
27207 uint32_t v_b0 = 0;
27208 uint32_t v_n_lit = 0;
27209 uint32_t v_n_dist = 0;
27210 uint32_t v_n_clen = 0;
27211 uint32_t v_i = 0;
27212 uint32_t v_b1 = 0;
27213 wuffs_base__status v_status = wuffs_base__make_status(NULL);
27214 uint32_t v_mask = 0;
27215 uint32_t v_table_entry = 0;
27216 uint32_t v_table_entry_n_bits = 0;
27217 uint32_t v_b2 = 0;
27218 uint32_t v_n_extra_bits = 0;
27219 uint8_t v_rep_symbol = 0;
27220 uint32_t v_rep_count = 0;
27221 uint32_t v_b3 = 0;
27222
27223 const uint8_t* iop_a_src = NULL;
27224 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27225 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27226 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27227 if (a_src) {
27228 io0_a_src = a_src->data.ptr;
27229 io1_a_src = io0_a_src + a_src->meta.ri;
27230 iop_a_src = io1_a_src;
27231 io2_a_src = io0_a_src + a_src->meta.wi;
27232 }
27233
27234 uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0];
27235 if (coro_susp_point) {
27236 v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits;
27237 v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits;
27238 v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit;
27239 v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist;
27240 v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen;
27241 v_i = self->private_data.s_init_dynamic_huffman[0].v_i;
27242 v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask;
27243 v_table_entry = self->private_data.s_init_dynamic_huffman[0].v_table_entry;
27244 v_n_extra_bits = self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits;
27245 v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol;
27246 v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count;
27247 }
27248 switch (coro_susp_point) {
27249 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
27250
27251 v_bits = self->private_impl.f_bits;
27252 v_n_bits = self->private_impl.f_n_bits;
27253 while (v_n_bits < 14) {
27254 {
27255 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
27256 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27257 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27258 goto suspend;
27259 }
27260 uint32_t t_0 = *iop_a_src++;
27261 v_b0 = t_0;
27262 }
27263 v_bits |= (v_b0 << v_n_bits);
27264 v_n_bits += 8;
27265 }
27266 v_n_lit = (((v_bits) & 0x1F) + 257);
27267 if (v_n_lit > 286) {
27268 status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count);
27269 goto exit;
27270 }
27271 v_bits >>= 5;
27272 v_n_dist = (((v_bits) & 0x1F) + 1);
27273 if (v_n_dist > 30) {
27274 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count);
27275 goto exit;
27276 }
27277 v_bits >>= 5;
27278 v_n_clen = (((v_bits) & 0xF) + 4);
27279 v_bits >>= 4;
27280 v_n_bits -= 14;
27281 v_i = 0;
27282 while (v_i < v_n_clen) {
27283 while (v_n_bits < 3) {
27284 {
27285 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
27286 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27287 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27288 goto suspend;
27289 }
27290 uint32_t t_1 = *iop_a_src++;
27291 v_b1 = t_1;
27292 }
27293 v_bits |= (v_b1 << v_n_bits);
27294 v_n_bits += 8;
27295 }
27296 self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7)));
27297 v_bits >>= 3;
27298 v_n_bits -= 3;
27299 v_i += 1;
27300 }
27301 while (v_i < 19) {
27302 self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0;
27303 v_i += 1;
27304 }
27305 v_status = wuffs_deflate__decoder__init_huff(self,
27306 0,
27307 0,
27308 19,
27309 4095);
27310 if (wuffs_base__status__is_error(&v_status)) {
27311 status = v_status;
27312 goto exit;
27313 }
27314 v_mask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27315 v_i = 0;
27316 label__0__continue:;
27317 while (v_i < (v_n_lit + v_n_dist)) {
27318 while (true) {
27319 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_mask)];
27320 v_table_entry_n_bits = (v_table_entry & 15);
27321 if (v_n_bits >= v_table_entry_n_bits) {
27322 v_bits >>= v_table_entry_n_bits;
27323 v_n_bits -= v_table_entry_n_bits;
27324 goto label__1__break;
27325 }
27326 {
27327 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
27328 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27329 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27330 goto suspend;
27331 }
27332 uint32_t t_2 = *iop_a_src++;
27333 v_b2 = t_2;
27334 }
27335 v_bits |= (v_b2 << v_n_bits);
27336 v_n_bits += 8;
27337 }
27338 label__1__break:;
27339 if ((v_table_entry >> 24) != 128) {
27340 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27341 goto exit;
27342 }
27343 v_table_entry = ((v_table_entry >> 8) & 255);
27344 if (v_table_entry < 16) {
27345 self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
27346 v_i += 1;
27347 goto label__0__continue;
27348 }
27349 v_n_extra_bits = 0;
27350 v_rep_symbol = 0;
27351 v_rep_count = 0;
27352 if (v_table_entry == 16) {
27353 v_n_extra_bits = 2;
27354 if (v_i <= 0) {
27355 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition);
27356 goto exit;
27357 }
27358 v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1)] & 15);
27359 v_rep_count = 3;
27360 } else if (v_table_entry == 17) {
27361 v_n_extra_bits = 3;
27362 v_rep_symbol = 0;
27363 v_rep_count = 3;
27364 } else if (v_table_entry == 18) {
27365 v_n_extra_bits = 7;
27366 v_rep_symbol = 0;
27367 v_rep_count = 11;
27368 } else {
27369 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27370 goto exit;
27371 }
27372 while (v_n_bits < v_n_extra_bits) {
27373 {
27374 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
27375 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
27376 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
27377 goto suspend;
27378 }
27379 uint32_t t_3 = *iop_a_src++;
27380 v_b3 = t_3;
27381 }
27382 v_bits |= (v_b3 << v_n_bits);
27383 v_n_bits += 8;
27384 }
27385 v_rep_count += ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits));
27386 v_bits >>= v_n_extra_bits;
27387 v_n_bits -= v_n_extra_bits;
27388 while (v_rep_count > 0) {
27389 if (v_i >= (v_n_lit + v_n_dist)) {
27390 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
27391 goto exit;
27392 }
27393 self->private_data.f_code_lengths[v_i] = v_rep_symbol;
27394 v_i += 1;
27395 v_rep_count -= 1;
27396 }
27397 }
27398 if (v_i != (v_n_lit + v_n_dist)) {
27399 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
27400 goto exit;
27401 }
27402 if (self->private_data.f_code_lengths[256] == 0) {
27403 status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code);
27404 goto exit;
27405 }
27406 v_status = wuffs_deflate__decoder__init_huff(self,
27407 0,
27408 0,
27409 v_n_lit,
27410 257);
27411 if (wuffs_base__status__is_error(&v_status)) {
27412 status = v_status;
27413 goto exit;
27414 }
27415 v_status = wuffs_deflate__decoder__init_huff(self,
27416 1,
27417 v_n_lit,
27418 (v_n_lit + v_n_dist),
27419 0);
27420 if (wuffs_base__status__is_error(&v_status)) {
27421 status = v_status;
27422 goto exit;
27423 }
27424 self->private_impl.f_bits = v_bits;
27425 self->private_impl.f_n_bits = v_n_bits;
27426
27427 goto ok;
27428 ok:
27429 self->private_impl.p_init_dynamic_huffman[0] = 0;
27430 goto exit;
27431 }
27432
27433 goto suspend;
27434 suspend:
27435 self->private_impl.p_init_dynamic_huffman[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
27436 self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits;
27437 self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits;
27438 self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit;
27439 self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist;
27440 self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen;
27441 self->private_data.s_init_dynamic_huffman[0].v_i = v_i;
27442 self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask;
27443 self->private_data.s_init_dynamic_huffman[0].v_table_entry = v_table_entry;
27444 self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits;
27445 self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol;
27446 self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count;
27447
27448 goto exit;
27449 exit:
27450 if (a_src) {
27451 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27452 }
27453
27454 return status;
27455 }
27456
27457 // -------- func deflate.decoder.init_huff
27458
27459 static wuffs_base__status
wuffs_deflate__decoder__init_huff(wuffs_deflate__decoder * self,uint32_t a_which,uint32_t a_n_codes0,uint32_t a_n_codes1,uint32_t a_base_symbol)27460 wuffs_deflate__decoder__init_huff(
27461 wuffs_deflate__decoder* self,
27462 uint32_t a_which,
27463 uint32_t a_n_codes0,
27464 uint32_t a_n_codes1,
27465 uint32_t a_base_symbol) {
27466 uint16_t v_counts[16] = {0};
27467 uint32_t v_i = 0;
27468 uint32_t v_remaining = 0;
27469 uint16_t v_offsets[16] = {0};
27470 uint32_t v_n_symbols = 0;
27471 uint32_t v_count = 0;
27472 uint16_t v_symbols[320] = {0};
27473 uint32_t v_min_cl = 0;
27474 uint32_t v_max_cl = 0;
27475 uint32_t v_initial_high_bits = 0;
27476 uint32_t v_prev_cl = 0;
27477 uint32_t v_prev_redirect_key = 0;
27478 uint32_t v_top = 0;
27479 uint32_t v_next_top = 0;
27480 uint32_t v_code = 0;
27481 uint32_t v_key = 0;
27482 uint32_t v_value = 0;
27483 uint32_t v_cl = 0;
27484 uint32_t v_redirect_key = 0;
27485 uint32_t v_j = 0;
27486 uint32_t v_reversed_key = 0;
27487 uint32_t v_symbol = 0;
27488 uint32_t v_high_bits = 0;
27489 uint32_t v_delta = 0;
27490
27491 v_i = a_n_codes0;
27492 while (v_i < a_n_codes1) {
27493 if (v_counts[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
27494 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27495 }
27496 #if defined(__GNUC__)
27497 #pragma GCC diagnostic push
27498 #pragma GCC diagnostic ignored "-Wconversion"
27499 #endif
27500 v_counts[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
27501 #if defined(__GNUC__)
27502 #pragma GCC diagnostic pop
27503 #endif
27504 v_i += 1;
27505 }
27506 if ((((uint32_t)(v_counts[0])) + a_n_codes0) == a_n_codes1) {
27507 return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
27508 }
27509 v_remaining = 1;
27510 v_i = 1;
27511 while (v_i <= 15) {
27512 if (v_remaining > 1073741824) {
27513 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27514 }
27515 v_remaining <<= 1;
27516 if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
27517 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed);
27518 }
27519 v_remaining -= ((uint32_t)(v_counts[v_i]));
27520 v_i += 1;
27521 }
27522 if (v_remaining != 0) {
27523 if ((a_which == 1) && (v_counts[1] == 1) && ((((uint32_t)(v_counts[0])) + a_n_codes0 + 1) == a_n_codes1)) {
27524 v_i = 0;
27525 while (v_i <= 29) {
27526 if (self->private_data.f_code_lengths[(a_n_codes0 + v_i)] == 1) {
27527 self->private_impl.f_n_huffs_bits[1] = 1;
27528 self->private_data.f_huffs[1][0] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[v_i] | 1);
27529 self->private_data.f_huffs[1][1] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31] | 1);
27530 return wuffs_base__make_status(NULL);
27531 }
27532 v_i += 1;
27533 }
27534 }
27535 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
27536 }
27537 v_i = 1;
27538 while (v_i <= 15) {
27539 v_offsets[v_i] = ((uint16_t)(v_n_symbols));
27540 v_count = ((uint32_t)(v_counts[v_i]));
27541 if (v_n_symbols > (320 - v_count)) {
27542 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27543 }
27544 v_n_symbols = (v_n_symbols + v_count);
27545 v_i += 1;
27546 }
27547 if (v_n_symbols > 288) {
27548 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27549 }
27550 v_i = a_n_codes0;
27551 while (v_i < a_n_codes1) {
27552 if (v_i < a_n_codes0) {
27553 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27554 }
27555 if (self->private_data.f_code_lengths[v_i] != 0) {
27556 if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] >= 320) {
27557 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27558 }
27559 v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15)]] = ((uint16_t)((v_i - a_n_codes0)));
27560 #if defined(__GNUC__)
27561 #pragma GCC diagnostic push
27562 #pragma GCC diagnostic ignored "-Wconversion"
27563 #endif
27564 v_offsets[(self->private_data.f_code_lengths[v_i] & 15)] += 1;
27565 #if defined(__GNUC__)
27566 #pragma GCC diagnostic pop
27567 #endif
27568 }
27569 v_i += 1;
27570 }
27571 v_min_cl = 1;
27572 while (true) {
27573 if (v_counts[v_min_cl] != 0) {
27574 goto label__0__break;
27575 }
27576 if (v_min_cl >= 9) {
27577 return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length);
27578 }
27579 v_min_cl += 1;
27580 }
27581 label__0__break:;
27582 v_max_cl = 15;
27583 while (true) {
27584 if (v_counts[v_max_cl] != 0) {
27585 goto label__1__break;
27586 }
27587 if (v_max_cl <= 1) {
27588 return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
27589 }
27590 v_max_cl -= 1;
27591 }
27592 label__1__break:;
27593 if (v_max_cl <= 9) {
27594 self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
27595 } else {
27596 self->private_impl.f_n_huffs_bits[a_which] = 9;
27597 }
27598 v_i = 0;
27599 if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15])))) {
27600 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27601 }
27602 if ((a_n_codes0 + ((uint32_t)(v_symbols[0]))) >= 320) {
27603 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27604 }
27605 v_initial_high_bits = 512;
27606 if (v_max_cl < 9) {
27607 v_initial_high_bits = (((uint32_t)(1)) << v_max_cl);
27608 }
27609 v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0])))] & 15)));
27610 v_prev_redirect_key = 4294967295;
27611 v_top = 0;
27612 v_next_top = 512;
27613 v_code = 0;
27614 v_key = 0;
27615 v_value = 0;
27616 while (true) {
27617 if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320) {
27618 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27619 }
27620 v_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15)));
27621 if (v_cl > v_prev_cl) {
27622 v_code <<= (v_cl - v_prev_cl);
27623 if (v_code >= 32768) {
27624 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27625 }
27626 }
27627 v_prev_cl = v_cl;
27628 v_key = v_code;
27629 if (v_cl > 9) {
27630 v_cl -= 9;
27631 v_redirect_key = ((v_key >> v_cl) & 511);
27632 v_key = ((v_key) & WUFFS_BASE__LOW_BITS_MASK__U32(v_cl));
27633 if (v_prev_redirect_key != v_redirect_key) {
27634 v_prev_redirect_key = v_redirect_key;
27635 v_remaining = (((uint32_t)(1)) << v_cl);
27636 v_j = v_prev_cl;
27637 while (v_j <= 15) {
27638 if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
27639 goto label__2__break;
27640 }
27641 v_remaining -= ((uint32_t)(v_counts[v_j]));
27642 if (v_remaining > 1073741824) {
27643 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27644 }
27645 v_remaining <<= 1;
27646 v_j += 1;
27647 }
27648 label__2__break:;
27649 if ((v_j <= 9) || (15 < v_j)) {
27650 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27651 }
27652 v_j -= 9;
27653 v_initial_high_bits = (((uint32_t)(1)) << v_j);
27654 v_top = v_next_top;
27655 if ((v_top + (((uint32_t)(1)) << v_j)) > 1024) {
27656 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27657 }
27658 v_next_top = (v_top + (((uint32_t)(1)) << v_j));
27659 v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1)])) | ((v_redirect_key & 1) << 8));
27660 self->private_data.f_huffs[a_which][v_redirect_key] = (268435465 | (v_top << 8) | (v_j << 4));
27661 }
27662 }
27663 if ((v_key >= 512) || (v_counts[v_prev_cl] <= 0)) {
27664 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27665 }
27666 #if defined(__GNUC__)
27667 #pragma GCC diagnostic push
27668 #pragma GCC diagnostic ignored "-Wconversion"
27669 #endif
27670 v_counts[v_prev_cl] -= 1;
27671 #if defined(__GNUC__)
27672 #pragma GCC diagnostic pop
27673 #endif
27674 v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1)])) | ((v_key & 1) << 8));
27675 v_reversed_key >>= (9 - v_cl);
27676 v_symbol = ((uint32_t)(v_symbols[v_i]));
27677 if (v_symbol == 256) {
27678 v_value = (536870912 | v_cl);
27679 } else if ((v_symbol < 256) && (a_which == 0)) {
27680 v_value = (2147483648 | (v_symbol << 8) | v_cl);
27681 } else if (v_symbol >= a_base_symbol) {
27682 v_symbol -= a_base_symbol;
27683 if (a_which == 0) {
27684 v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
27685 } else {
27686 v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31)] | v_cl);
27687 }
27688 } else {
27689 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27690 }
27691 v_high_bits = v_initial_high_bits;
27692 v_delta = (((uint32_t)(1)) << v_cl);
27693 while (v_high_bits >= v_delta) {
27694 v_high_bits -= v_delta;
27695 if ((v_top + ((v_high_bits | v_reversed_key) & 511)) >= 1024) {
27696 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27697 }
27698 self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511))] = v_value;
27699 }
27700 v_i += 1;
27701 if (v_i >= v_n_symbols) {
27702 goto label__3__break;
27703 }
27704 v_code += 1;
27705 if (v_code >= 32768) {
27706 return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27707 }
27708 }
27709 label__3__break:;
27710 return wuffs_base__make_status(NULL);
27711 }
27712
27713 // ‼ WUFFS MULTI-FILE SECTION +x86_bmi2
27714 // -------- func deflate.decoder.decode_huffman_bmi2
27715
27716 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27717 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2")
27718 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_bmi2(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)27719 wuffs_deflate__decoder__decode_huffman_bmi2(
27720 wuffs_deflate__decoder* self,
27721 wuffs_base__io_buffer* a_dst,
27722 wuffs_base__io_buffer* a_src) {
27723 wuffs_base__status status = wuffs_base__make_status(NULL);
27724
27725 uint64_t v_bits = 0;
27726 uint32_t v_n_bits = 0;
27727 uint32_t v_table_entry = 0;
27728 uint32_t v_table_entry_n_bits = 0;
27729 uint64_t v_lmask = 0;
27730 uint64_t v_dmask = 0;
27731 uint32_t v_redir_top = 0;
27732 uint32_t v_redir_mask = 0;
27733 uint32_t v_length = 0;
27734 uint32_t v_dist_minus_1 = 0;
27735 uint32_t v_hlen = 0;
27736 uint32_t v_hdist = 0;
27737 uint32_t v_hdist_adjustment = 0;
27738
27739 uint8_t* iop_a_dst = NULL;
27740 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27741 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27742 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27743 if (a_dst) {
27744 io0_a_dst = a_dst->data.ptr;
27745 io1_a_dst = io0_a_dst + a_dst->meta.wi;
27746 iop_a_dst = io1_a_dst;
27747 io2_a_dst = io0_a_dst + a_dst->data.len;
27748 if (a_dst->meta.closed) {
27749 io2_a_dst = iop_a_dst;
27750 }
27751 }
27752 const uint8_t* iop_a_src = NULL;
27753 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27754 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27755 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27756 if (a_src) {
27757 io0_a_src = a_src->data.ptr;
27758 io1_a_src = io0_a_src + a_src->meta.ri;
27759 iop_a_src = io1_a_src;
27760 io2_a_src = io0_a_src + a_src->meta.wi;
27761 }
27762
27763 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27764 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27765 goto exit;
27766 }
27767 v_bits = ((uint64_t)(self->private_impl.f_bits));
27768 v_n_bits = self->private_impl.f_n_bits;
27769 v_lmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27770 v_dmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27771 if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
27772 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
27773 goto exit;
27774 }
27775 v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
27776 label__loop__continue:;
27777 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8)) {
27778 v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63)));
27779 iop_a_src += ((63 - (v_n_bits & 63)) >> 3);
27780 v_n_bits |= 56;
27781 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
27782 v_table_entry_n_bits = (v_table_entry & 15);
27783 v_bits >>= v_table_entry_n_bits;
27784 v_n_bits -= v_table_entry_n_bits;
27785 if ((v_table_entry >> 31) != 0) {
27786 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27787 goto label__loop__continue;
27788 } else if ((v_table_entry >> 30) != 0) {
27789 } else if ((v_table_entry >> 29) != 0) {
27790 self->private_impl.f_end_of_block = true;
27791 goto label__loop__break;
27792 } else if ((v_table_entry >> 28) != 0) {
27793 v_redir_top = ((v_table_entry >> 8) & 65535);
27794 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27795 v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27796 v_table_entry_n_bits = (v_table_entry & 15);
27797 v_bits >>= v_table_entry_n_bits;
27798 v_n_bits -= v_table_entry_n_bits;
27799 if ((v_table_entry >> 31) != 0) {
27800 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
27801 goto label__loop__continue;
27802 } else if ((v_table_entry >> 30) != 0) {
27803 } else if ((v_table_entry >> 29) != 0) {
27804 self->private_impl.f_end_of_block = true;
27805 goto label__loop__break;
27806 } else if ((v_table_entry >> 28) != 0) {
27807 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27808 goto exit;
27809 } else if ((v_table_entry >> 27) != 0) {
27810 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27811 goto exit;
27812 } else {
27813 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27814 goto exit;
27815 }
27816 } else if ((v_table_entry >> 27) != 0) {
27817 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27818 goto exit;
27819 } else {
27820 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27821 goto exit;
27822 }
27823 v_length = (((v_table_entry >> 8) & 255) + 3);
27824 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27825 if (v_table_entry_n_bits > 0) {
27826 v_length = (((v_length + 253 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255) + 3);
27827 v_bits >>= v_table_entry_n_bits;
27828 v_n_bits -= v_table_entry_n_bits;
27829 }
27830 v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
27831 v_table_entry_n_bits = (v_table_entry & 15);
27832 v_bits >>= v_table_entry_n_bits;
27833 v_n_bits -= v_table_entry_n_bits;
27834 if ((v_table_entry >> 28) == 1) {
27835 v_redir_top = ((v_table_entry >> 8) & 65535);
27836 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
27837 v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
27838 v_table_entry_n_bits = (v_table_entry & 15);
27839 v_bits >>= v_table_entry_n_bits;
27840 v_n_bits -= v_table_entry_n_bits;
27841 }
27842 if ((v_table_entry >> 24) != 64) {
27843 if ((v_table_entry >> 24) == 8) {
27844 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
27845 goto exit;
27846 }
27847 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
27848 goto exit;
27849 }
27850 v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
27851 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
27852 v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767);
27853 v_bits >>= v_table_entry_n_bits;
27854 v_n_bits -= v_table_entry_n_bits;
27855 while (true) {
27856 if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
27857 v_hlen = 0;
27858 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
27859 if (v_length > v_hdist) {
27860 v_length -= v_hdist;
27861 v_hlen = v_hdist;
27862 } else {
27863 v_hlen = v_length;
27864 v_length = 0;
27865 }
27866 v_hdist += v_hdist_adjustment;
27867 if (self->private_impl.f_history_index < v_hdist) {
27868 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
27869 goto exit;
27870 }
27871 wuffs_base__io_writer__limited_copy_u32_from_slice(
27872 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), ((self->private_impl.f_history_index - v_hdist) & 32767)));
27873 if (v_length == 0) {
27874 goto label__loop__continue;
27875 }
27876 if ((((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
27877 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
27878 goto exit;
27879 }
27880 }
27881 if ((v_dist_minus_1 + 1) >= 8) {
27882 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
27883 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27884 } else if ((v_dist_minus_1 + 1) == 1) {
27885 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
27886 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27887 } else {
27888 wuffs_base__io_writer__limited_copy_u32_from_history_fast(
27889 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
27890 }
27891 goto label__0__break;
27892 }
27893 label__0__break:;
27894 }
27895 label__loop__break:;
27896 if (v_n_bits > 63) {
27897 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27898 goto exit;
27899 }
27900 while (v_n_bits >= 8) {
27901 v_n_bits -= 8;
27902 if (iop_a_src > io1_a_src) {
27903 iop_a_src--;
27904 } else {
27905 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
27906 goto exit;
27907 }
27908 }
27909 self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1)) << v_n_bits) - 1))));
27910 self->private_impl.f_n_bits = v_n_bits;
27911 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
27912 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27913 goto exit;
27914 }
27915 goto exit;
27916 exit:
27917 if (a_dst) {
27918 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
27919 }
27920 if (a_src) {
27921 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
27922 }
27923
27924 return status;
27925 }
27926 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
27927 // ‼ WUFFS MULTI-FILE SECTION -x86_bmi2
27928
27929 // -------- func deflate.decoder.decode_huffman_fast32
27930
27931 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_fast32(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)27932 wuffs_deflate__decoder__decode_huffman_fast32(
27933 wuffs_deflate__decoder* self,
27934 wuffs_base__io_buffer* a_dst,
27935 wuffs_base__io_buffer* a_src) {
27936 wuffs_base__status status = wuffs_base__make_status(NULL);
27937
27938 uint32_t v_bits = 0;
27939 uint32_t v_n_bits = 0;
27940 uint32_t v_table_entry = 0;
27941 uint32_t v_table_entry_n_bits = 0;
27942 uint32_t v_lmask = 0;
27943 uint32_t v_dmask = 0;
27944 uint32_t v_redir_top = 0;
27945 uint32_t v_redir_mask = 0;
27946 uint32_t v_length = 0;
27947 uint32_t v_dist_minus_1 = 0;
27948 uint32_t v_hlen = 0;
27949 uint32_t v_hdist = 0;
27950 uint32_t v_hdist_adjustment = 0;
27951
27952 uint8_t* iop_a_dst = NULL;
27953 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27954 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27955 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27956 if (a_dst) {
27957 io0_a_dst = a_dst->data.ptr;
27958 io1_a_dst = io0_a_dst + a_dst->meta.wi;
27959 iop_a_dst = io1_a_dst;
27960 io2_a_dst = io0_a_dst + a_dst->data.len;
27961 if (a_dst->meta.closed) {
27962 io2_a_dst = iop_a_dst;
27963 }
27964 }
27965 const uint8_t* iop_a_src = NULL;
27966 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27967 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27968 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
27969 if (a_src) {
27970 io0_a_src = a_src->data.ptr;
27971 io1_a_src = io0_a_src + a_src->meta.ri;
27972 iop_a_src = io1_a_src;
27973 io2_a_src = io0_a_src + a_src->meta.wi;
27974 }
27975
27976 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
27977 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
27978 goto exit;
27979 }
27980 v_bits = self->private_impl.f_bits;
27981 v_n_bits = self->private_impl.f_n_bits;
27982 v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
27983 v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
27984 if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
27985 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
27986 goto exit;
27987 }
27988 v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
27989 label__loop__continue:;
27990 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12)) {
27991 if (v_n_bits < 15) {
27992 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27993 iop_a_src += 1;
27994 v_n_bits += 8;
27995 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
27996 iop_a_src += 1;
27997 v_n_bits += 8;
27998 } else {
27999 }
28000 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
28001 v_table_entry_n_bits = (v_table_entry & 15);
28002 v_bits >>= v_table_entry_n_bits;
28003 v_n_bits -= v_table_entry_n_bits;
28004 if ((v_table_entry >> 31) != 0) {
28005 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28006 goto label__loop__continue;
28007 } else if ((v_table_entry >> 30) != 0) {
28008 } else if ((v_table_entry >> 29) != 0) {
28009 self->private_impl.f_end_of_block = true;
28010 goto label__loop__break;
28011 } else if ((v_table_entry >> 28) != 0) {
28012 if (v_n_bits < 15) {
28013 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28014 iop_a_src += 1;
28015 v_n_bits += 8;
28016 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28017 iop_a_src += 1;
28018 v_n_bits += 8;
28019 } else {
28020 }
28021 v_redir_top = ((v_table_entry >> 8) & 65535);
28022 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28023 v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28024 v_table_entry_n_bits = (v_table_entry & 15);
28025 v_bits >>= v_table_entry_n_bits;
28026 v_n_bits -= v_table_entry_n_bits;
28027 if ((v_table_entry >> 31) != 0) {
28028 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28029 goto label__loop__continue;
28030 } else if ((v_table_entry >> 30) != 0) {
28031 } else if ((v_table_entry >> 29) != 0) {
28032 self->private_impl.f_end_of_block = true;
28033 goto label__loop__break;
28034 } else if ((v_table_entry >> 28) != 0) {
28035 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28036 goto exit;
28037 } else if ((v_table_entry >> 27) != 0) {
28038 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28039 goto exit;
28040 } else {
28041 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28042 goto exit;
28043 }
28044 } else if ((v_table_entry >> 27) != 0) {
28045 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28046 goto exit;
28047 } else {
28048 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28049 goto exit;
28050 }
28051 v_length = (((v_table_entry >> 8) & 255) + 3);
28052 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28053 if (v_table_entry_n_bits > 0) {
28054 if (v_n_bits < 15) {
28055 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28056 iop_a_src += 1;
28057 v_n_bits += 8;
28058 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28059 iop_a_src += 1;
28060 v_n_bits += 8;
28061 } else {
28062 }
28063 v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
28064 v_bits >>= v_table_entry_n_bits;
28065 v_n_bits -= v_table_entry_n_bits;
28066 } else {
28067 }
28068 if (v_n_bits < 15) {
28069 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28070 iop_a_src += 1;
28071 v_n_bits += 8;
28072 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28073 iop_a_src += 1;
28074 v_n_bits += 8;
28075 } else {
28076 }
28077 v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
28078 v_table_entry_n_bits = (v_table_entry & 15);
28079 v_bits >>= v_table_entry_n_bits;
28080 v_n_bits -= v_table_entry_n_bits;
28081 if ((v_table_entry >> 28) == 1) {
28082 if (v_n_bits < 15) {
28083 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28084 iop_a_src += 1;
28085 v_n_bits += 8;
28086 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28087 iop_a_src += 1;
28088 v_n_bits += 8;
28089 } else {
28090 }
28091 v_redir_top = ((v_table_entry >> 8) & 65535);
28092 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28093 v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28094 v_table_entry_n_bits = (v_table_entry & 15);
28095 v_bits >>= v_table_entry_n_bits;
28096 v_n_bits -= v_table_entry_n_bits;
28097 } else {
28098 }
28099 if ((v_table_entry >> 24) != 64) {
28100 if ((v_table_entry >> 24) == 8) {
28101 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28102 goto exit;
28103 }
28104 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28105 goto exit;
28106 }
28107 v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
28108 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28109 if (v_n_bits < v_table_entry_n_bits) {
28110 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28111 iop_a_src += 1;
28112 v_n_bits += 8;
28113 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
28114 iop_a_src += 1;
28115 v_n_bits += 8;
28116 }
28117 v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
28118 v_bits >>= v_table_entry_n_bits;
28119 v_n_bits -= v_table_entry_n_bits;
28120 while (true) {
28121 if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
28122 v_hlen = 0;
28123 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
28124 if (v_length > v_hdist) {
28125 v_length -= v_hdist;
28126 v_hlen = v_hdist;
28127 } else {
28128 v_hlen = v_length;
28129 v_length = 0;
28130 }
28131 v_hdist += v_hdist_adjustment;
28132 if (self->private_impl.f_history_index < v_hdist) {
28133 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
28134 goto exit;
28135 }
28136 wuffs_base__io_writer__limited_copy_u32_from_slice(
28137 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), ((self->private_impl.f_history_index - v_hdist) & 32767)));
28138 if (v_length == 0) {
28139 goto label__loop__continue;
28140 }
28141 if ((((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
28142 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
28143 goto exit;
28144 }
28145 }
28146 if ((v_dist_minus_1 + 1) >= 8) {
28147 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
28148 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28149 } else {
28150 wuffs_base__io_writer__limited_copy_u32_from_history_fast(
28151 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28152 }
28153 goto label__0__break;
28154 }
28155 label__0__break:;
28156 }
28157 label__loop__break:;
28158 while (v_n_bits >= 8) {
28159 v_n_bits -= 8;
28160 if (iop_a_src > io1_a_src) {
28161 iop_a_src--;
28162 } else {
28163 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
28164 goto exit;
28165 }
28166 }
28167 self->private_impl.f_bits = (v_bits & ((((uint32_t)(1)) << v_n_bits) - 1));
28168 self->private_impl.f_n_bits = v_n_bits;
28169 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
28170 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28171 goto exit;
28172 }
28173 goto exit;
28174 exit:
28175 if (a_dst) {
28176 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28177 }
28178 if (a_src) {
28179 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28180 }
28181
28182 return status;
28183 }
28184
28185 // -------- func deflate.decoder.decode_huffman_fast64
28186
28187 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_fast64(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)28188 wuffs_deflate__decoder__decode_huffman_fast64(
28189 wuffs_deflate__decoder* self,
28190 wuffs_base__io_buffer* a_dst,
28191 wuffs_base__io_buffer* a_src) {
28192 return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src);
28193 }
28194
28195 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)28196 wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
28197 wuffs_deflate__decoder* self,
28198 wuffs_base__io_buffer* a_dst,
28199 wuffs_base__io_buffer* a_src) {
28200 wuffs_base__status status = wuffs_base__make_status(NULL);
28201
28202 uint64_t v_bits = 0;
28203 uint32_t v_n_bits = 0;
28204 uint32_t v_table_entry = 0;
28205 uint32_t v_table_entry_n_bits = 0;
28206 uint64_t v_lmask = 0;
28207 uint64_t v_dmask = 0;
28208 uint32_t v_redir_top = 0;
28209 uint32_t v_redir_mask = 0;
28210 uint32_t v_length = 0;
28211 uint32_t v_dist_minus_1 = 0;
28212 uint32_t v_hlen = 0;
28213 uint32_t v_hdist = 0;
28214 uint32_t v_hdist_adjustment = 0;
28215
28216 uint8_t* iop_a_dst = NULL;
28217 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28218 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28219 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28220 if (a_dst) {
28221 io0_a_dst = a_dst->data.ptr;
28222 io1_a_dst = io0_a_dst + a_dst->meta.wi;
28223 iop_a_dst = io1_a_dst;
28224 io2_a_dst = io0_a_dst + a_dst->data.len;
28225 if (a_dst->meta.closed) {
28226 io2_a_dst = iop_a_dst;
28227 }
28228 }
28229 const uint8_t* iop_a_src = NULL;
28230 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28231 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28232 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28233 if (a_src) {
28234 io0_a_src = a_src->data.ptr;
28235 io1_a_src = io0_a_src + a_src->meta.ri;
28236 iop_a_src = io1_a_src;
28237 io2_a_src = io0_a_src + a_src->meta.wi;
28238 }
28239
28240 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
28241 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28242 goto exit;
28243 }
28244 v_bits = ((uint64_t)(self->private_impl.f_bits));
28245 v_n_bits = self->private_impl.f_n_bits;
28246 v_lmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
28247 v_dmask = ((((uint64_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
28248 if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0)) {
28249 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
28250 goto exit;
28251 }
28252 v_hdist_adjustment = ((uint32_t)(((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0)) & 4294967295)));
28253 label__loop__continue:;
28254 while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8)) {
28255 v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63)));
28256 iop_a_src += ((63 - (v_n_bits & 63)) >> 3);
28257 v_n_bits |= 56;
28258 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
28259 v_table_entry_n_bits = (v_table_entry & 15);
28260 v_bits >>= v_table_entry_n_bits;
28261 v_n_bits -= v_table_entry_n_bits;
28262 if ((v_table_entry >> 31) != 0) {
28263 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28264 goto label__loop__continue;
28265 } else if ((v_table_entry >> 30) != 0) {
28266 } else if ((v_table_entry >> 29) != 0) {
28267 self->private_impl.f_end_of_block = true;
28268 goto label__loop__break;
28269 } else if ((v_table_entry >> 28) != 0) {
28270 v_redir_top = ((v_table_entry >> 8) & 65535);
28271 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28272 v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
28273 v_table_entry_n_bits = (v_table_entry & 15);
28274 v_bits >>= v_table_entry_n_bits;
28275 v_n_bits -= v_table_entry_n_bits;
28276 if ((v_table_entry >> 31) != 0) {
28277 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(((v_table_entry >> 8) & 255)))), iop_a_dst += 1);
28278 goto label__loop__continue;
28279 } else if ((v_table_entry >> 30) != 0) {
28280 } else if ((v_table_entry >> 29) != 0) {
28281 self->private_impl.f_end_of_block = true;
28282 goto label__loop__break;
28283 } else if ((v_table_entry >> 28) != 0) {
28284 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28285 goto exit;
28286 } else if ((v_table_entry >> 27) != 0) {
28287 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28288 goto exit;
28289 } else {
28290 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28291 goto exit;
28292 }
28293 } else if ((v_table_entry >> 27) != 0) {
28294 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28295 goto exit;
28296 } else {
28297 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28298 goto exit;
28299 }
28300 v_length = (((v_table_entry >> 8) & 255) + 3);
28301 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28302 if (v_table_entry_n_bits > 0) {
28303 v_length = (((v_length + 253 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255) + 3);
28304 v_bits >>= v_table_entry_n_bits;
28305 v_n_bits -= v_table_entry_n_bits;
28306 }
28307 v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
28308 v_table_entry_n_bits = (v_table_entry & 15);
28309 v_bits >>= v_table_entry_n_bits;
28310 v_n_bits -= v_table_entry_n_bits;
28311 if ((v_table_entry >> 28) == 1) {
28312 v_redir_top = ((v_table_entry >> 8) & 65535);
28313 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28314 v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (((uint32_t)((v_bits & 4294967295))) & v_redir_mask)) & 1023)];
28315 v_table_entry_n_bits = (v_table_entry & 15);
28316 v_bits >>= v_table_entry_n_bits;
28317 v_n_bits -= v_table_entry_n_bits;
28318 }
28319 if ((v_table_entry >> 24) != 64) {
28320 if ((v_table_entry >> 24) == 8) {
28321 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28322 goto exit;
28323 }
28324 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28325 goto exit;
28326 }
28327 v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
28328 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28329 v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767);
28330 v_bits >>= v_table_entry_n_bits;
28331 v_n_bits -= v_table_entry_n_bits;
28332 while (true) {
28333 if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
28334 v_hlen = 0;
28335 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
28336 if (v_length > v_hdist) {
28337 v_length -= v_hdist;
28338 v_hlen = v_hdist;
28339 } else {
28340 v_hlen = v_length;
28341 v_length = 0;
28342 }
28343 v_hdist += v_hdist_adjustment;
28344 if (self->private_impl.f_history_index < v_hdist) {
28345 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
28346 goto exit;
28347 }
28348 wuffs_base__io_writer__limited_copy_u32_from_slice(
28349 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), ((self->private_impl.f_history_index - v_hdist) & 32767)));
28350 if (v_length == 0) {
28351 goto label__loop__continue;
28352 }
28353 if ((((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
28354 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
28355 goto exit;
28356 }
28357 }
28358 if ((v_dist_minus_1 + 1) >= 8) {
28359 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
28360 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28361 } else if ((v_dist_minus_1 + 1) == 1) {
28362 wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
28363 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28364 } else {
28365 wuffs_base__io_writer__limited_copy_u32_from_history_fast(
28366 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28367 }
28368 goto label__0__break;
28369 }
28370 label__0__break:;
28371 }
28372 label__loop__break:;
28373 if (v_n_bits > 63) {
28374 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28375 goto exit;
28376 }
28377 while (v_n_bits >= 8) {
28378 v_n_bits -= 8;
28379 if (iop_a_src > io1_a_src) {
28380 iop_a_src--;
28381 } else {
28382 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
28383 goto exit;
28384 }
28385 }
28386 self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1)) << v_n_bits) - 1))));
28387 self->private_impl.f_n_bits = v_n_bits;
28388 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0)) {
28389 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28390 goto exit;
28391 }
28392 goto exit;
28393 exit:
28394 if (a_dst) {
28395 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28396 }
28397 if (a_src) {
28398 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28399 }
28400
28401 return status;
28402 }
28403
28404 // -------- func deflate.decoder.decode_huffman_slow
28405
28406 static wuffs_base__status
wuffs_deflate__decoder__decode_huffman_slow(wuffs_deflate__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src)28407 wuffs_deflate__decoder__decode_huffman_slow(
28408 wuffs_deflate__decoder* self,
28409 wuffs_base__io_buffer* a_dst,
28410 wuffs_base__io_buffer* a_src) {
28411 wuffs_base__status status = wuffs_base__make_status(NULL);
28412
28413 uint32_t v_bits = 0;
28414 uint32_t v_n_bits = 0;
28415 uint32_t v_table_entry = 0;
28416 uint32_t v_table_entry_n_bits = 0;
28417 uint32_t v_lmask = 0;
28418 uint32_t v_dmask = 0;
28419 uint32_t v_b0 = 0;
28420 uint32_t v_redir_top = 0;
28421 uint32_t v_redir_mask = 0;
28422 uint32_t v_b1 = 0;
28423 uint32_t v_length = 0;
28424 uint32_t v_b2 = 0;
28425 uint32_t v_b3 = 0;
28426 uint32_t v_b4 = 0;
28427 uint32_t v_dist_minus_1 = 0;
28428 uint32_t v_b5 = 0;
28429 uint32_t v_n_copied = 0;
28430 uint32_t v_hlen = 0;
28431 uint32_t v_hdist = 0;
28432
28433 uint8_t* iop_a_dst = NULL;
28434 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28435 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28436 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28437 if (a_dst) {
28438 io0_a_dst = a_dst->data.ptr;
28439 io1_a_dst = io0_a_dst + a_dst->meta.wi;
28440 iop_a_dst = io1_a_dst;
28441 io2_a_dst = io0_a_dst + a_dst->data.len;
28442 if (a_dst->meta.closed) {
28443 io2_a_dst = iop_a_dst;
28444 }
28445 }
28446 const uint8_t* iop_a_src = NULL;
28447 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28448 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28449 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
28450 if (a_src) {
28451 io0_a_src = a_src->data.ptr;
28452 io1_a_src = io0_a_src + a_src->meta.ri;
28453 iop_a_src = io1_a_src;
28454 io2_a_src = io0_a_src + a_src->meta.wi;
28455 }
28456
28457 uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
28458 if (coro_susp_point) {
28459 v_bits = self->private_data.s_decode_huffman_slow[0].v_bits;
28460 v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits;
28461 v_table_entry = self->private_data.s_decode_huffman_slow[0].v_table_entry;
28462 v_table_entry_n_bits = self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits;
28463 v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask;
28464 v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask;
28465 v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top;
28466 v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask;
28467 v_length = self->private_data.s_decode_huffman_slow[0].v_length;
28468 v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1;
28469 v_hlen = self->private_data.s_decode_huffman_slow[0].v_hlen;
28470 }
28471 switch (coro_susp_point) {
28472 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28473
28474 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
28475 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28476 goto exit;
28477 }
28478 v_bits = self->private_impl.f_bits;
28479 v_n_bits = self->private_impl.f_n_bits;
28480 v_lmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[0]) - 1);
28481 v_dmask = ((((uint32_t)(1)) << self->private_impl.f_n_huffs_bits[1]) - 1);
28482 label__loop__continue:;
28483 while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
28484 while (true) {
28485 v_table_entry = self->private_data.f_huffs[0][(v_bits & v_lmask)];
28486 v_table_entry_n_bits = (v_table_entry & 15);
28487 if (v_n_bits >= v_table_entry_n_bits) {
28488 v_bits >>= v_table_entry_n_bits;
28489 v_n_bits -= v_table_entry_n_bits;
28490 goto label__0__break;
28491 }
28492 {
28493 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
28494 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28495 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28496 goto suspend;
28497 }
28498 uint32_t t_0 = *iop_a_src++;
28499 v_b0 = t_0;
28500 }
28501 v_bits |= (v_b0 << v_n_bits);
28502 v_n_bits += 8;
28503 }
28504 label__0__break:;
28505 if ((v_table_entry >> 31) != 0) {
28506 self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
28507 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
28508 if (iop_a_dst == io2_a_dst) {
28509 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28510 goto suspend;
28511 }
28512 *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
28513 goto label__loop__continue;
28514 } else if ((v_table_entry >> 30) != 0) {
28515 } else if ((v_table_entry >> 29) != 0) {
28516 self->private_impl.f_end_of_block = true;
28517 goto label__loop__break;
28518 } else if ((v_table_entry >> 28) != 0) {
28519 v_redir_top = ((v_table_entry >> 8) & 65535);
28520 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28521 while (true) {
28522 v_table_entry = self->private_data.f_huffs[0][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28523 v_table_entry_n_bits = (v_table_entry & 15);
28524 if (v_n_bits >= v_table_entry_n_bits) {
28525 v_bits >>= v_table_entry_n_bits;
28526 v_n_bits -= v_table_entry_n_bits;
28527 goto label__1__break;
28528 }
28529 {
28530 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
28531 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28532 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28533 goto suspend;
28534 }
28535 uint32_t t_1 = *iop_a_src++;
28536 v_b1 = t_1;
28537 }
28538 v_bits |= (v_b1 << v_n_bits);
28539 v_n_bits += 8;
28540 }
28541 label__1__break:;
28542 if ((v_table_entry >> 31) != 0) {
28543 self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)(((v_table_entry >> 8) & 255)));
28544 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
28545 if (iop_a_dst == io2_a_dst) {
28546 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28547 goto suspend;
28548 }
28549 *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
28550 goto label__loop__continue;
28551 } else if ((v_table_entry >> 30) != 0) {
28552 } else if ((v_table_entry >> 29) != 0) {
28553 self->private_impl.f_end_of_block = true;
28554 goto label__loop__break;
28555 } else if ((v_table_entry >> 28) != 0) {
28556 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28557 goto exit;
28558 } else if ((v_table_entry >> 27) != 0) {
28559 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28560 goto exit;
28561 } else {
28562 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28563 goto exit;
28564 }
28565 } else if ((v_table_entry >> 27) != 0) {
28566 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28567 goto exit;
28568 } else {
28569 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28570 goto exit;
28571 }
28572 v_length = (((v_table_entry >> 8) & 255) + 3);
28573 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28574 if (v_table_entry_n_bits > 0) {
28575 while (v_n_bits < v_table_entry_n_bits) {
28576 {
28577 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
28578 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28579 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28580 goto suspend;
28581 }
28582 uint32_t t_2 = *iop_a_src++;
28583 v_b2 = t_2;
28584 }
28585 v_bits |= (v_b2 << v_n_bits);
28586 v_n_bits += 8;
28587 }
28588 v_length = (((v_length + 253 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255) + 3);
28589 v_bits >>= v_table_entry_n_bits;
28590 v_n_bits -= v_table_entry_n_bits;
28591 }
28592 while (true) {
28593 v_table_entry = self->private_data.f_huffs[1][(v_bits & v_dmask)];
28594 v_table_entry_n_bits = (v_table_entry & 15);
28595 if (v_n_bits >= v_table_entry_n_bits) {
28596 v_bits >>= v_table_entry_n_bits;
28597 v_n_bits -= v_table_entry_n_bits;
28598 goto label__2__break;
28599 }
28600 {
28601 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
28602 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28603 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28604 goto suspend;
28605 }
28606 uint32_t t_3 = *iop_a_src++;
28607 v_b3 = t_3;
28608 }
28609 v_bits |= (v_b3 << v_n_bits);
28610 v_n_bits += 8;
28611 }
28612 label__2__break:;
28613 if ((v_table_entry >> 28) == 1) {
28614 v_redir_top = ((v_table_entry >> 8) & 65535);
28615 v_redir_mask = ((((uint32_t)(1)) << ((v_table_entry >> 4) & 15)) - 1);
28616 while (true) {
28617 v_table_entry = self->private_data.f_huffs[1][((v_redir_top + (v_bits & v_redir_mask)) & 1023)];
28618 v_table_entry_n_bits = (v_table_entry & 15);
28619 if (v_n_bits >= v_table_entry_n_bits) {
28620 v_bits >>= v_table_entry_n_bits;
28621 v_n_bits -= v_table_entry_n_bits;
28622 goto label__3__break;
28623 }
28624 {
28625 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
28626 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28627 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28628 goto suspend;
28629 }
28630 uint32_t t_4 = *iop_a_src++;
28631 v_b4 = t_4;
28632 }
28633 v_bits |= (v_b4 << v_n_bits);
28634 v_n_bits += 8;
28635 }
28636 label__3__break:;
28637 }
28638 if ((v_table_entry >> 24) != 64) {
28639 if ((v_table_entry >> 24) == 8) {
28640 status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
28641 goto exit;
28642 }
28643 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
28644 goto exit;
28645 }
28646 v_dist_minus_1 = ((v_table_entry >> 8) & 32767);
28647 v_table_entry_n_bits = ((v_table_entry >> 4) & 15);
28648 if (v_table_entry_n_bits > 0) {
28649 while (v_n_bits < v_table_entry_n_bits) {
28650 {
28651 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
28652 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
28653 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28654 goto suspend;
28655 }
28656 uint32_t t_5 = *iop_a_src++;
28657 v_b5 = t_5;
28658 }
28659 v_bits |= (v_b5 << v_n_bits);
28660 v_n_bits += 8;
28661 }
28662 v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767);
28663 v_bits >>= v_table_entry_n_bits;
28664 v_n_bits -= v_table_entry_n_bits;
28665 }
28666 label__inner__continue:;
28667 while (true) {
28668 if (((uint64_t)((v_dist_minus_1 + 1))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
28669 v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
28670 if (v_hdist < v_length) {
28671 v_hlen = v_hdist;
28672 } else {
28673 v_hlen = v_length;
28674 }
28675 v_hdist += ((uint32_t)((((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0))) & 4294967295)));
28676 if (self->private_impl.f_history_index < v_hdist) {
28677 status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
28678 goto exit;
28679 }
28680 v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
28681 &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_history, 33025), ((self->private_impl.f_history_index - v_hdist) & 32767)));
28682 if (v_n_copied < v_hlen) {
28683 v_length -= v_n_copied;
28684 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28685 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
28686 goto label__inner__continue;
28687 }
28688 v_length -= v_hlen;
28689 if (v_length == 0) {
28690 goto label__loop__continue;
28691 }
28692 }
28693 v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_history(
28694 &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1));
28695 if (v_length <= v_n_copied) {
28696 goto label__loop__continue;
28697 }
28698 v_length -= v_n_copied;
28699 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
28700 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
28701 }
28702 }
28703 label__loop__break:;
28704 self->private_impl.f_bits = v_bits;
28705 self->private_impl.f_n_bits = v_n_bits;
28706 if ((self->private_impl.f_n_bits >= 8) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7)) != 0)) {
28707 status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
28708 goto exit;
28709 }
28710
28711 ok:
28712 self->private_impl.p_decode_huffman_slow[0] = 0;
28713 goto exit;
28714 }
28715
28716 goto suspend;
28717 suspend:
28718 self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28719 self->private_data.s_decode_huffman_slow[0].v_bits = v_bits;
28720 self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits;
28721 self->private_data.s_decode_huffman_slow[0].v_table_entry = v_table_entry;
28722 self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits = v_table_entry_n_bits;
28723 self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask;
28724 self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask;
28725 self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top;
28726 self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask;
28727 self->private_data.s_decode_huffman_slow[0].v_length = v_length;
28728 self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1;
28729 self->private_data.s_decode_huffman_slow[0].v_hlen = v_hlen;
28730
28731 goto exit;
28732 exit:
28733 if (a_dst) {
28734 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
28735 }
28736 if (a_src) {
28737 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
28738 }
28739
28740 return status;
28741 }
28742
28743 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
28744
28745 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
28746
28747 // ---------------- Status Codes Implementations
28748
28749 const char wuffs_lzw__error__bad_code[] = "#lzw: bad code";
28750 const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O";
28751
28752 // ---------------- Private Consts
28753
28754 // ---------------- Private Initializer Prototypes
28755
28756 // ---------------- Private Function Prototypes
28757
28758 static wuffs_base__empty_struct
28759 wuffs_lzw__decoder__read_from(
28760 wuffs_lzw__decoder* self,
28761 wuffs_base__io_buffer* a_src);
28762
28763 static wuffs_base__status
28764 wuffs_lzw__decoder__write_to(
28765 wuffs_lzw__decoder* self,
28766 wuffs_base__io_buffer* a_dst);
28767
28768 // ---------------- VTables
28769
28770 const wuffs_base__io_transformer__func_ptrs
28771 wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = {
28772 (wuffs_base__empty_struct(*)(void*,
28773 uint32_t,
28774 bool))(&wuffs_lzw__decoder__set_quirk_enabled),
28775 (wuffs_base__status(*)(void*,
28776 wuffs_base__io_buffer*,
28777 wuffs_base__io_buffer*,
28778 wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io),
28779 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len),
28780 };
28781
28782 // ---------------- Initializer Implementations
28783
28784 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_lzw__decoder__initialize(wuffs_lzw__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)28785 wuffs_lzw__decoder__initialize(
28786 wuffs_lzw__decoder* self,
28787 size_t sizeof_star_self,
28788 uint64_t wuffs_version,
28789 uint32_t options){
28790 if (!self) {
28791 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28792 }
28793 if (sizeof(*self) != sizeof_star_self) {
28794 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
28795 }
28796 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
28797 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
28798 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
28799 }
28800
28801 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
28802 // The whole point of this if-check is to detect an uninitialized *self.
28803 // We disable the warning on GCC. Clang-5.0 does not have this warning.
28804 #if !defined(__clang__) && defined(__GNUC__)
28805 #pragma GCC diagnostic push
28806 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
28807 #endif
28808 if (self->private_impl.magic != 0) {
28809 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
28810 }
28811 #if !defined(__clang__) && defined(__GNUC__)
28812 #pragma GCC diagnostic pop
28813 #endif
28814 } else {
28815 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
28816 memset(self, 0, sizeof(*self));
28817 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
28818 } else {
28819 memset(&(self->private_impl), 0, sizeof(self->private_impl));
28820 }
28821 }
28822
28823 self->private_impl.magic = WUFFS_BASE__MAGIC;
28824 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
28825 wuffs_base__io_transformer__vtable_name;
28826 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
28827 (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer);
28828 return wuffs_base__make_status(NULL);
28829 }
28830
28831 wuffs_lzw__decoder*
wuffs_lzw__decoder__alloc()28832 wuffs_lzw__decoder__alloc() {
28833 wuffs_lzw__decoder* x =
28834 (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
28835 if (!x) {
28836 return NULL;
28837 }
28838 if (wuffs_lzw__decoder__initialize(
28839 x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
28840 free(x);
28841 return NULL;
28842 }
28843 return x;
28844 }
28845
28846 size_t
sizeof__wuffs_lzw__decoder()28847 sizeof__wuffs_lzw__decoder() {
28848 return sizeof(wuffs_lzw__decoder);
28849 }
28850
28851 // ---------------- Function Implementations
28852
28853 // -------- func lzw.decoder.set_quirk_enabled
28854
28855 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_lzw__decoder__set_quirk_enabled(wuffs_lzw__decoder * self,uint32_t a_quirk,bool a_enabled)28856 wuffs_lzw__decoder__set_quirk_enabled(
28857 wuffs_lzw__decoder* self,
28858 uint32_t a_quirk,
28859 bool a_enabled) {
28860 return wuffs_base__make_empty_struct();
28861 }
28862
28863 // -------- func lzw.decoder.set_literal_width
28864
28865 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_lzw__decoder__set_literal_width(wuffs_lzw__decoder * self,uint32_t a_lw)28866 wuffs_lzw__decoder__set_literal_width(
28867 wuffs_lzw__decoder* self,
28868 uint32_t a_lw) {
28869 if (!self) {
28870 return wuffs_base__make_empty_struct();
28871 }
28872 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28873 return wuffs_base__make_empty_struct();
28874 }
28875 if (a_lw > 8) {
28876 self->private_impl.magic = WUFFS_BASE__DISABLED;
28877 return wuffs_base__make_empty_struct();
28878 }
28879
28880 self->private_impl.f_set_literal_width_arg = (a_lw + 1);
28881 return wuffs_base__make_empty_struct();
28882 }
28883
28884 // -------- func lzw.decoder.workbuf_len
28885
28886 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder * self)28887 wuffs_lzw__decoder__workbuf_len(
28888 const wuffs_lzw__decoder* self) {
28889 if (!self) {
28890 return wuffs_base__utility__empty_range_ii_u64();
28891 }
28892 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
28893 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
28894 return wuffs_base__utility__empty_range_ii_u64();
28895 }
28896
28897 return wuffs_base__utility__make_range_ii_u64(0, 0);
28898 }
28899
28900 // -------- func lzw.decoder.transform_io
28901
28902 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_lzw__decoder__transform_io(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)28903 wuffs_lzw__decoder__transform_io(
28904 wuffs_lzw__decoder* self,
28905 wuffs_base__io_buffer* a_dst,
28906 wuffs_base__io_buffer* a_src,
28907 wuffs_base__slice_u8 a_workbuf) {
28908 if (!self) {
28909 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
28910 }
28911 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
28912 return wuffs_base__make_status(
28913 (self->private_impl.magic == WUFFS_BASE__DISABLED)
28914 ? wuffs_base__error__disabled_by_previous_error
28915 : wuffs_base__error__initialize_not_called);
28916 }
28917 if (!a_dst || !a_src) {
28918 self->private_impl.magic = WUFFS_BASE__DISABLED;
28919 return wuffs_base__make_status(wuffs_base__error__bad_argument);
28920 }
28921 if ((self->private_impl.active_coroutine != 0) &&
28922 (self->private_impl.active_coroutine != 1)) {
28923 self->private_impl.magic = WUFFS_BASE__DISABLED;
28924 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
28925 }
28926 self->private_impl.active_coroutine = 0;
28927 wuffs_base__status status = wuffs_base__make_status(NULL);
28928
28929 uint32_t v_i = 0;
28930
28931 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
28932 switch (coro_susp_point) {
28933 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
28934
28935 self->private_impl.f_literal_width = 8;
28936 if (self->private_impl.f_set_literal_width_arg > 0) {
28937 self->private_impl.f_literal_width = (self->private_impl.f_set_literal_width_arg - 1);
28938 }
28939 self->private_impl.f_clear_code = (((uint32_t)(1)) << self->private_impl.f_literal_width);
28940 self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1);
28941 self->private_impl.f_save_code = self->private_impl.f_end_code;
28942 self->private_impl.f_prev_code = self->private_impl.f_end_code;
28943 self->private_impl.f_width = (self->private_impl.f_literal_width + 1);
28944 self->private_impl.f_bits = 0;
28945 self->private_impl.f_n_bits = 0;
28946 self->private_impl.f_output_ri = 0;
28947 self->private_impl.f_output_wi = 0;
28948 v_i = 0;
28949 while (v_i < self->private_impl.f_clear_code) {
28950 self->private_data.f_lm1s[v_i] = 0;
28951 self->private_data.f_suffixes[v_i][0] = ((uint8_t)(v_i));
28952 v_i += 1;
28953 }
28954 label__0__continue:;
28955 while (true) {
28956 wuffs_lzw__decoder__read_from(self, a_src);
28957 if (self->private_impl.f_output_wi > 0) {
28958 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
28959 status = wuffs_lzw__decoder__write_to(self, a_dst);
28960 if (status.repr) {
28961 goto suspend;
28962 }
28963 }
28964 if (self->private_impl.f_read_from_return_value == 0) {
28965 goto label__0__break;
28966 } else if (self->private_impl.f_read_from_return_value == 1) {
28967 goto label__0__continue;
28968 } else if (self->private_impl.f_read_from_return_value == 2) {
28969 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
28970 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
28971 } else if (self->private_impl.f_read_from_return_value == 3) {
28972 status = wuffs_base__make_status(wuffs_lzw__error__bad_code);
28973 goto exit;
28974 } else {
28975 status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
28976 goto exit;
28977 }
28978 }
28979 label__0__break:;
28980
28981 ok:
28982 self->private_impl.p_transform_io[0] = 0;
28983 goto exit;
28984 }
28985
28986 goto suspend;
28987 suspend:
28988 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
28989 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
28990
28991 goto exit;
28992 exit:
28993 if (wuffs_base__status__is_error(&status)) {
28994 self->private_impl.magic = WUFFS_BASE__DISABLED;
28995 }
28996 return status;
28997 }
28998
28999 // -------- func lzw.decoder.read_from
29000
29001 static wuffs_base__empty_struct
wuffs_lzw__decoder__read_from(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_src)29002 wuffs_lzw__decoder__read_from(
29003 wuffs_lzw__decoder* self,
29004 wuffs_base__io_buffer* a_src) {
29005 uint32_t v_clear_code = 0;
29006 uint32_t v_end_code = 0;
29007 uint32_t v_save_code = 0;
29008 uint32_t v_prev_code = 0;
29009 uint32_t v_width = 0;
29010 uint32_t v_bits = 0;
29011 uint32_t v_n_bits = 0;
29012 uint32_t v_output_wi = 0;
29013 uint32_t v_code = 0;
29014 uint32_t v_c = 0;
29015 uint32_t v_o = 0;
29016 uint32_t v_steps = 0;
29017 uint8_t v_first_byte = 0;
29018 uint16_t v_lm1_b = 0;
29019 uint16_t v_lm1_a = 0;
29020
29021 const uint8_t* iop_a_src = NULL;
29022 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29023 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29024 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29025 if (a_src) {
29026 io0_a_src = a_src->data.ptr;
29027 io1_a_src = io0_a_src + a_src->meta.ri;
29028 iop_a_src = io1_a_src;
29029 io2_a_src = io0_a_src + a_src->meta.wi;
29030 }
29031
29032 v_clear_code = self->private_impl.f_clear_code;
29033 v_end_code = self->private_impl.f_end_code;
29034 v_save_code = self->private_impl.f_save_code;
29035 v_prev_code = self->private_impl.f_prev_code;
29036 v_width = self->private_impl.f_width;
29037 v_bits = self->private_impl.f_bits;
29038 v_n_bits = self->private_impl.f_n_bits;
29039 v_output_wi = self->private_impl.f_output_wi;
29040 while (true) {
29041 if (v_n_bits < v_width) {
29042 if (((uint64_t)(io2_a_src - iop_a_src)) >= 4) {
29043 v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
29044 iop_a_src += ((31 - v_n_bits) >> 3);
29045 v_n_bits |= 24;
29046 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29047 self->private_impl.f_read_from_return_value = 2;
29048 goto label__0__break;
29049 } else {
29050 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
29051 iop_a_src += 1;
29052 v_n_bits += 8;
29053 if (v_n_bits >= v_width) {
29054 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29055 self->private_impl.f_read_from_return_value = 2;
29056 goto label__0__break;
29057 } else {
29058 v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
29059 iop_a_src += 1;
29060 v_n_bits += 8;
29061 if (v_n_bits < v_width) {
29062 self->private_impl.f_read_from_return_value = 4;
29063 goto label__0__break;
29064 }
29065 }
29066 }
29067 }
29068 v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
29069 v_bits >>= v_width;
29070 v_n_bits -= v_width;
29071 if (v_code < v_clear_code) {
29072 self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
29073 v_output_wi = ((v_output_wi + 1) & 8191);
29074 if (v_save_code <= 4095) {
29075 v_lm1_a = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1)) & 4095);
29076 self->private_data.f_lm1s[v_save_code] = v_lm1_a;
29077 if ((v_lm1_a % 8) != 0) {
29078 self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
29079 memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code]));
29080 self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8)] = ((uint8_t)(v_code));
29081 } else {
29082 self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
29083 self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_code));
29084 }
29085 v_save_code += 1;
29086 if (v_width < 12) {
29087 v_width += (1 & (v_save_code >> v_width));
29088 }
29089 v_prev_code = v_code;
29090 }
29091 } else if (v_code <= v_end_code) {
29092 if (v_code == v_end_code) {
29093 self->private_impl.f_read_from_return_value = 0;
29094 goto label__0__break;
29095 }
29096 v_save_code = v_end_code;
29097 v_prev_code = v_end_code;
29098 v_width = (self->private_impl.f_literal_width + 1);
29099 } else if (v_code <= v_save_code) {
29100 v_c = v_code;
29101 if (v_code == v_save_code) {
29102 v_c = v_prev_code;
29103 }
29104 v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288)) & 8191);
29105 v_output_wi = ((v_output_wi + 1 + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191);
29106 v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3);
29107 while (true) {
29108 memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8);
29109 if (v_steps <= 0) {
29110 goto label__1__break;
29111 }
29112 v_steps -= 1;
29113 v_o = (((uint32_t)(v_o - 8)) & 8191);
29114 v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
29115 }
29116 label__1__break:;
29117 v_first_byte = self->private_data.f_suffixes[v_c][0];
29118 if (v_code == v_save_code) {
29119 self->private_data.f_output[v_output_wi] = v_first_byte;
29120 v_output_wi = ((v_output_wi + 1) & 8191);
29121 }
29122 if (v_save_code <= 4095) {
29123 v_lm1_b = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1)) & 4095);
29124 self->private_data.f_lm1s[v_save_code] = v_lm1_b;
29125 if ((v_lm1_b % 8) != 0) {
29126 self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
29127 memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code]));
29128 self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8)] = v_first_byte;
29129 } else {
29130 self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
29131 self->private_data.f_suffixes[v_save_code][0] = ((uint8_t)(v_first_byte));
29132 }
29133 v_save_code += 1;
29134 if (v_width < 12) {
29135 v_width += (1 & (v_save_code >> v_width));
29136 }
29137 v_prev_code = v_code;
29138 }
29139 } else {
29140 self->private_impl.f_read_from_return_value = 3;
29141 goto label__0__break;
29142 }
29143 if (v_output_wi > 4095) {
29144 self->private_impl.f_read_from_return_value = 1;
29145 goto label__0__break;
29146 }
29147 }
29148 label__0__break:;
29149 if (self->private_impl.f_read_from_return_value != 2) {
29150 while (v_n_bits >= 8) {
29151 v_n_bits -= 8;
29152 if (iop_a_src > io1_a_src) {
29153 iop_a_src--;
29154 } else {
29155 self->private_impl.f_read_from_return_value = 4;
29156 goto label__2__break;
29157 }
29158 }
29159 label__2__break:;
29160 }
29161 self->private_impl.f_save_code = v_save_code;
29162 self->private_impl.f_prev_code = v_prev_code;
29163 self->private_impl.f_width = v_width;
29164 self->private_impl.f_bits = v_bits;
29165 self->private_impl.f_n_bits = v_n_bits;
29166 self->private_impl.f_output_wi = v_output_wi;
29167 if (a_src) {
29168 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29169 }
29170
29171 return wuffs_base__make_empty_struct();
29172 }
29173
29174 // -------- func lzw.decoder.write_to
29175
29176 static wuffs_base__status
wuffs_lzw__decoder__write_to(wuffs_lzw__decoder * self,wuffs_base__io_buffer * a_dst)29177 wuffs_lzw__decoder__write_to(
29178 wuffs_lzw__decoder* self,
29179 wuffs_base__io_buffer* a_dst) {
29180 wuffs_base__status status = wuffs_base__make_status(NULL);
29181
29182 wuffs_base__slice_u8 v_s = {0};
29183 uint64_t v_n = 0;
29184
29185 uint8_t* iop_a_dst = NULL;
29186 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29187 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29188 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29189 if (a_dst) {
29190 io0_a_dst = a_dst->data.ptr;
29191 io1_a_dst = io0_a_dst + a_dst->meta.wi;
29192 iop_a_dst = io1_a_dst;
29193 io2_a_dst = io0_a_dst + a_dst->data.len;
29194 if (a_dst->meta.closed) {
29195 io2_a_dst = iop_a_dst;
29196 }
29197 }
29198
29199 uint32_t coro_susp_point = self->private_impl.p_write_to[0];
29200 switch (coro_susp_point) {
29201 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29202
29203 while (self->private_impl.f_output_wi > 0) {
29204 if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
29205 status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
29206 goto exit;
29207 }
29208 v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
29209 8199),
29210 self->private_impl.f_output_ri,
29211 self->private_impl.f_output_wi);
29212 v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s);
29213 if (v_n == ((uint64_t)(v_s.len))) {
29214 self->private_impl.f_output_ri = 0;
29215 self->private_impl.f_output_wi = 0;
29216 status = wuffs_base__make_status(NULL);
29217 goto ok;
29218 }
29219 self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)((v_n & 4294967295))))) & 8191);
29220 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
29221 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
29222 }
29223
29224 ok:
29225 self->private_impl.p_write_to[0] = 0;
29226 goto exit;
29227 }
29228
29229 goto suspend;
29230 suspend:
29231 self->private_impl.p_write_to[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29232
29233 goto exit;
29234 exit:
29235 if (a_dst) {
29236 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
29237 }
29238
29239 return status;
29240 }
29241
29242 // -------- func lzw.decoder.flush
29243
29244 WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
wuffs_lzw__decoder__flush(wuffs_lzw__decoder * self)29245 wuffs_lzw__decoder__flush(
29246 wuffs_lzw__decoder* self) {
29247 if (!self) {
29248 return wuffs_base__make_slice_u8(NULL, 0);
29249 }
29250 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29251 return wuffs_base__make_slice_u8(NULL, 0);
29252 }
29253
29254 wuffs_base__slice_u8 v_s = {0};
29255
29256 if (self->private_impl.f_output_ri <= self->private_impl.f_output_wi) {
29257 v_s = wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_output,
29258 8199),
29259 self->private_impl.f_output_ri,
29260 self->private_impl.f_output_wi);
29261 }
29262 self->private_impl.f_output_ri = 0;
29263 self->private_impl.f_output_wi = 0;
29264 return v_s;
29265 }
29266
29267 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
29268
29269 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
29270
29271 // ---------------- Status Codes Implementations
29272
29273 const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label";
29274 const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size";
29275 const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control";
29276 const char wuffs_gif__error__bad_header[] = "#gif: bad header";
29277 const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width";
29278 const char wuffs_gif__error__bad_palette[] = "#gif: bad palette";
29279 const char wuffs_gif__error__internal_error_inconsistent_ri_wi[] = "#gif: internal error: inconsistent ri/wi";
29280
29281 // ---------------- Private Consts
29282
29283 static const uint32_t
29284 WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
29285 4294967295, 1, 2, 4, 0,
29286 };
29287
29288 static const uint8_t
29289 WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
29290 1, 2, 4, 8, 8,
29291 };
29292
29293 static const uint8_t
29294 WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
29295 0, 1, 2, 4, 8,
29296 };
29297
29298 static const uint8_t
29299 WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29300 65, 78, 73, 77, 69, 88, 84, 83,
29301 49, 46, 48,
29302 };
29303
29304 static const uint8_t
29305 WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29306 78, 69, 84, 83, 67, 65, 80, 69,
29307 50, 46, 48,
29308 };
29309
29310 static const uint8_t
29311 WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29312 73, 67, 67, 82, 71, 66, 71, 49,
29313 48, 49, 50,
29314 };
29315
29316 static const uint8_t
29317 WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
29318 88, 77, 80, 32, 68, 97, 116, 97,
29319 88, 77, 80,
29320 };
29321
29322 #define WUFFS_GIF__QUIRKS_BASE 1041635328
29323
29324 #define WUFFS_GIF__QUIRKS_COUNT 7
29325
29326 // ---------------- Private Initializer Prototypes
29327
29328 // ---------------- Private Function Prototypes
29329
29330 static wuffs_base__status
29331 wuffs_gif__decoder__skip_frame(
29332 wuffs_gif__decoder* self,
29333 wuffs_base__io_buffer* a_src);
29334
29335 static wuffs_base__empty_struct
29336 wuffs_gif__decoder__reset_gc(
29337 wuffs_gif__decoder* self);
29338
29339 static wuffs_base__status
29340 wuffs_gif__decoder__decode_up_to_id_part1(
29341 wuffs_gif__decoder* self,
29342 wuffs_base__io_buffer* a_src);
29343
29344 static wuffs_base__status
29345 wuffs_gif__decoder__decode_header(
29346 wuffs_gif__decoder* self,
29347 wuffs_base__io_buffer* a_src);
29348
29349 static wuffs_base__status
29350 wuffs_gif__decoder__decode_lsd(
29351 wuffs_gif__decoder* self,
29352 wuffs_base__io_buffer* a_src);
29353
29354 static wuffs_base__status
29355 wuffs_gif__decoder__decode_extension(
29356 wuffs_gif__decoder* self,
29357 wuffs_base__io_buffer* a_src);
29358
29359 static wuffs_base__status
29360 wuffs_gif__decoder__skip_blocks(
29361 wuffs_gif__decoder* self,
29362 wuffs_base__io_buffer* a_src);
29363
29364 static wuffs_base__status
29365 wuffs_gif__decoder__decode_ae(
29366 wuffs_gif__decoder* self,
29367 wuffs_base__io_buffer* a_src);
29368
29369 static wuffs_base__status
29370 wuffs_gif__decoder__decode_gc(
29371 wuffs_gif__decoder* self,
29372 wuffs_base__io_buffer* a_src);
29373
29374 static wuffs_base__status
29375 wuffs_gif__decoder__decode_id_part0(
29376 wuffs_gif__decoder* self,
29377 wuffs_base__io_buffer* a_src);
29378
29379 static wuffs_base__status
29380 wuffs_gif__decoder__decode_id_part1(
29381 wuffs_gif__decoder* self,
29382 wuffs_base__pixel_buffer* a_dst,
29383 wuffs_base__io_buffer* a_src,
29384 wuffs_base__pixel_blend a_blend);
29385
29386 static wuffs_base__status
29387 wuffs_gif__decoder__decode_id_part2(
29388 wuffs_gif__decoder* self,
29389 wuffs_base__pixel_buffer* a_dst,
29390 wuffs_base__io_buffer* a_src,
29391 wuffs_base__slice_u8 a_workbuf);
29392
29393 static wuffs_base__status
29394 wuffs_gif__decoder__copy_to_image_buffer(
29395 wuffs_gif__decoder* self,
29396 wuffs_base__pixel_buffer* a_pb,
29397 wuffs_base__slice_u8 a_src);
29398
29399 // ---------------- VTables
29400
29401 const wuffs_base__image_decoder__func_ptrs
29402 wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = {
29403 (wuffs_base__status(*)(void*,
29404 wuffs_base__pixel_buffer*,
29405 wuffs_base__io_buffer*,
29406 wuffs_base__pixel_blend,
29407 wuffs_base__slice_u8,
29408 wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame),
29409 (wuffs_base__status(*)(void*,
29410 wuffs_base__frame_config*,
29411 wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config),
29412 (wuffs_base__status(*)(void*,
29413 wuffs_base__image_config*,
29414 wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config),
29415 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect),
29416 (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops),
29417 (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs),
29418 (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames),
29419 (wuffs_base__status(*)(void*,
29420 uint64_t,
29421 uint64_t))(&wuffs_gif__decoder__restart_frame),
29422 (wuffs_base__empty_struct(*)(void*,
29423 uint32_t,
29424 bool))(&wuffs_gif__decoder__set_quirk_enabled),
29425 (wuffs_base__empty_struct(*)(void*,
29426 uint32_t,
29427 bool))(&wuffs_gif__decoder__set_report_metadata),
29428 (wuffs_base__status(*)(void*,
29429 wuffs_base__io_buffer*,
29430 wuffs_base__more_information*,
29431 wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more),
29432 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len),
29433 };
29434
29435 // ---------------- Initializer Implementations
29436
29437 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_gif__decoder__initialize(wuffs_gif__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)29438 wuffs_gif__decoder__initialize(
29439 wuffs_gif__decoder* self,
29440 size_t sizeof_star_self,
29441 uint64_t wuffs_version,
29442 uint32_t options){
29443 if (!self) {
29444 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29445 }
29446 if (sizeof(*self) != sizeof_star_self) {
29447 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
29448 }
29449 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
29450 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
29451 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
29452 }
29453
29454 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
29455 // The whole point of this if-check is to detect an uninitialized *self.
29456 // We disable the warning on GCC. Clang-5.0 does not have this warning.
29457 #if !defined(__clang__) && defined(__GNUC__)
29458 #pragma GCC diagnostic push
29459 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
29460 #endif
29461 if (self->private_impl.magic != 0) {
29462 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
29463 }
29464 #if !defined(__clang__) && defined(__GNUC__)
29465 #pragma GCC diagnostic pop
29466 #endif
29467 } else {
29468 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
29469 memset(self, 0, sizeof(*self));
29470 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
29471 } else {
29472 memset(&(self->private_impl), 0, sizeof(self->private_impl));
29473 }
29474 }
29475
29476 {
29477 wuffs_base__status z = wuffs_lzw__decoder__initialize(
29478 &self->private_data.f_lzw, sizeof(self->private_data.f_lzw), WUFFS_VERSION, options);
29479 if (z.repr) {
29480 return z;
29481 }
29482 }
29483 self->private_impl.magic = WUFFS_BASE__MAGIC;
29484 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
29485 wuffs_base__image_decoder__vtable_name;
29486 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
29487 (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder);
29488 return wuffs_base__make_status(NULL);
29489 }
29490
29491 wuffs_gif__decoder*
wuffs_gif__decoder__alloc()29492 wuffs_gif__decoder__alloc() {
29493 wuffs_gif__decoder* x =
29494 (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
29495 if (!x) {
29496 return NULL;
29497 }
29498 if (wuffs_gif__decoder__initialize(
29499 x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
29500 free(x);
29501 return NULL;
29502 }
29503 return x;
29504 }
29505
29506 size_t
sizeof__wuffs_gif__decoder()29507 sizeof__wuffs_gif__decoder() {
29508 return sizeof(wuffs_gif__decoder);
29509 }
29510
29511 // ---------------- Function Implementations
29512
29513 // -------- func gif.decoder.set_quirk_enabled
29514
29515 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_gif__decoder__set_quirk_enabled(wuffs_gif__decoder * self,uint32_t a_quirk,bool a_enabled)29516 wuffs_gif__decoder__set_quirk_enabled(
29517 wuffs_gif__decoder* self,
29518 uint32_t a_quirk,
29519 bool a_enabled) {
29520 if (!self) {
29521 return wuffs_base__make_empty_struct();
29522 }
29523 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29524 return wuffs_base__make_empty_struct();
29525 }
29526
29527 if ((self->private_impl.f_call_sequence == 0) && (a_quirk >= 1041635328)) {
29528 a_quirk -= 1041635328;
29529 if (a_quirk < 7) {
29530 self->private_impl.f_quirks[a_quirk] = a_enabled;
29531 }
29532 }
29533 return wuffs_base__make_empty_struct();
29534 }
29535
29536 // -------- func gif.decoder.decode_image_config
29537
29538 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__decode_image_config(wuffs_gif__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)29539 wuffs_gif__decoder__decode_image_config(
29540 wuffs_gif__decoder* self,
29541 wuffs_base__image_config* a_dst,
29542 wuffs_base__io_buffer* a_src) {
29543 if (!self) {
29544 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29545 }
29546 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29547 return wuffs_base__make_status(
29548 (self->private_impl.magic == WUFFS_BASE__DISABLED)
29549 ? wuffs_base__error__disabled_by_previous_error
29550 : wuffs_base__error__initialize_not_called);
29551 }
29552 if (!a_src) {
29553 self->private_impl.magic = WUFFS_BASE__DISABLED;
29554 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29555 }
29556 if ((self->private_impl.active_coroutine != 0) &&
29557 (self->private_impl.active_coroutine != 1)) {
29558 self->private_impl.magic = WUFFS_BASE__DISABLED;
29559 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29560 }
29561 self->private_impl.active_coroutine = 0;
29562 wuffs_base__status status = wuffs_base__make_status(NULL);
29563
29564 bool v_ffio = false;
29565
29566 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
29567 switch (coro_susp_point) {
29568 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29569
29570 if (self->private_impl.f_call_sequence == 0) {
29571 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29572 status = wuffs_gif__decoder__decode_header(self, a_src);
29573 if (status.repr) {
29574 goto suspend;
29575 }
29576 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29577 status = wuffs_gif__decoder__decode_lsd(self, a_src);
29578 if (status.repr) {
29579 goto suspend;
29580 }
29581 } else if (self->private_impl.f_call_sequence != 2) {
29582 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29583 goto exit;
29584 }
29585 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
29586 status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
29587 if (status.repr) {
29588 goto suspend;
29589 }
29590 v_ffio = ! self->private_impl.f_gc_has_transparent_index;
29591 if ( ! self->private_impl.f_quirks[2]) {
29592 v_ffio = (v_ffio &&
29593 (self->private_impl.f_frame_rect_x0 == 0) &&
29594 (self->private_impl.f_frame_rect_y0 == 0) &&
29595 (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
29596 (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
29597 } else if (v_ffio) {
29598 self->private_impl.f_black_color_u32_argb_premul = 4278190080;
29599 }
29600 if (self->private_impl.f_background_color_u32_argb_premul == 77) {
29601 self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
29602 }
29603 if (a_dst != NULL) {
29604 wuffs_base__image_config__set(
29605 a_dst,
29606 2198077448,
29607 0,
29608 self->private_impl.f_width,
29609 self->private_impl.f_height,
29610 self->private_impl.f_frame_config_io_position,
29611 v_ffio);
29612 }
29613 self->private_impl.f_call_sequence = 3;
29614
29615 goto ok;
29616 ok:
29617 self->private_impl.p_decode_image_config[0] = 0;
29618 goto exit;
29619 }
29620
29621 goto suspend;
29622 suspend:
29623 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29624 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
29625
29626 goto exit;
29627 exit:
29628 if (wuffs_base__status__is_error(&status)) {
29629 self->private_impl.magic = WUFFS_BASE__DISABLED;
29630 }
29631 return status;
29632 }
29633
29634 // -------- func gif.decoder.set_report_metadata
29635
29636 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_gif__decoder__set_report_metadata(wuffs_gif__decoder * self,uint32_t a_fourcc,bool a_report)29637 wuffs_gif__decoder__set_report_metadata(
29638 wuffs_gif__decoder* self,
29639 uint32_t a_fourcc,
29640 bool a_report) {
29641 if (!self) {
29642 return wuffs_base__make_empty_struct();
29643 }
29644 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29645 return wuffs_base__make_empty_struct();
29646 }
29647
29648 if (a_fourcc == 1229144912) {
29649 self->private_impl.f_report_metadata_iccp = a_report;
29650 } else if (a_fourcc == 1481461792) {
29651 self->private_impl.f_report_metadata_xmp = a_report;
29652 }
29653 return wuffs_base__make_empty_struct();
29654 }
29655
29656 // -------- func gif.decoder.tell_me_more
29657
29658 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__tell_me_more(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)29659 wuffs_gif__decoder__tell_me_more(
29660 wuffs_gif__decoder* self,
29661 wuffs_base__io_buffer* a_dst,
29662 wuffs_base__more_information* a_minfo,
29663 wuffs_base__io_buffer* a_src) {
29664 if (!self) {
29665 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29666 }
29667 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29668 return wuffs_base__make_status(
29669 (self->private_impl.magic == WUFFS_BASE__DISABLED)
29670 ? wuffs_base__error__disabled_by_previous_error
29671 : wuffs_base__error__initialize_not_called);
29672 }
29673 if (!a_dst || !a_src) {
29674 self->private_impl.magic = WUFFS_BASE__DISABLED;
29675 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29676 }
29677 if ((self->private_impl.active_coroutine != 0) &&
29678 (self->private_impl.active_coroutine != 2)) {
29679 self->private_impl.magic = WUFFS_BASE__DISABLED;
29680 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29681 }
29682 self->private_impl.active_coroutine = 0;
29683 wuffs_base__status status = wuffs_base__make_status(NULL);
29684
29685 uint64_t v_chunk_length = 0;
29686
29687 const uint8_t* iop_a_src = NULL;
29688 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29689 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29690 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29691 if (a_src) {
29692 io0_a_src = a_src->data.ptr;
29693 io1_a_src = io0_a_src + a_src->meta.ri;
29694 iop_a_src = io1_a_src;
29695 io2_a_src = io0_a_src + a_src->meta.wi;
29696 }
29697
29698 uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
29699 switch (coro_susp_point) {
29700 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29701
29702 if (self->private_impl.f_call_sequence != 1) {
29703 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29704 goto exit;
29705 }
29706 if (self->private_impl.f_metadata_fourcc == 0) {
29707 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
29708 goto exit;
29709 }
29710 while (true) {
29711 label__0__continue:;
29712 while (true) {
29713 if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_io_position) {
29714 if (a_minfo != NULL) {
29715 wuffs_base__more_information__set(a_minfo,
29716 2,
29717 0,
29718 self->private_impl.f_metadata_io_position,
29719 0,
29720 0);
29721 }
29722 status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
29723 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
29724 goto label__0__continue;
29725 }
29726 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
29727 if (a_minfo != NULL) {
29728 wuffs_base__more_information__set(a_minfo,
29729 0,
29730 0,
29731 0,
29732 0,
29733 0);
29734 }
29735 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
29736 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
29737 goto label__0__continue;
29738 }
29739 goto label__0__break;
29740 }
29741 label__0__break:;
29742 v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
29743 if (v_chunk_length <= 0) {
29744 iop_a_src += 1;
29745 goto label__1__break;
29746 }
29747 if (self->private_impl.f_metadata_fourcc == 1481461792) {
29748 v_chunk_length += 1;
29749 } else {
29750 iop_a_src += 1;
29751 }
29752 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))), v_chunk_length);
29753 if (a_minfo != NULL) {
29754 wuffs_base__more_information__set(a_minfo,
29755 3,
29756 self->private_impl.f_metadata_fourcc,
29757 0,
29758 wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))),
29759 self->private_impl.f_metadata_io_position);
29760 }
29761 status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
29762 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
29763 }
29764 label__1__break:;
29765 if (a_minfo != NULL) {
29766 wuffs_base__more_information__set(a_minfo,
29767 3,
29768 self->private_impl.f_metadata_fourcc,
29769 0,
29770 self->private_impl.f_metadata_io_position,
29771 self->private_impl.f_metadata_io_position);
29772 }
29773 self->private_impl.f_call_sequence = 2;
29774 self->private_impl.f_metadata_fourcc = 0;
29775 self->private_impl.f_metadata_io_position = 0;
29776 status = wuffs_base__make_status(NULL);
29777 goto ok;
29778
29779 ok:
29780 self->private_impl.p_tell_me_more[0] = 0;
29781 goto exit;
29782 }
29783
29784 goto suspend;
29785 suspend:
29786 self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
29787 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
29788
29789 goto exit;
29790 exit:
29791 if (a_src) {
29792 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29793 }
29794
29795 if (wuffs_base__status__is_error(&status)) {
29796 self->private_impl.magic = WUFFS_BASE__DISABLED;
29797 }
29798 return status;
29799 }
29800
29801 // -------- func gif.decoder.num_animation_loops
29802
29803 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder * self)29804 wuffs_gif__decoder__num_animation_loops(
29805 const wuffs_gif__decoder* self) {
29806 if (!self) {
29807 return 0;
29808 }
29809 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29810 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29811 return 0;
29812 }
29813
29814 if (self->private_impl.f_seen_num_animation_loops_value) {
29815 return self->private_impl.f_num_animation_loops_value;
29816 }
29817 if (self->private_impl.f_num_decoded_frame_configs_value > 1) {
29818 return 1;
29819 }
29820 return 0;
29821 }
29822
29823 // -------- func gif.decoder.num_decoded_frame_configs
29824
29825 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder * self)29826 wuffs_gif__decoder__num_decoded_frame_configs(
29827 const wuffs_gif__decoder* self) {
29828 if (!self) {
29829 return 0;
29830 }
29831 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29832 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29833 return 0;
29834 }
29835
29836 return self->private_impl.f_num_decoded_frame_configs_value;
29837 }
29838
29839 // -------- func gif.decoder.num_decoded_frames
29840
29841 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder * self)29842 wuffs_gif__decoder__num_decoded_frames(
29843 const wuffs_gif__decoder* self) {
29844 if (!self) {
29845 return 0;
29846 }
29847 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29848 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29849 return 0;
29850 }
29851
29852 return self->private_impl.f_num_decoded_frames_value;
29853 }
29854
29855 // -------- func gif.decoder.frame_dirty_rect
29856
29857 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder * self)29858 wuffs_gif__decoder__frame_dirty_rect(
29859 const wuffs_gif__decoder* self) {
29860 if (!self) {
29861 return wuffs_base__utility__empty_rect_ie_u32();
29862 }
29863 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29864 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29865 return wuffs_base__utility__empty_rect_ie_u32();
29866 }
29867
29868 return wuffs_base__utility__make_rect_ie_u32(
29869 wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
29870 wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
29871 wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
29872 wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height));
29873 }
29874
29875 // -------- func gif.decoder.workbuf_len
29876
29877 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder * self)29878 wuffs_gif__decoder__workbuf_len(
29879 const wuffs_gif__decoder* self) {
29880 if (!self) {
29881 return wuffs_base__utility__empty_range_ii_u64();
29882 }
29883 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
29884 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
29885 return wuffs_base__utility__empty_range_ii_u64();
29886 }
29887
29888 return wuffs_base__utility__make_range_ii_u64(0, 0);
29889 }
29890
29891 // -------- func gif.decoder.restart_frame
29892
29893 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__restart_frame(wuffs_gif__decoder * self,uint64_t a_index,uint64_t a_io_position)29894 wuffs_gif__decoder__restart_frame(
29895 wuffs_gif__decoder* self,
29896 uint64_t a_index,
29897 uint64_t a_io_position) {
29898 if (!self) {
29899 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29900 }
29901 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29902 return wuffs_base__make_status(
29903 (self->private_impl.magic == WUFFS_BASE__DISABLED)
29904 ? wuffs_base__error__disabled_by_previous_error
29905 : wuffs_base__error__initialize_not_called);
29906 }
29907
29908 if (self->private_impl.f_call_sequence < 3) {
29909 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
29910 }
29911 self->private_impl.f_delayed_num_decoded_frames = false;
29912 self->private_impl.f_end_of_data = false;
29913 self->private_impl.f_restarted = true;
29914 self->private_impl.f_frame_config_io_position = a_io_position;
29915 self->private_impl.f_num_decoded_frame_configs_value = a_index;
29916 self->private_impl.f_num_decoded_frames_value = a_index;
29917 wuffs_gif__decoder__reset_gc(self);
29918 return wuffs_base__make_status(NULL);
29919 }
29920
29921 // -------- func gif.decoder.decode_frame_config
29922
29923 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__decode_frame_config(wuffs_gif__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)29924 wuffs_gif__decoder__decode_frame_config(
29925 wuffs_gif__decoder* self,
29926 wuffs_base__frame_config* a_dst,
29927 wuffs_base__io_buffer* a_src) {
29928 if (!self) {
29929 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
29930 }
29931 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
29932 return wuffs_base__make_status(
29933 (self->private_impl.magic == WUFFS_BASE__DISABLED)
29934 ? wuffs_base__error__disabled_by_previous_error
29935 : wuffs_base__error__initialize_not_called);
29936 }
29937 if (!a_src) {
29938 self->private_impl.magic = WUFFS_BASE__DISABLED;
29939 return wuffs_base__make_status(wuffs_base__error__bad_argument);
29940 }
29941 if ((self->private_impl.active_coroutine != 0) &&
29942 (self->private_impl.active_coroutine != 3)) {
29943 self->private_impl.magic = WUFFS_BASE__DISABLED;
29944 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
29945 }
29946 self->private_impl.active_coroutine = 0;
29947 wuffs_base__status status = wuffs_base__make_status(NULL);
29948
29949 uint32_t v_background_color = 0;
29950 uint8_t v_flags = 0;
29951
29952 const uint8_t* iop_a_src = NULL;
29953 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29954 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29955 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
29956 if (a_src) {
29957 io0_a_src = a_src->data.ptr;
29958 io1_a_src = io0_a_src + a_src->meta.ri;
29959 iop_a_src = io1_a_src;
29960 io2_a_src = io0_a_src + a_src->meta.wi;
29961 }
29962
29963 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
29964 if (coro_susp_point) {
29965 v_background_color = self->private_data.s_decode_frame_config[0].v_background_color;
29966 }
29967 switch (coro_susp_point) {
29968 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
29969
29970 self->private_impl.f_ignore_metadata = true;
29971 self->private_impl.f_dirty_max_excl_y = 0;
29972 if ( ! self->private_impl.f_end_of_data) {
29973 if (self->private_impl.f_call_sequence == 0) {
29974 if (a_src) {
29975 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29976 }
29977 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
29978 status = wuffs_gif__decoder__decode_image_config(self, NULL, a_src);
29979 if (a_src) {
29980 iop_a_src = a_src->data.ptr + a_src->meta.ri;
29981 }
29982 if (status.repr) {
29983 goto suspend;
29984 }
29985 } else if (self->private_impl.f_call_sequence != 3) {
29986 if (self->private_impl.f_call_sequence == 4) {
29987 if (a_src) {
29988 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
29989 }
29990 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
29991 status = wuffs_gif__decoder__skip_frame(self, a_src);
29992 if (a_src) {
29993 iop_a_src = a_src->data.ptr + a_src->meta.ri;
29994 }
29995 if (status.repr) {
29996 goto suspend;
29997 }
29998 }
29999 if (a_src) {
30000 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30001 }
30002 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30003 status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
30004 if (a_src) {
30005 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30006 }
30007 if (status.repr) {
30008 goto suspend;
30009 }
30010 }
30011 }
30012 if (self->private_impl.f_end_of_data) {
30013 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
30014 goto ok;
30015 }
30016 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
30017 if ( ! self->private_impl.f_gc_has_transparent_index) {
30018 v_background_color = self->private_impl.f_background_color_u32_argb_premul;
30019 if (self->private_impl.f_quirks[1] && (self->private_impl.f_num_decoded_frame_configs_value == 0)) {
30020 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
30021 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30022 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
30023 }
30024 v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
30025 if ((v_flags & 128) != 0) {
30026 v_background_color = self->private_impl.f_black_color_u32_argb_premul;
30027 }
30028 }
30029 }
30030 if (a_dst != NULL) {
30031 wuffs_base__frame_config__set(
30032 a_dst,
30033 wuffs_base__utility__make_rect_ie_u32(
30034 wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
30035 wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
30036 wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
30037 wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
30038 ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
30039 self->private_impl.f_num_decoded_frame_configs_value,
30040 self->private_impl.f_frame_config_io_position,
30041 self->private_impl.f_gc_disposal,
30042 ! self->private_impl.f_gc_has_transparent_index,
30043 false,
30044 v_background_color);
30045 }
30046 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
30047 self->private_impl.f_call_sequence = 4;
30048
30049 ok:
30050 self->private_impl.p_decode_frame_config[0] = 0;
30051 goto exit;
30052 }
30053
30054 goto suspend;
30055 suspend:
30056 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30057 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
30058 self->private_data.s_decode_frame_config[0].v_background_color = v_background_color;
30059
30060 goto exit;
30061 exit:
30062 if (a_src) {
30063 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30064 }
30065
30066 if (wuffs_base__status__is_error(&status)) {
30067 self->private_impl.magic = WUFFS_BASE__DISABLED;
30068 }
30069 return status;
30070 }
30071
30072 // -------- func gif.decoder.skip_frame
30073
30074 static wuffs_base__status
wuffs_gif__decoder__skip_frame(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30075 wuffs_gif__decoder__skip_frame(
30076 wuffs_gif__decoder* self,
30077 wuffs_base__io_buffer* a_src) {
30078 wuffs_base__status status = wuffs_base__make_status(NULL);
30079
30080 uint8_t v_flags = 0;
30081 uint8_t v_lw = 0;
30082
30083 const uint8_t* iop_a_src = NULL;
30084 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30085 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30086 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30087 if (a_src) {
30088 io0_a_src = a_src->data.ptr;
30089 io1_a_src = io0_a_src + a_src->meta.ri;
30090 iop_a_src = io1_a_src;
30091 io2_a_src = io0_a_src + a_src->meta.wi;
30092 }
30093
30094 uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
30095 switch (coro_susp_point) {
30096 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30097
30098 {
30099 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30100 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30101 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30102 goto suspend;
30103 }
30104 uint8_t t_0 = *iop_a_src++;
30105 v_flags = t_0;
30106 }
30107 if ((v_flags & 128) != 0) {
30108 self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3)) << (1 + (v_flags & 7)));
30109 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30110 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30111 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30112 iop_a_src = io2_a_src;
30113 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30114 goto suspend;
30115 }
30116 iop_a_src += self->private_data.s_skip_frame[0].scratch;
30117 }
30118 {
30119 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30120 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30121 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30122 goto suspend;
30123 }
30124 uint8_t t_1 = *iop_a_src++;
30125 v_lw = t_1;
30126 }
30127 if (v_lw > 8) {
30128 status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
30129 goto exit;
30130 }
30131 if (a_src) {
30132 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30133 }
30134 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30135 status = wuffs_gif__decoder__skip_blocks(self, a_src);
30136 if (a_src) {
30137 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30138 }
30139 if (status.repr) {
30140 goto suspend;
30141 }
30142 if (self->private_impl.f_quirks[0]) {
30143 self->private_impl.f_delayed_num_decoded_frames = true;
30144 } else {
30145 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30146 }
30147 wuffs_gif__decoder__reset_gc(self);
30148
30149 goto ok;
30150 ok:
30151 self->private_impl.p_skip_frame[0] = 0;
30152 goto exit;
30153 }
30154
30155 goto suspend;
30156 suspend:
30157 self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30158
30159 goto exit;
30160 exit:
30161 if (a_src) {
30162 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30163 }
30164
30165 return status;
30166 }
30167
30168 // -------- func gif.decoder.decode_frame
30169
30170 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gif__decoder__decode_frame(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)30171 wuffs_gif__decoder__decode_frame(
30172 wuffs_gif__decoder* self,
30173 wuffs_base__pixel_buffer* a_dst,
30174 wuffs_base__io_buffer* a_src,
30175 wuffs_base__pixel_blend a_blend,
30176 wuffs_base__slice_u8 a_workbuf,
30177 wuffs_base__decode_frame_options* a_opts) {
30178 if (!self) {
30179 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
30180 }
30181 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
30182 return wuffs_base__make_status(
30183 (self->private_impl.magic == WUFFS_BASE__DISABLED)
30184 ? wuffs_base__error__disabled_by_previous_error
30185 : wuffs_base__error__initialize_not_called);
30186 }
30187 if (!a_dst || !a_src) {
30188 self->private_impl.magic = WUFFS_BASE__DISABLED;
30189 return wuffs_base__make_status(wuffs_base__error__bad_argument);
30190 }
30191 if ((self->private_impl.active_coroutine != 0) &&
30192 (self->private_impl.active_coroutine != 4)) {
30193 self->private_impl.magic = WUFFS_BASE__DISABLED;
30194 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
30195 }
30196 self->private_impl.active_coroutine = 0;
30197 wuffs_base__status status = wuffs_base__make_status(NULL);
30198
30199 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
30200 switch (coro_susp_point) {
30201 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30202
30203 self->private_impl.f_ignore_metadata = true;
30204 if (self->private_impl.f_call_sequence != 4) {
30205 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30206 status = wuffs_gif__decoder__decode_frame_config(self, NULL, a_src);
30207 if (status.repr) {
30208 goto suspend;
30209 }
30210 }
30211 if (self->private_impl.f_quirks[5] && ((self->private_impl.f_frame_rect_x0 == self->private_impl.f_frame_rect_x1) || (self->private_impl.f_frame_rect_y0 == self->private_impl.f_frame_rect_y1))) {
30212 status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size);
30213 goto exit;
30214 }
30215 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30216 status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
30217 if (status.repr) {
30218 goto suspend;
30219 }
30220 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30221 status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
30222 if (status.repr) {
30223 goto suspend;
30224 }
30225 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30226 wuffs_gif__decoder__reset_gc(self);
30227
30228 goto ok;
30229 ok:
30230 self->private_impl.p_decode_frame[0] = 0;
30231 goto exit;
30232 }
30233
30234 goto suspend;
30235 suspend:
30236 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30237 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
30238
30239 goto exit;
30240 exit:
30241 if (wuffs_base__status__is_error(&status)) {
30242 self->private_impl.magic = WUFFS_BASE__DISABLED;
30243 }
30244 return status;
30245 }
30246
30247 // -------- func gif.decoder.reset_gc
30248
30249 static wuffs_base__empty_struct
wuffs_gif__decoder__reset_gc(wuffs_gif__decoder * self)30250 wuffs_gif__decoder__reset_gc(
30251 wuffs_gif__decoder* self) {
30252 self->private_impl.f_call_sequence = 5;
30253 self->private_impl.f_gc_has_transparent_index = false;
30254 self->private_impl.f_gc_transparent_index = 0;
30255 self->private_impl.f_gc_disposal = 0;
30256 self->private_impl.f_gc_duration = 0;
30257 return wuffs_base__make_empty_struct();
30258 }
30259
30260 // -------- func gif.decoder.decode_up_to_id_part1
30261
30262 static wuffs_base__status
wuffs_gif__decoder__decode_up_to_id_part1(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30263 wuffs_gif__decoder__decode_up_to_id_part1(
30264 wuffs_gif__decoder* self,
30265 wuffs_base__io_buffer* a_src) {
30266 wuffs_base__status status = wuffs_base__make_status(NULL);
30267
30268 uint8_t v_block_type = 0;
30269
30270 const uint8_t* iop_a_src = NULL;
30271 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30272 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30273 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30274 if (a_src) {
30275 io0_a_src = a_src->data.ptr;
30276 io1_a_src = io0_a_src + a_src->meta.ri;
30277 iop_a_src = io1_a_src;
30278 io2_a_src = io0_a_src + a_src->meta.wi;
30279 }
30280
30281 uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
30282 switch (coro_susp_point) {
30283 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30284
30285 if ( ! self->private_impl.f_restarted) {
30286 if (self->private_impl.f_call_sequence != 2) {
30287 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
30288 }
30289 } else if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
30290 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
30291 goto exit;
30292 } else {
30293 self->private_impl.f_restarted = false;
30294 }
30295 while (true) {
30296 {
30297 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30298 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30299 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30300 goto suspend;
30301 }
30302 uint8_t t_0 = *iop_a_src++;
30303 v_block_type = t_0;
30304 }
30305 if (v_block_type == 33) {
30306 if (a_src) {
30307 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30308 }
30309 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30310 status = wuffs_gif__decoder__decode_extension(self, a_src);
30311 if (a_src) {
30312 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30313 }
30314 if (status.repr) {
30315 goto suspend;
30316 }
30317 } else if (v_block_type == 44) {
30318 if (self->private_impl.f_delayed_num_decoded_frames) {
30319 self->private_impl.f_delayed_num_decoded_frames = false;
30320 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30321 }
30322 if (a_src) {
30323 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30324 }
30325 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30326 status = wuffs_gif__decoder__decode_id_part0(self, a_src);
30327 if (a_src) {
30328 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30329 }
30330 if (status.repr) {
30331 goto suspend;
30332 }
30333 goto label__0__break;
30334 } else {
30335 if (self->private_impl.f_delayed_num_decoded_frames) {
30336 self->private_impl.f_delayed_num_decoded_frames = false;
30337 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
30338 }
30339 self->private_impl.f_end_of_data = true;
30340 goto label__0__break;
30341 }
30342 }
30343 label__0__break:;
30344
30345 goto ok;
30346 ok:
30347 self->private_impl.p_decode_up_to_id_part1[0] = 0;
30348 goto exit;
30349 }
30350
30351 goto suspend;
30352 suspend:
30353 self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30354
30355 goto exit;
30356 exit:
30357 if (a_src) {
30358 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30359 }
30360
30361 return status;
30362 }
30363
30364 // -------- func gif.decoder.decode_header
30365
30366 static wuffs_base__status
wuffs_gif__decoder__decode_header(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30367 wuffs_gif__decoder__decode_header(
30368 wuffs_gif__decoder* self,
30369 wuffs_base__io_buffer* a_src) {
30370 wuffs_base__status status = wuffs_base__make_status(NULL);
30371
30372 uint8_t v_c[6] = {0};
30373 uint32_t v_i = 0;
30374
30375 const uint8_t* iop_a_src = NULL;
30376 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30377 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30378 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30379 if (a_src) {
30380 io0_a_src = a_src->data.ptr;
30381 io1_a_src = io0_a_src + a_src->meta.ri;
30382 iop_a_src = io1_a_src;
30383 io2_a_src = io0_a_src + a_src->meta.wi;
30384 }
30385
30386 uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
30387 if (coro_susp_point) {
30388 memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
30389 v_i = self->private_data.s_decode_header[0].v_i;
30390 }
30391 switch (coro_susp_point) {
30392 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30393
30394 while (v_i < 6) {
30395 {
30396 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30397 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30398 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30399 goto suspend;
30400 }
30401 uint8_t t_0 = *iop_a_src++;
30402 v_c[v_i] = t_0;
30403 }
30404 v_i += 1;
30405 }
30406 if ((v_c[0] != 71) ||
30407 (v_c[1] != 73) ||
30408 (v_c[2] != 70) ||
30409 (v_c[3] != 56) ||
30410 ((v_c[4] != 55) && (v_c[4] != 57)) ||
30411 (v_c[5] != 97)) {
30412 status = wuffs_base__make_status(wuffs_gif__error__bad_header);
30413 goto exit;
30414 }
30415
30416 goto ok;
30417 ok:
30418 self->private_impl.p_decode_header[0] = 0;
30419 goto exit;
30420 }
30421
30422 goto suspend;
30423 suspend:
30424 self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30425 memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
30426 self->private_data.s_decode_header[0].v_i = v_i;
30427
30428 goto exit;
30429 exit:
30430 if (a_src) {
30431 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30432 }
30433
30434 return status;
30435 }
30436
30437 // -------- func gif.decoder.decode_lsd
30438
30439 static wuffs_base__status
wuffs_gif__decoder__decode_lsd(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30440 wuffs_gif__decoder__decode_lsd(
30441 wuffs_gif__decoder* self,
30442 wuffs_base__io_buffer* a_src) {
30443 wuffs_base__status status = wuffs_base__make_status(NULL);
30444
30445 uint8_t v_flags = 0;
30446 uint8_t v_background_color_index = 0;
30447 uint32_t v_num_palette_entries = 0;
30448 uint32_t v_i = 0;
30449 uint32_t v_j = 0;
30450 uint32_t v_argb = 0;
30451
30452 const uint8_t* iop_a_src = NULL;
30453 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30454 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30455 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30456 if (a_src) {
30457 io0_a_src = a_src->data.ptr;
30458 io1_a_src = io0_a_src + a_src->meta.ri;
30459 iop_a_src = io1_a_src;
30460 io2_a_src = io0_a_src + a_src->meta.wi;
30461 }
30462
30463 uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
30464 if (coro_susp_point) {
30465 v_flags = self->private_data.s_decode_lsd[0].v_flags;
30466 v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index;
30467 v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries;
30468 v_i = self->private_data.s_decode_lsd[0].v_i;
30469 }
30470 switch (coro_susp_point) {
30471 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30472
30473 {
30474 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30475 uint32_t t_0;
30476 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30477 t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30478 iop_a_src += 2;
30479 } else {
30480 self->private_data.s_decode_lsd[0].scratch = 0;
30481 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30482 while (true) {
30483 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30484 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30485 goto suspend;
30486 }
30487 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30488 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
30489 *scratch <<= 8;
30490 *scratch >>= 8;
30491 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
30492 if (num_bits_0 == 8) {
30493 t_0 = ((uint32_t)(*scratch));
30494 break;
30495 }
30496 num_bits_0 += 8;
30497 *scratch |= ((uint64_t)(num_bits_0)) << 56;
30498 }
30499 }
30500 self->private_impl.f_width = t_0;
30501 }
30502 {
30503 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30504 uint32_t t_1;
30505 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30506 t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30507 iop_a_src += 2;
30508 } else {
30509 self->private_data.s_decode_lsd[0].scratch = 0;
30510 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30511 while (true) {
30512 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30513 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30514 goto suspend;
30515 }
30516 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30517 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
30518 *scratch <<= 8;
30519 *scratch >>= 8;
30520 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
30521 if (num_bits_1 == 8) {
30522 t_1 = ((uint32_t)(*scratch));
30523 break;
30524 }
30525 num_bits_1 += 8;
30526 *scratch |= ((uint64_t)(num_bits_1)) << 56;
30527 }
30528 }
30529 self->private_impl.f_height = t_1;
30530 }
30531 {
30532 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30533 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30534 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30535 goto suspend;
30536 }
30537 uint8_t t_2 = *iop_a_src++;
30538 v_flags = t_2;
30539 }
30540 {
30541 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30542 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30543 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30544 goto suspend;
30545 }
30546 uint8_t t_3 = *iop_a_src++;
30547 v_background_color_index = t_3;
30548 }
30549 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
30550 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30551 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30552 goto suspend;
30553 }
30554 iop_a_src++;
30555 v_i = 0;
30556 self->private_impl.f_has_global_palette = ((v_flags & 128) != 0);
30557 if (self->private_impl.f_has_global_palette) {
30558 v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
30559 while (v_i < v_num_palette_entries) {
30560 {
30561 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30562 uint32_t t_4;
30563 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
30564 t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
30565 iop_a_src += 3;
30566 } else {
30567 self->private_data.s_decode_lsd[0].scratch = 0;
30568 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
30569 while (true) {
30570 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30571 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30572 goto suspend;
30573 }
30574 uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
30575 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
30576 *scratch >>= 8;
30577 *scratch <<= 8;
30578 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
30579 if (num_bits_4 == 16) {
30580 t_4 = ((uint32_t)(*scratch >> 40));
30581 break;
30582 }
30583 num_bits_4 += 8;
30584 *scratch |= ((uint64_t)(num_bits_4));
30585 }
30586 }
30587 v_argb = t_4;
30588 }
30589 v_argb |= 4278190080;
30590 self->private_data.f_palettes[0][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
30591 self->private_data.f_palettes[0][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
30592 self->private_data.f_palettes[0][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
30593 self->private_data.f_palettes[0][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
30594 v_i += 1;
30595 }
30596 if (self->private_impl.f_quirks[2]) {
30597 if ((v_background_color_index != 0) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
30598 v_j = (4 * ((uint32_t)(v_background_color_index)));
30599 self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0][(v_j + 0)])) << 0) |
30600 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 1)])) << 8) |
30601 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 2)])) << 16) |
30602 (((uint32_t)(self->private_data.f_palettes[0][(v_j + 3)])) << 24));
30603 } else {
30604 self->private_impl.f_background_color_u32_argb_premul = 77;
30605 }
30606 }
30607 }
30608 while (v_i < 256) {
30609 self->private_data.f_palettes[0][((4 * v_i) + 0)] = 0;
30610 self->private_data.f_palettes[0][((4 * v_i) + 1)] = 0;
30611 self->private_data.f_palettes[0][((4 * v_i) + 2)] = 0;
30612 self->private_data.f_palettes[0][((4 * v_i) + 3)] = 255;
30613 v_i += 1;
30614 }
30615
30616 goto ok;
30617 ok:
30618 self->private_impl.p_decode_lsd[0] = 0;
30619 goto exit;
30620 }
30621
30622 goto suspend;
30623 suspend:
30624 self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30625 self->private_data.s_decode_lsd[0].v_flags = v_flags;
30626 self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index;
30627 self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries;
30628 self->private_data.s_decode_lsd[0].v_i = v_i;
30629
30630 goto exit;
30631 exit:
30632 if (a_src) {
30633 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30634 }
30635
30636 return status;
30637 }
30638
30639 // -------- func gif.decoder.decode_extension
30640
30641 static wuffs_base__status
wuffs_gif__decoder__decode_extension(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30642 wuffs_gif__decoder__decode_extension(
30643 wuffs_gif__decoder* self,
30644 wuffs_base__io_buffer* a_src) {
30645 wuffs_base__status status = wuffs_base__make_status(NULL);
30646
30647 uint8_t v_label = 0;
30648
30649 const uint8_t* iop_a_src = NULL;
30650 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30651 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30652 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30653 if (a_src) {
30654 io0_a_src = a_src->data.ptr;
30655 io1_a_src = io0_a_src + a_src->meta.ri;
30656 iop_a_src = io1_a_src;
30657 io2_a_src = io0_a_src + a_src->meta.wi;
30658 }
30659
30660 uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
30661 switch (coro_susp_point) {
30662 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30663
30664 {
30665 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30666 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30667 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30668 goto suspend;
30669 }
30670 uint8_t t_0 = *iop_a_src++;
30671 v_label = t_0;
30672 }
30673 if (v_label == 249) {
30674 if (a_src) {
30675 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30676 }
30677 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30678 status = wuffs_gif__decoder__decode_gc(self, a_src);
30679 if (a_src) {
30680 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30681 }
30682 if (status.repr) {
30683 goto suspend;
30684 }
30685 status = wuffs_base__make_status(NULL);
30686 goto ok;
30687 } else if (v_label == 255) {
30688 if (a_src) {
30689 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30690 }
30691 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30692 status = wuffs_gif__decoder__decode_ae(self, a_src);
30693 if (a_src) {
30694 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30695 }
30696 if (status.repr) {
30697 goto suspend;
30698 }
30699 status = wuffs_base__make_status(NULL);
30700 goto ok;
30701 }
30702 if (a_src) {
30703 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30704 }
30705 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30706 status = wuffs_gif__decoder__skip_blocks(self, a_src);
30707 if (a_src) {
30708 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30709 }
30710 if (status.repr) {
30711 goto suspend;
30712 }
30713
30714 ok:
30715 self->private_impl.p_decode_extension[0] = 0;
30716 goto exit;
30717 }
30718
30719 goto suspend;
30720 suspend:
30721 self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30722
30723 goto exit;
30724 exit:
30725 if (a_src) {
30726 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30727 }
30728
30729 return status;
30730 }
30731
30732 // -------- func gif.decoder.skip_blocks
30733
30734 static wuffs_base__status
wuffs_gif__decoder__skip_blocks(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30735 wuffs_gif__decoder__skip_blocks(
30736 wuffs_gif__decoder* self,
30737 wuffs_base__io_buffer* a_src) {
30738 wuffs_base__status status = wuffs_base__make_status(NULL);
30739
30740 uint8_t v_block_size = 0;
30741
30742 const uint8_t* iop_a_src = NULL;
30743 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30744 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30745 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30746 if (a_src) {
30747 io0_a_src = a_src->data.ptr;
30748 io1_a_src = io0_a_src + a_src->meta.ri;
30749 iop_a_src = io1_a_src;
30750 io2_a_src = io0_a_src + a_src->meta.wi;
30751 }
30752
30753 uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
30754 switch (coro_susp_point) {
30755 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30756
30757 while (true) {
30758 {
30759 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30760 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30761 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30762 goto suspend;
30763 }
30764 uint8_t t_0 = *iop_a_src++;
30765 v_block_size = t_0;
30766 }
30767 if (v_block_size == 0) {
30768 status = wuffs_base__make_status(NULL);
30769 goto ok;
30770 }
30771 self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
30772 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30773 if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30774 self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30775 iop_a_src = io2_a_src;
30776 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30777 goto suspend;
30778 }
30779 iop_a_src += self->private_data.s_skip_blocks[0].scratch;
30780 }
30781
30782 ok:
30783 self->private_impl.p_skip_blocks[0] = 0;
30784 goto exit;
30785 }
30786
30787 goto suspend;
30788 suspend:
30789 self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
30790
30791 goto exit;
30792 exit:
30793 if (a_src) {
30794 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30795 }
30796
30797 return status;
30798 }
30799
30800 // -------- func gif.decoder.decode_ae
30801
30802 static wuffs_base__status
wuffs_gif__decoder__decode_ae(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)30803 wuffs_gif__decoder__decode_ae(
30804 wuffs_gif__decoder* self,
30805 wuffs_base__io_buffer* a_src) {
30806 wuffs_base__status status = wuffs_base__make_status(NULL);
30807
30808 uint8_t v_c = 0;
30809 uint8_t v_block_size = 0;
30810 bool v_is_animexts = false;
30811 bool v_is_netscape = false;
30812 bool v_is_iccp = false;
30813 bool v_is_xmp = false;
30814
30815 const uint8_t* iop_a_src = NULL;
30816 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30817 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30818 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
30819 if (a_src) {
30820 io0_a_src = a_src->data.ptr;
30821 io1_a_src = io0_a_src + a_src->meta.ri;
30822 iop_a_src = io1_a_src;
30823 io2_a_src = io0_a_src + a_src->meta.wi;
30824 }
30825
30826 uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
30827 if (coro_susp_point) {
30828 v_block_size = self->private_data.s_decode_ae[0].v_block_size;
30829 v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
30830 v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
30831 v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
30832 v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
30833 }
30834 switch (coro_susp_point) {
30835 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
30836
30837 while (true) {
30838 if (self->private_impl.f_metadata_fourcc != 0) {
30839 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30840 goto ok;
30841 }
30842 {
30843 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
30844 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30845 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30846 goto suspend;
30847 }
30848 uint8_t t_0 = *iop_a_src++;
30849 v_block_size = t_0;
30850 }
30851 if (v_block_size == 0) {
30852 status = wuffs_base__make_status(NULL);
30853 goto ok;
30854 }
30855 if (v_block_size != 11) {
30856 self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
30857 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
30858 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30859 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30860 iop_a_src = io2_a_src;
30861 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30862 goto suspend;
30863 }
30864 iop_a_src += self->private_data.s_decode_ae[0].scratch;
30865 goto label__goto_done__break;
30866 }
30867 v_is_animexts = true;
30868 v_is_netscape = true;
30869 v_is_iccp = true;
30870 v_is_xmp = true;
30871 v_block_size = 0;
30872 while (v_block_size < 11) {
30873 {
30874 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
30875 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30876 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30877 goto suspend;
30878 }
30879 uint8_t t_1 = *iop_a_src++;
30880 v_c = t_1;
30881 }
30882 v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
30883 v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
30884 v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size]));
30885 v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size]));
30886 #if defined(__GNUC__)
30887 #pragma GCC diagnostic push
30888 #pragma GCC diagnostic ignored "-Wconversion"
30889 #endif
30890 v_block_size += 1;
30891 #if defined(__GNUC__)
30892 #pragma GCC diagnostic pop
30893 #endif
30894 }
30895 if (v_is_animexts || v_is_netscape) {
30896 {
30897 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
30898 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30899 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30900 goto suspend;
30901 }
30902 uint8_t t_2 = *iop_a_src++;
30903 v_block_size = t_2;
30904 }
30905 if (v_block_size != 3) {
30906 self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
30907 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
30908 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30909 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30910 iop_a_src = io2_a_src;
30911 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30912 goto suspend;
30913 }
30914 iop_a_src += self->private_data.s_decode_ae[0].scratch;
30915 goto label__goto_done__break;
30916 }
30917 {
30918 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
30919 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30920 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30921 goto suspend;
30922 }
30923 uint8_t t_3 = *iop_a_src++;
30924 v_c = t_3;
30925 }
30926 if (v_c != 1) {
30927 self->private_data.s_decode_ae[0].scratch = 2;
30928 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
30929 if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
30930 self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
30931 iop_a_src = io2_a_src;
30932 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30933 goto suspend;
30934 }
30935 iop_a_src += self->private_data.s_decode_ae[0].scratch;
30936 goto label__goto_done__break;
30937 }
30938 {
30939 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
30940 uint32_t t_4;
30941 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
30942 t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
30943 iop_a_src += 2;
30944 } else {
30945 self->private_data.s_decode_ae[0].scratch = 0;
30946 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
30947 while (true) {
30948 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
30949 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
30950 goto suspend;
30951 }
30952 uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
30953 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
30954 *scratch <<= 8;
30955 *scratch >>= 8;
30956 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
30957 if (num_bits_4 == 8) {
30958 t_4 = ((uint32_t)(*scratch));
30959 break;
30960 }
30961 num_bits_4 += 8;
30962 *scratch |= ((uint64_t)(num_bits_4)) << 56;
30963 }
30964 }
30965 self->private_impl.f_num_animation_loops_value = t_4;
30966 }
30967 self->private_impl.f_seen_num_animation_loops_value = true;
30968 if ((0 < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535)) {
30969 self->private_impl.f_num_animation_loops_value += 1;
30970 }
30971 } else if (self->private_impl.f_ignore_metadata) {
30972 } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
30973 self->private_impl.f_metadata_fourcc = 1229144912;
30974 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
30975 self->private_impl.f_call_sequence = 1;
30976 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30977 goto ok;
30978 } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
30979 self->private_impl.f_metadata_fourcc = 1481461792;
30980 self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
30981 self->private_impl.f_call_sequence = 1;
30982 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
30983 goto ok;
30984 }
30985 goto label__goto_done__break;
30986 }
30987 label__goto_done__break:;
30988 if (a_src) {
30989 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
30990 }
30991 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
30992 status = wuffs_gif__decoder__skip_blocks(self, a_src);
30993 if (a_src) {
30994 iop_a_src = a_src->data.ptr + a_src->meta.ri;
30995 }
30996 if (status.repr) {
30997 goto suspend;
30998 }
30999
31000 ok:
31001 self->private_impl.p_decode_ae[0] = 0;
31002 goto exit;
31003 }
31004
31005 goto suspend;
31006 suspend:
31007 self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31008 self->private_data.s_decode_ae[0].v_block_size = v_block_size;
31009 self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
31010 self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
31011 self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
31012 self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
31013
31014 goto exit;
31015 exit:
31016 if (a_src) {
31017 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31018 }
31019
31020 return status;
31021 }
31022
31023 // -------- func gif.decoder.decode_gc
31024
31025 static wuffs_base__status
wuffs_gif__decoder__decode_gc(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)31026 wuffs_gif__decoder__decode_gc(
31027 wuffs_gif__decoder* self,
31028 wuffs_base__io_buffer* a_src) {
31029 wuffs_base__status status = wuffs_base__make_status(NULL);
31030
31031 uint8_t v_c = 0;
31032 uint8_t v_flags = 0;
31033 uint16_t v_gc_duration_centiseconds = 0;
31034
31035 const uint8_t* iop_a_src = NULL;
31036 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31037 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31038 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31039 if (a_src) {
31040 io0_a_src = a_src->data.ptr;
31041 io1_a_src = io0_a_src + a_src->meta.ri;
31042 iop_a_src = io1_a_src;
31043 io2_a_src = io0_a_src + a_src->meta.wi;
31044 }
31045
31046 uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
31047 switch (coro_susp_point) {
31048 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31049
31050 {
31051 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31052 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31053 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31054 goto suspend;
31055 }
31056 uint8_t t_0 = *iop_a_src++;
31057 v_c = t_0;
31058 }
31059 if (v_c != 4) {
31060 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
31061 goto exit;
31062 }
31063 {
31064 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31065 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31066 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31067 goto suspend;
31068 }
31069 uint8_t t_1 = *iop_a_src++;
31070 v_flags = t_1;
31071 }
31072 self->private_impl.f_gc_has_transparent_index = ((v_flags & 1) != 0);
31073 v_flags = ((v_flags >> 2) & 7);
31074 if (v_flags == 2) {
31075 self->private_impl.f_gc_disposal = 1;
31076 } else if ((v_flags == 3) || (v_flags == 4)) {
31077 self->private_impl.f_gc_disposal = 2;
31078 } else {
31079 self->private_impl.f_gc_disposal = 0;
31080 }
31081 {
31082 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31083 uint16_t t_2;
31084 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31085 t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
31086 iop_a_src += 2;
31087 } else {
31088 self->private_data.s_decode_gc[0].scratch = 0;
31089 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31090 while (true) {
31091 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31092 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31093 goto suspend;
31094 }
31095 uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
31096 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
31097 *scratch <<= 8;
31098 *scratch >>= 8;
31099 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
31100 if (num_bits_2 == 8) {
31101 t_2 = ((uint16_t)(*scratch));
31102 break;
31103 }
31104 num_bits_2 += 8;
31105 *scratch |= ((uint64_t)(num_bits_2)) << 56;
31106 }
31107 }
31108 v_gc_duration_centiseconds = t_2;
31109 }
31110 self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000);
31111 {
31112 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31113 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31114 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31115 goto suspend;
31116 }
31117 uint8_t t_3 = *iop_a_src++;
31118 self->private_impl.f_gc_transparent_index = t_3;
31119 }
31120 {
31121 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31122 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31123 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31124 goto suspend;
31125 }
31126 uint8_t t_4 = *iop_a_src++;
31127 v_c = t_4;
31128 }
31129 if (v_c != 0) {
31130 status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
31131 goto exit;
31132 }
31133
31134 goto ok;
31135 ok:
31136 self->private_impl.p_decode_gc[0] = 0;
31137 goto exit;
31138 }
31139
31140 goto suspend;
31141 suspend:
31142 self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31143
31144 goto exit;
31145 exit:
31146 if (a_src) {
31147 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31148 }
31149
31150 return status;
31151 }
31152
31153 // -------- func gif.decoder.decode_id_part0
31154
31155 static wuffs_base__status
wuffs_gif__decoder__decode_id_part0(wuffs_gif__decoder * self,wuffs_base__io_buffer * a_src)31156 wuffs_gif__decoder__decode_id_part0(
31157 wuffs_gif__decoder* self,
31158 wuffs_base__io_buffer* a_src) {
31159 wuffs_base__status status = wuffs_base__make_status(NULL);
31160
31161 const uint8_t* iop_a_src = NULL;
31162 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31163 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31164 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31165 if (a_src) {
31166 io0_a_src = a_src->data.ptr;
31167 io1_a_src = io0_a_src + a_src->meta.ri;
31168 iop_a_src = io1_a_src;
31169 io2_a_src = io0_a_src + a_src->meta.wi;
31170 }
31171
31172 uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
31173 switch (coro_susp_point) {
31174 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31175
31176 {
31177 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31178 uint32_t t_0;
31179 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31180 t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31181 iop_a_src += 2;
31182 } else {
31183 self->private_data.s_decode_id_part0[0].scratch = 0;
31184 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31185 while (true) {
31186 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31187 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31188 goto suspend;
31189 }
31190 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31191 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
31192 *scratch <<= 8;
31193 *scratch >>= 8;
31194 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
31195 if (num_bits_0 == 8) {
31196 t_0 = ((uint32_t)(*scratch));
31197 break;
31198 }
31199 num_bits_0 += 8;
31200 *scratch |= ((uint64_t)(num_bits_0)) << 56;
31201 }
31202 }
31203 self->private_impl.f_frame_rect_x0 = t_0;
31204 }
31205 {
31206 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31207 uint32_t t_1;
31208 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31209 t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31210 iop_a_src += 2;
31211 } else {
31212 self->private_data.s_decode_id_part0[0].scratch = 0;
31213 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31214 while (true) {
31215 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31216 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31217 goto suspend;
31218 }
31219 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31220 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
31221 *scratch <<= 8;
31222 *scratch >>= 8;
31223 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
31224 if (num_bits_1 == 8) {
31225 t_1 = ((uint32_t)(*scratch));
31226 break;
31227 }
31228 num_bits_1 += 8;
31229 *scratch |= ((uint64_t)(num_bits_1)) << 56;
31230 }
31231 }
31232 self->private_impl.f_frame_rect_y0 = t_1;
31233 }
31234 {
31235 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31236 uint32_t t_2;
31237 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31238 t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31239 iop_a_src += 2;
31240 } else {
31241 self->private_data.s_decode_id_part0[0].scratch = 0;
31242 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31243 while (true) {
31244 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31245 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31246 goto suspend;
31247 }
31248 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31249 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
31250 *scratch <<= 8;
31251 *scratch >>= 8;
31252 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
31253 if (num_bits_2 == 8) {
31254 t_2 = ((uint32_t)(*scratch));
31255 break;
31256 }
31257 num_bits_2 += 8;
31258 *scratch |= ((uint64_t)(num_bits_2)) << 56;
31259 }
31260 }
31261 self->private_impl.f_frame_rect_x1 = t_2;
31262 }
31263 self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
31264 {
31265 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
31266 uint32_t t_3;
31267 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
31268 t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
31269 iop_a_src += 2;
31270 } else {
31271 self->private_data.s_decode_id_part0[0].scratch = 0;
31272 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
31273 while (true) {
31274 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31275 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31276 goto suspend;
31277 }
31278 uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
31279 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
31280 *scratch <<= 8;
31281 *scratch >>= 8;
31282 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
31283 if (num_bits_3 == 8) {
31284 t_3 = ((uint32_t)(*scratch));
31285 break;
31286 }
31287 num_bits_3 += 8;
31288 *scratch |= ((uint64_t)(num_bits_3)) << 56;
31289 }
31290 }
31291 self->private_impl.f_frame_rect_y1 = t_3;
31292 }
31293 self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
31294 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31295 self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
31296 if ((self->private_impl.f_call_sequence == 0) && ! self->private_impl.f_quirks[4]) {
31297 self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
31298 self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
31299 }
31300
31301 goto ok;
31302 ok:
31303 self->private_impl.p_decode_id_part0[0] = 0;
31304 goto exit;
31305 }
31306
31307 goto suspend;
31308 suspend:
31309 self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31310
31311 goto exit;
31312 exit:
31313 if (a_src) {
31314 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31315 }
31316
31317 return status;
31318 }
31319
31320 // -------- func gif.decoder.decode_id_part1
31321
31322 static wuffs_base__status
wuffs_gif__decoder__decode_id_part1(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend)31323 wuffs_gif__decoder__decode_id_part1(
31324 wuffs_gif__decoder* self,
31325 wuffs_base__pixel_buffer* a_dst,
31326 wuffs_base__io_buffer* a_src,
31327 wuffs_base__pixel_blend a_blend) {
31328 wuffs_base__status status = wuffs_base__make_status(NULL);
31329
31330 uint8_t v_flags = 0;
31331 uint8_t v_which_palette = 0;
31332 uint32_t v_num_palette_entries = 0;
31333 uint32_t v_i = 0;
31334 uint32_t v_argb = 0;
31335 wuffs_base__status v_status = wuffs_base__make_status(NULL);
31336 uint8_t v_lw = 0;
31337
31338 const uint8_t* iop_a_src = NULL;
31339 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31340 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31341 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31342 if (a_src) {
31343 io0_a_src = a_src->data.ptr;
31344 io1_a_src = io0_a_src + a_src->meta.ri;
31345 iop_a_src = io1_a_src;
31346 io2_a_src = io0_a_src + a_src->meta.wi;
31347 }
31348
31349 uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0];
31350 if (coro_susp_point) {
31351 v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette;
31352 v_num_palette_entries = self->private_data.s_decode_id_part1[0].v_num_palette_entries;
31353 v_i = self->private_data.s_decode_id_part1[0].v_i;
31354 }
31355 switch (coro_susp_point) {
31356 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31357
31358 {
31359 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31360 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31361 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31362 goto suspend;
31363 }
31364 uint8_t t_0 = *iop_a_src++;
31365 v_flags = t_0;
31366 }
31367 if ((v_flags & 64) != 0) {
31368 self->private_impl.f_interlace = 4;
31369 } else {
31370 self->private_impl.f_interlace = 0;
31371 }
31372 v_which_palette = 1;
31373 if ((v_flags & 128) != 0) {
31374 v_num_palette_entries = (((uint32_t)(1)) << (1 + (v_flags & 7)));
31375 v_i = 0;
31376 while (v_i < v_num_palette_entries) {
31377 {
31378 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
31379 uint32_t t_1;
31380 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
31381 t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
31382 iop_a_src += 3;
31383 } else {
31384 self->private_data.s_decode_id_part1[0].scratch = 0;
31385 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31386 while (true) {
31387 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31388 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31389 goto suspend;
31390 }
31391 uint64_t* scratch = &self->private_data.s_decode_id_part1[0].scratch;
31392 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
31393 *scratch >>= 8;
31394 *scratch <<= 8;
31395 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
31396 if (num_bits_1 == 16) {
31397 t_1 = ((uint32_t)(*scratch >> 40));
31398 break;
31399 }
31400 num_bits_1 += 8;
31401 *scratch |= ((uint64_t)(num_bits_1));
31402 }
31403 }
31404 v_argb = t_1;
31405 }
31406 v_argb |= 4278190080;
31407 self->private_data.f_palettes[1][((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
31408 self->private_data.f_palettes[1][((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
31409 self->private_data.f_palettes[1][((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
31410 self->private_data.f_palettes[1][((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
31411 v_i += 1;
31412 }
31413 while (v_i < 256) {
31414 self->private_data.f_palettes[1][((4 * v_i) + 0)] = 0;
31415 self->private_data.f_palettes[1][((4 * v_i) + 1)] = 0;
31416 self->private_data.f_palettes[1][((4 * v_i) + 2)] = 0;
31417 self->private_data.f_palettes[1][((4 * v_i) + 3)] = 255;
31418 v_i += 1;
31419 }
31420 } else if (self->private_impl.f_quirks[6] && ! self->private_impl.f_has_global_palette) {
31421 status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
31422 goto exit;
31423 } else if (self->private_impl.f_gc_has_transparent_index) {
31424 wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_palettes[1], 1024), wuffs_base__make_slice_u8(self->private_data.f_palettes[0], 1024));
31425 } else {
31426 v_which_palette = 0;
31427 }
31428 if (self->private_impl.f_gc_has_transparent_index) {
31429 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0)] = 0;
31430 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1)] = 0;
31431 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2)] = 0;
31432 self->private_data.f_palettes[1][((4 * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3)] = 0;
31433 }
31434 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
31435 wuffs_base__pixel_buffer__pixel_format(a_dst),
31436 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
31437 wuffs_base__utility__make_pixel_format(2198077448),
31438 wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024),
31439 a_blend);
31440 if ( ! wuffs_base__status__is_ok(&v_status)) {
31441 status = v_status;
31442 if (wuffs_base__status__is_error(&status)) {
31443 goto exit;
31444 } else if (wuffs_base__status__is_suspension(&status)) {
31445 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
31446 goto exit;
31447 }
31448 goto ok;
31449 }
31450 if (self->private_impl.f_previous_lzw_decode_ended_abruptly) {
31451 wuffs_base__ignore_status(wuffs_lzw__decoder__initialize(&self->private_data.f_lzw,
31452 sizeof (wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
31453 }
31454 {
31455 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31456 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31457 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31458 goto suspend;
31459 }
31460 uint8_t t_2 = *iop_a_src++;
31461 v_lw = t_2;
31462 }
31463 if (v_lw > 8) {
31464 status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
31465 goto exit;
31466 }
31467 wuffs_lzw__decoder__set_literal_width(&self->private_data.f_lzw, ((uint32_t)(v_lw)));
31468 self->private_impl.f_previous_lzw_decode_ended_abruptly = true;
31469
31470 ok:
31471 self->private_impl.p_decode_id_part1[0] = 0;
31472 goto exit;
31473 }
31474
31475 goto suspend;
31476 suspend:
31477 self->private_impl.p_decode_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31478 self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette;
31479 self->private_data.s_decode_id_part1[0].v_num_palette_entries = v_num_palette_entries;
31480 self->private_data.s_decode_id_part1[0].v_i = v_i;
31481
31482 goto exit;
31483 exit:
31484 if (a_src) {
31485 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31486 }
31487
31488 return status;
31489 }
31490
31491 // -------- func gif.decoder.decode_id_part2
31492
31493 static wuffs_base__status
wuffs_gif__decoder__decode_id_part2(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)31494 wuffs_gif__decoder__decode_id_part2(
31495 wuffs_gif__decoder* self,
31496 wuffs_base__pixel_buffer* a_dst,
31497 wuffs_base__io_buffer* a_src,
31498 wuffs_base__slice_u8 a_workbuf) {
31499 wuffs_base__io_buffer empty_io_buffer = wuffs_base__empty_io_buffer();
31500
31501 wuffs_base__status status = wuffs_base__make_status(NULL);
31502
31503 uint64_t v_block_size = 0;
31504 bool v_need_block_size = false;
31505 uint32_t v_n_copied = 0;
31506 uint64_t v_n_compressed = 0;
31507 wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
31508 wuffs_base__io_buffer* v_r = &u_r;
31509 const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31510 const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31511 const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31512 const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31513 uint64_t v_mark = 0;
31514 wuffs_base__status v_lzw_status = wuffs_base__make_status(NULL);
31515 wuffs_base__status v_copy_status = wuffs_base__make_status(NULL);
31516 wuffs_base__slice_u8 v_uncompressed = {0};
31517
31518 const uint8_t* iop_a_src = NULL;
31519 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31520 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31521 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
31522 if (a_src) {
31523 io0_a_src = a_src->data.ptr;
31524 io1_a_src = io0_a_src + a_src->meta.ri;
31525 iop_a_src = io1_a_src;
31526 io2_a_src = io0_a_src + a_src->meta.wi;
31527 }
31528
31529 uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0];
31530 if (coro_susp_point) {
31531 v_block_size = self->private_data.s_decode_id_part2[0].v_block_size;
31532 v_need_block_size = self->private_data.s_decode_id_part2[0].v_need_block_size;
31533 v_lzw_status = self->private_data.s_decode_id_part2[0].v_lzw_status;
31534 }
31535 switch (coro_susp_point) {
31536 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
31537
31538 v_need_block_size = true;
31539 label__outer__continue:;
31540 while (true) {
31541 if (v_need_block_size) {
31542 v_need_block_size = false;
31543 {
31544 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
31545 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
31546 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31547 goto suspend;
31548 }
31549 uint64_t t_0 = *iop_a_src++;
31550 v_block_size = t_0;
31551 }
31552 }
31553 if (v_block_size == 0) {
31554 goto label__outer__break;
31555 }
31556 while (((uint64_t)(io2_a_src - iop_a_src)) == 0) {
31557 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31558 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
31559 }
31560 if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) {
31561 self->private_impl.f_compressed_ri = 0;
31562 self->private_impl.f_compressed_wi = 0;
31563 }
31564 while (self->private_impl.f_compressed_wi <= 3841) {
31565 v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
31566 if (v_n_compressed <= 0) {
31567 goto label__0__break;
31568 }
31569 v_n_copied = wuffs_base__io_reader__limited_copy_u32_to_slice(
31570 &iop_a_src, io2_a_src,((uint32_t)((v_n_compressed & 4294967295))), wuffs_base__slice_u8__subslice_i(wuffs_base__make_slice_u8(self->private_data.f_compressed, 4096), self->private_impl.f_compressed_wi));
31571 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied)));
31572 wuffs_base__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied)));
31573 if (v_block_size > 0) {
31574 goto label__0__break;
31575 }
31576 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
31577 v_need_block_size = true;
31578 goto label__0__break;
31579 }
31580 v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
31581 iop_a_src += 1;
31582 }
31583 label__0__break:;
31584 label__inner__continue:;
31585 while (true) {
31586 if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096)) {
31587 status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31588 goto exit;
31589 }
31590 {
31591 wuffs_base__io_buffer* o_0_v_r = v_r;
31592 const uint8_t *o_0_iop_v_r = iop_v_r;
31593 const uint8_t *o_0_io0_v_r = io0_v_r;
31594 const uint8_t *o_0_io1_v_r = io1_v_r;
31595 const uint8_t *o_0_io2_v_r = io2_v_r;
31596 v_r = wuffs_base__io_reader__set(
31597 &u_r,
31598 &iop_v_r,
31599 &io0_v_r,
31600 &io1_v_r,
31601 &io2_v_r,
31602 wuffs_base__slice_u8__subslice_ij(wuffs_base__make_slice_u8(self->private_data.f_compressed,
31603 4096),
31604 self->private_impl.f_compressed_ri,
31605 self->private_impl.f_compressed_wi),
31606 0);
31607 v_mark = ((uint64_t)(iop_v_r - io0_v_r));
31608 {
31609 u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
31610 wuffs_base__status t_1 = wuffs_lzw__decoder__transform_io(&self->private_data.f_lzw, &empty_io_buffer, v_r, wuffs_base__utility__empty_slice_u8());
31611 v_lzw_status = t_1;
31612 iop_v_r = u_r.data.ptr + u_r.meta.ri;
31613 }
31614 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r))));
31615 v_r = o_0_v_r;
31616 iop_v_r = o_0_iop_v_r;
31617 io0_v_r = o_0_io0_v_r;
31618 io1_v_r = o_0_io1_v_r;
31619 io2_v_r = o_0_io2_v_r;
31620 }
31621 v_uncompressed = wuffs_lzw__decoder__flush(&self->private_data.f_lzw);
31622 if (((uint64_t)(v_uncompressed.len)) > 0) {
31623 v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(self, a_dst, v_uncompressed);
31624 if (wuffs_base__status__is_error(&v_copy_status)) {
31625 status = v_copy_status;
31626 goto exit;
31627 }
31628 }
31629 if (wuffs_base__status__is_ok(&v_lzw_status)) {
31630 self->private_impl.f_previous_lzw_decode_ended_abruptly = false;
31631 if (v_need_block_size || (v_block_size > 0)) {
31632 self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
31633 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
31634 if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31635 self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31636 iop_a_src = io2_a_src;
31637 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31638 goto suspend;
31639 }
31640 iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
31641 if (a_src) {
31642 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31643 }
31644 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
31645 status = wuffs_gif__decoder__skip_blocks(self, a_src);
31646 if (a_src) {
31647 iop_a_src = a_src->data.ptr + a_src->meta.ri;
31648 }
31649 if (status.repr) {
31650 goto suspend;
31651 }
31652 }
31653 goto label__outer__break;
31654 } else if (v_lzw_status.repr == wuffs_base__suspension__short_read) {
31655 goto label__outer__continue;
31656 } else if (v_lzw_status.repr == wuffs_base__suspension__short_write) {
31657 goto label__inner__continue;
31658 } else if (self->private_impl.f_quirks[3] && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) && (self->private_impl.f_interlace == 0)) {
31659 if (v_need_block_size || (v_block_size > 0)) {
31660 self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
31661 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
31662 if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
31663 self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
31664 iop_a_src = io2_a_src;
31665 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
31666 goto suspend;
31667 }
31668 iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
31669 if (a_src) {
31670 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31671 }
31672 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
31673 status = wuffs_gif__decoder__skip_blocks(self, a_src);
31674 if (a_src) {
31675 iop_a_src = a_src->data.ptr + a_src->meta.ri;
31676 }
31677 if (status.repr) {
31678 goto suspend;
31679 }
31680 }
31681 goto label__outer__break;
31682 }
31683 status = v_lzw_status;
31684 if (wuffs_base__status__is_error(&status)) {
31685 goto exit;
31686 } else if (wuffs_base__status__is_suspension(&status)) {
31687 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
31688 goto exit;
31689 }
31690 goto ok;
31691 }
31692 }
31693 label__outer__break:;
31694 self->private_impl.f_compressed_ri = 0;
31695 self->private_impl.f_compressed_wi = 0;
31696 if ((self->private_impl.f_dst_y < self->private_impl.f_frame_rect_y1) && (self->private_impl.f_frame_rect_x0 != self->private_impl.f_frame_rect_x1) && (self->private_impl.f_frame_rect_y0 != self->private_impl.f_frame_rect_y1)) {
31697 status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
31698 goto exit;
31699 }
31700
31701 ok:
31702 self->private_impl.p_decode_id_part2[0] = 0;
31703 goto exit;
31704 }
31705
31706 goto suspend;
31707 suspend:
31708 self->private_impl.p_decode_id_part2[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
31709 self->private_data.s_decode_id_part2[0].v_block_size = v_block_size;
31710 self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size;
31711 self->private_data.s_decode_id_part2[0].v_lzw_status = v_lzw_status;
31712
31713 goto exit;
31714 exit:
31715 if (a_src) {
31716 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
31717 }
31718
31719 return status;
31720 }
31721
31722 // -------- func gif.decoder.copy_to_image_buffer
31723
31724 static wuffs_base__status
wuffs_gif__decoder__copy_to_image_buffer(wuffs_gif__decoder * self,wuffs_base__pixel_buffer * a_pb,wuffs_base__slice_u8 a_src)31725 wuffs_gif__decoder__copy_to_image_buffer(
31726 wuffs_gif__decoder* self,
31727 wuffs_base__pixel_buffer* a_pb,
31728 wuffs_base__slice_u8 a_src) {
31729 wuffs_base__slice_u8 v_dst = {0};
31730 wuffs_base__slice_u8 v_src = {0};
31731 uint64_t v_width_in_bytes = 0;
31732 uint64_t v_n = 0;
31733 uint64_t v_src_ri = 0;
31734 wuffs_base__pixel_format v_pixfmt = {0};
31735 uint32_t v_bytes_per_pixel = 0;
31736 uint32_t v_bits_per_pixel = 0;
31737 wuffs_base__table_u8 v_tab = {0};
31738 uint64_t v_i = 0;
31739 uint64_t v_j = 0;
31740 uint32_t v_replicate_y0 = 0;
31741 uint32_t v_replicate_y1 = 0;
31742 wuffs_base__slice_u8 v_replicate_dst = {0};
31743 wuffs_base__slice_u8 v_replicate_src = {0};
31744
31745 v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
31746 v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt);
31747 if ((v_bits_per_pixel & 7) != 0) {
31748 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
31749 }
31750 v_bytes_per_pixel = (v_bits_per_pixel >> 3);
31751 v_width_in_bytes = (((uint64_t)(self->private_impl.f_width)) * ((uint64_t)(v_bytes_per_pixel)));
31752 v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0);
31753 label__0__continue:;
31754 while (v_src_ri < ((uint64_t)(a_src.len))) {
31755 v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
31756 if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
31757 if (self->private_impl.f_quirks[3]) {
31758 return wuffs_base__make_status(NULL);
31759 }
31760 return wuffs_base__make_status(wuffs_base__error__too_much_data);
31761 }
31762 v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
31763 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
31764 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0);
31765 } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) {
31766 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes);
31767 }
31768 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel)));
31769 if (v_i < ((uint64_t)(v_dst.len))) {
31770 v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel)));
31771 if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
31772 v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
31773 } else {
31774 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
31775 }
31776 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024), v_src);
31777 wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
31778 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
31779 self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1));
31780 }
31781 if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
31782 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31783 if (self->private_impl.f_interlace == 0) {
31784 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1);
31785 goto label__0__continue;
31786 }
31787 if ((self->private_impl.f_num_decoded_frames_value == 0) && ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1)) {
31788 v_replicate_src = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
31789 v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1);
31790 v_replicate_y1 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_COUNT[self->private_impl.f_interlace])));
31791 v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1);
31792 while (v_replicate_y0 < v_replicate_y1) {
31793 v_replicate_dst = wuffs_base__table_u8__row_u32(v_tab, v_replicate_y0);
31794 wuffs_base__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src);
31795 v_replicate_y0 += 1;
31796 }
31797 self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1);
31798 }
31799 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
31800 while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
31801 #if defined(__GNUC__)
31802 #pragma GCC diagnostic push
31803 #pragma GCC diagnostic ignored "-Wconversion"
31804 #endif
31805 self->private_impl.f_interlace -= 1;
31806 #if defined(__GNUC__)
31807 #pragma GCC diagnostic pop
31808 #endif
31809 self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]);
31810 }
31811 goto label__0__continue;
31812 }
31813 if (((uint64_t)(a_src.len)) == v_src_ri) {
31814 goto label__0__break;
31815 } else if (((uint64_t)(a_src.len)) < v_src_ri) {
31816 return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31817 }
31818 v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
31819 v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
31820 wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
31821 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
31822 if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
31823 self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
31824 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
31825 while ((self->private_impl.f_interlace > 0) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
31826 #if defined(__GNUC__)
31827 #pragma GCC diagnostic push
31828 #pragma GCC diagnostic ignored "-Wconversion"
31829 #endif
31830 self->private_impl.f_interlace -= 1;
31831 #if defined(__GNUC__)
31832 #pragma GCC diagnostic pop
31833 #endif
31834 self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]);
31835 }
31836 goto label__0__continue;
31837 }
31838 if (v_src_ri != ((uint64_t)(a_src.len))) {
31839 return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_ri_wi);
31840 }
31841 goto label__0__break;
31842 }
31843 label__0__break:;
31844 return wuffs_base__make_status(NULL);
31845 }
31846
31847 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
31848
31849 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
31850
31851 // ---------------- Status Codes Implementations
31852
31853 const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum";
31854 const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method";
31855 const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags";
31856 const char wuffs_gzip__error__bad_header[] = "#gzip: bad header";
31857
31858 // ---------------- Private Consts
31859
31860 // ---------------- Private Initializer Prototypes
31861
31862 // ---------------- Private Function Prototypes
31863
31864 // ---------------- VTables
31865
31866 const wuffs_base__io_transformer__func_ptrs
31867 wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
31868 (wuffs_base__empty_struct(*)(void*,
31869 uint32_t,
31870 bool))(&wuffs_gzip__decoder__set_quirk_enabled),
31871 (wuffs_base__status(*)(void*,
31872 wuffs_base__io_buffer*,
31873 wuffs_base__io_buffer*,
31874 wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io),
31875 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len),
31876 };
31877
31878 // ---------------- Initializer Implementations
31879
31880 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_gzip__decoder__initialize(wuffs_gzip__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)31881 wuffs_gzip__decoder__initialize(
31882 wuffs_gzip__decoder* self,
31883 size_t sizeof_star_self,
31884 uint64_t wuffs_version,
31885 uint32_t options){
31886 if (!self) {
31887 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
31888 }
31889 if (sizeof(*self) != sizeof_star_self) {
31890 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
31891 }
31892 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
31893 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
31894 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
31895 }
31896
31897 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
31898 // The whole point of this if-check is to detect an uninitialized *self.
31899 // We disable the warning on GCC. Clang-5.0 does not have this warning.
31900 #if !defined(__clang__) && defined(__GNUC__)
31901 #pragma GCC diagnostic push
31902 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
31903 #endif
31904 if (self->private_impl.magic != 0) {
31905 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
31906 }
31907 #if !defined(__clang__) && defined(__GNUC__)
31908 #pragma GCC diagnostic pop
31909 #endif
31910 } else {
31911 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
31912 memset(self, 0, sizeof(*self));
31913 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
31914 } else {
31915 memset(&(self->private_impl), 0, sizeof(self->private_impl));
31916 }
31917 }
31918
31919 {
31920 wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
31921 &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
31922 if (z.repr) {
31923 return z;
31924 }
31925 }
31926 {
31927 wuffs_base__status z = wuffs_deflate__decoder__initialize(
31928 &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
31929 if (z.repr) {
31930 return z;
31931 }
31932 }
31933 self->private_impl.magic = WUFFS_BASE__MAGIC;
31934 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
31935 wuffs_base__io_transformer__vtable_name;
31936 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
31937 (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
31938 return wuffs_base__make_status(NULL);
31939 }
31940
31941 wuffs_gzip__decoder*
wuffs_gzip__decoder__alloc()31942 wuffs_gzip__decoder__alloc() {
31943 wuffs_gzip__decoder* x =
31944 (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
31945 if (!x) {
31946 return NULL;
31947 }
31948 if (wuffs_gzip__decoder__initialize(
31949 x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
31950 free(x);
31951 return NULL;
31952 }
31953 return x;
31954 }
31955
31956 size_t
sizeof__wuffs_gzip__decoder()31957 sizeof__wuffs_gzip__decoder() {
31958 return sizeof(wuffs_gzip__decoder);
31959 }
31960
31961 // ---------------- Function Implementations
31962
31963 // -------- func gzip.decoder.set_quirk_enabled
31964
31965 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_gzip__decoder__set_quirk_enabled(wuffs_gzip__decoder * self,uint32_t a_quirk,bool a_enabled)31966 wuffs_gzip__decoder__set_quirk_enabled(
31967 wuffs_gzip__decoder* self,
31968 uint32_t a_quirk,
31969 bool a_enabled) {
31970 if (!self) {
31971 return wuffs_base__make_empty_struct();
31972 }
31973 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
31974 return wuffs_base__make_empty_struct();
31975 }
31976
31977 if (a_quirk == 1) {
31978 self->private_impl.f_ignore_checksum = a_enabled;
31979 }
31980 return wuffs_base__make_empty_struct();
31981 }
31982
31983 // -------- func gzip.decoder.workbuf_len
31984
31985 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_gzip__decoder__workbuf_len(const wuffs_gzip__decoder * self)31986 wuffs_gzip__decoder__workbuf_len(
31987 const wuffs_gzip__decoder* self) {
31988 if (!self) {
31989 return wuffs_base__utility__empty_range_ii_u64();
31990 }
31991 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
31992 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
31993 return wuffs_base__utility__empty_range_ii_u64();
31994 }
31995
31996 return wuffs_base__utility__make_range_ii_u64(1, 1);
31997 }
31998
31999 // -------- func gzip.decoder.transform_io
32000
32001 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_gzip__decoder__transform_io(wuffs_gzip__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)32002 wuffs_gzip__decoder__transform_io(
32003 wuffs_gzip__decoder* self,
32004 wuffs_base__io_buffer* a_dst,
32005 wuffs_base__io_buffer* a_src,
32006 wuffs_base__slice_u8 a_workbuf) {
32007 if (!self) {
32008 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32009 }
32010 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32011 return wuffs_base__make_status(
32012 (self->private_impl.magic == WUFFS_BASE__DISABLED)
32013 ? wuffs_base__error__disabled_by_previous_error
32014 : wuffs_base__error__initialize_not_called);
32015 }
32016 if (!a_dst || !a_src) {
32017 self->private_impl.magic = WUFFS_BASE__DISABLED;
32018 return wuffs_base__make_status(wuffs_base__error__bad_argument);
32019 }
32020 if ((self->private_impl.active_coroutine != 0) &&
32021 (self->private_impl.active_coroutine != 1)) {
32022 self->private_impl.magic = WUFFS_BASE__DISABLED;
32023 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32024 }
32025 self->private_impl.active_coroutine = 0;
32026 wuffs_base__status status = wuffs_base__make_status(NULL);
32027
32028 uint8_t v_c = 0;
32029 uint8_t v_flags = 0;
32030 uint16_t v_xlen = 0;
32031 uint64_t v_mark = 0;
32032 uint32_t v_checksum_got = 0;
32033 uint32_t v_decoded_length_got = 0;
32034 wuffs_base__status v_status = wuffs_base__make_status(NULL);
32035 uint32_t v_checksum_want = 0;
32036 uint32_t v_decoded_length_want = 0;
32037
32038 uint8_t* iop_a_dst = NULL;
32039 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32040 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32041 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32042 if (a_dst) {
32043 io0_a_dst = a_dst->data.ptr;
32044 io1_a_dst = io0_a_dst + a_dst->meta.wi;
32045 iop_a_dst = io1_a_dst;
32046 io2_a_dst = io0_a_dst + a_dst->data.len;
32047 if (a_dst->meta.closed) {
32048 io2_a_dst = iop_a_dst;
32049 }
32050 }
32051 const uint8_t* iop_a_src = NULL;
32052 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32053 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32054 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32055 if (a_src) {
32056 io0_a_src = a_src->data.ptr;
32057 io1_a_src = io0_a_src + a_src->meta.ri;
32058 iop_a_src = io1_a_src;
32059 io2_a_src = io0_a_src + a_src->meta.wi;
32060 }
32061
32062 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
32063 if (coro_susp_point) {
32064 v_flags = self->private_data.s_transform_io[0].v_flags;
32065 v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
32066 v_decoded_length_got = self->private_data.s_transform_io[0].v_decoded_length_got;
32067 v_checksum_want = self->private_data.s_transform_io[0].v_checksum_want;
32068 }
32069 switch (coro_susp_point) {
32070 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32071
32072 {
32073 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
32074 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32075 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32076 goto suspend;
32077 }
32078 uint8_t t_0 = *iop_a_src++;
32079 v_c = t_0;
32080 }
32081 if (v_c != 31) {
32082 status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
32083 goto exit;
32084 }
32085 {
32086 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
32087 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32088 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32089 goto suspend;
32090 }
32091 uint8_t t_1 = *iop_a_src++;
32092 v_c = t_1;
32093 }
32094 if (v_c != 139) {
32095 status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
32096 goto exit;
32097 }
32098 {
32099 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
32100 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32101 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32102 goto suspend;
32103 }
32104 uint8_t t_2 = *iop_a_src++;
32105 v_c = t_2;
32106 }
32107 if (v_c != 8) {
32108 status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method);
32109 goto exit;
32110 }
32111 {
32112 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
32113 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32114 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32115 goto suspend;
32116 }
32117 uint8_t t_3 = *iop_a_src++;
32118 v_flags = t_3;
32119 }
32120 self->private_data.s_transform_io[0].scratch = 6;
32121 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
32122 if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32123 self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32124 iop_a_src = io2_a_src;
32125 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32126 goto suspend;
32127 }
32128 iop_a_src += self->private_data.s_transform_io[0].scratch;
32129 if ((v_flags & 4) != 0) {
32130 {
32131 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
32132 uint16_t t_4;
32133 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
32134 t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
32135 iop_a_src += 2;
32136 } else {
32137 self->private_data.s_transform_io[0].scratch = 0;
32138 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
32139 while (true) {
32140 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32141 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32142 goto suspend;
32143 }
32144 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
32145 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
32146 *scratch <<= 8;
32147 *scratch >>= 8;
32148 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
32149 if (num_bits_4 == 8) {
32150 t_4 = ((uint16_t)(*scratch));
32151 break;
32152 }
32153 num_bits_4 += 8;
32154 *scratch |= ((uint64_t)(num_bits_4)) << 56;
32155 }
32156 }
32157 v_xlen = t_4;
32158 }
32159 self->private_data.s_transform_io[0].scratch = ((uint32_t)(v_xlen));
32160 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
32161 if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32162 self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32163 iop_a_src = io2_a_src;
32164 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32165 goto suspend;
32166 }
32167 iop_a_src += self->private_data.s_transform_io[0].scratch;
32168 }
32169 if ((v_flags & 8) != 0) {
32170 while (true) {
32171 {
32172 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
32173 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32174 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32175 goto suspend;
32176 }
32177 uint8_t t_5 = *iop_a_src++;
32178 v_c = t_5;
32179 }
32180 if (v_c == 0) {
32181 goto label__0__break;
32182 }
32183 }
32184 label__0__break:;
32185 }
32186 if ((v_flags & 16) != 0) {
32187 while (true) {
32188 {
32189 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
32190 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32191 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32192 goto suspend;
32193 }
32194 uint8_t t_6 = *iop_a_src++;
32195 v_c = t_6;
32196 }
32197 if (v_c == 0) {
32198 goto label__1__break;
32199 }
32200 }
32201 label__1__break:;
32202 }
32203 if ((v_flags & 2) != 0) {
32204 self->private_data.s_transform_io[0].scratch = 2;
32205 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
32206 if (self->private_data.s_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
32207 self->private_data.s_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
32208 iop_a_src = io2_a_src;
32209 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32210 goto suspend;
32211 }
32212 iop_a_src += self->private_data.s_transform_io[0].scratch;
32213 }
32214 if ((v_flags & 224) != 0) {
32215 status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags);
32216 goto exit;
32217 }
32218 while (true) {
32219 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
32220 {
32221 if (a_dst) {
32222 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32223 }
32224 if (a_src) {
32225 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32226 }
32227 wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
32228 v_status = t_7;
32229 if (a_dst) {
32230 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
32231 }
32232 if (a_src) {
32233 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32234 }
32235 }
32236 if ( ! self->private_impl.f_ignore_checksum) {
32237 v_checksum_got = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
32238 v_decoded_length_got += ((uint32_t)((wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))) & 4294967295)));
32239 }
32240 if (wuffs_base__status__is_ok(&v_status)) {
32241 goto label__2__break;
32242 }
32243 status = v_status;
32244 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
32245 }
32246 label__2__break:;
32247 {
32248 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
32249 uint32_t t_8;
32250 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32251 t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32252 iop_a_src += 4;
32253 } else {
32254 self->private_data.s_transform_io[0].scratch = 0;
32255 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
32256 while (true) {
32257 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32258 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32259 goto suspend;
32260 }
32261 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
32262 uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
32263 *scratch <<= 8;
32264 *scratch >>= 8;
32265 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
32266 if (num_bits_8 == 24) {
32267 t_8 = ((uint32_t)(*scratch));
32268 break;
32269 }
32270 num_bits_8 += 8;
32271 *scratch |= ((uint64_t)(num_bits_8)) << 56;
32272 }
32273 }
32274 v_checksum_want = t_8;
32275 }
32276 {
32277 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
32278 uint32_t t_9;
32279 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
32280 t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32281 iop_a_src += 4;
32282 } else {
32283 self->private_data.s_transform_io[0].scratch = 0;
32284 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
32285 while (true) {
32286 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
32287 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32288 goto suspend;
32289 }
32290 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
32291 uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
32292 *scratch <<= 8;
32293 *scratch >>= 8;
32294 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
32295 if (num_bits_9 == 24) {
32296 t_9 = ((uint32_t)(*scratch));
32297 break;
32298 }
32299 num_bits_9 += 8;
32300 *scratch |= ((uint64_t)(num_bits_9)) << 56;
32301 }
32302 }
32303 v_decoded_length_want = t_9;
32304 }
32305 if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_got != v_checksum_want) || (v_decoded_length_got != v_decoded_length_want))) {
32306 status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum);
32307 goto exit;
32308 }
32309
32310 ok:
32311 self->private_impl.p_transform_io[0] = 0;
32312 goto exit;
32313 }
32314
32315 goto suspend;
32316 suspend:
32317 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
32318 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
32319 self->private_data.s_transform_io[0].v_flags = v_flags;
32320 self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
32321 self->private_data.s_transform_io[0].v_decoded_length_got = v_decoded_length_got;
32322 self->private_data.s_transform_io[0].v_checksum_want = v_checksum_want;
32323
32324 goto exit;
32325 exit:
32326 if (a_dst) {
32327 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32328 }
32329 if (a_src) {
32330 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32331 }
32332
32333 if (wuffs_base__status__is_error(&status)) {
32334 self->private_impl.magic = WUFFS_BASE__DISABLED;
32335 }
32336 return status;
32337 }
32338
32339 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
32340
32341 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
32342
32343 // ---------------- Status Codes Implementations
32344
32345 const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code";
32346 const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8";
32347 const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape";
32348 const char wuffs_json__error__bad_input[] = "#json: bad input";
32349 const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string";
32350 const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination";
32351 const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length";
32352 const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth";
32353 const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O";
32354
32355 // ---------------- Private Consts
32356
32357 #define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99
32358
32359 static const uint8_t
32360 WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32361 0, 0, 0, 0, 0, 0, 0, 0,
32362 0, 0, 3, 0, 0, 0, 0, 0,
32363 0, 0, 0, 0, 0, 0, 0, 0,
32364 0, 0, 0, 0, 0, 0, 0, 0,
32365 0, 0, 162, 0, 0, 0, 0, 5,
32366 0, 0, 0, 0, 0, 0, 0, 175,
32367 7, 0, 0, 0, 0, 0, 0, 0,
32368 0, 0, 0, 0, 0, 0, 0, 4,
32369 0, 0, 0, 0, 0, 0, 0, 0,
32370 0, 0, 0, 0, 0, 0, 0, 0,
32371 0, 0, 0, 0, 0, 0, 0, 0,
32372 0, 0, 0, 0, 220, 0, 0, 0,
32373 0, 1, 136, 0, 0, 2, 140, 0,
32374 0, 0, 0, 0, 0, 0, 138, 0,
32375 0, 0, 141, 0, 137, 0, 6, 0,
32376 0, 0, 0, 0, 0, 0, 0, 0,
32377 0, 0, 0, 0, 0, 0, 0, 0,
32378 0, 0, 0, 0, 0, 0, 0, 0,
32379 0, 0, 0, 0, 0, 0, 0, 0,
32380 0, 0, 0, 0, 0, 0, 0, 0,
32381 0, 0, 0, 0, 0, 0, 0, 0,
32382 0, 0, 0, 0, 0, 0, 0, 0,
32383 0, 0, 0, 0, 0, 0, 0, 0,
32384 0, 0, 0, 0, 0, 0, 0, 0,
32385 0, 0, 0, 0, 0, 0, 0, 0,
32386 0, 0, 0, 0, 0, 0, 0, 0,
32387 0, 0, 0, 0, 0, 0, 0, 0,
32388 0, 0, 0, 0, 0, 0, 0, 0,
32389 0, 0, 0, 0, 0, 0, 0, 0,
32390 0, 0, 0, 0, 0, 0, 0, 0,
32391 0, 0, 0, 0, 0, 0, 0, 0,
32392 0, 0, 0, 0, 0, 0, 0, 0,
32393 };
32394
32395 static const uint8_t
32396 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
32397 0, 1, 3, 4, 5, 6, 7, 10,
32398 };
32399
32400 static const uint8_t
32401 WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
32402 0, 7, 27, 10, 63, 39, 11, 0,
32403 };
32404
32405 static const uint8_t
32406 WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32407 128, 129, 130, 131, 132, 133, 134, 135,
32408 136, 137, 138, 139, 140, 141, 142, 143,
32409 144, 145, 146, 147, 148, 149, 150, 151,
32410 152, 153, 154, 155, 156, 157, 158, 159,
32411 0, 0, 1, 0, 0, 0, 0, 0,
32412 0, 0, 0, 0, 0, 0, 0, 0,
32413 0, 0, 0, 0, 0, 0, 0, 0,
32414 0, 0, 0, 0, 0, 0, 0, 0,
32415 0, 0, 0, 0, 0, 0, 0, 0,
32416 0, 0, 0, 0, 0, 0, 0, 0,
32417 0, 0, 0, 0, 0, 0, 0, 0,
32418 0, 0, 0, 0, 2, 0, 0, 0,
32419 0, 0, 0, 0, 0, 0, 0, 0,
32420 0, 0, 0, 0, 0, 0, 0, 0,
32421 0, 0, 0, 0, 0, 0, 0, 0,
32422 0, 0, 0, 0, 0, 0, 0, 0,
32423 16, 16, 16, 16, 16, 16, 16, 16,
32424 16, 16, 16, 16, 16, 16, 16, 16,
32425 16, 16, 16, 16, 16, 16, 16, 16,
32426 16, 16, 16, 16, 16, 16, 16, 16,
32427 16, 16, 16, 16, 16, 16, 16, 16,
32428 16, 16, 16, 16, 16, 16, 16, 16,
32429 16, 16, 16, 16, 16, 16, 16, 16,
32430 16, 16, 16, 16, 16, 16, 16, 16,
32431 32, 32, 3, 3, 3, 3, 3, 3,
32432 3, 3, 3, 3, 3, 3, 3, 3,
32433 3, 3, 3, 3, 3, 3, 3, 3,
32434 3, 3, 3, 3, 3, 3, 3, 3,
32435 4, 4, 4, 4, 4, 4, 4, 4,
32436 4, 4, 4, 4, 4, 4, 4, 4,
32437 5, 5, 5, 5, 5, 32, 32, 32,
32438 32, 32, 32, 32, 32, 32, 32, 32,
32439 };
32440
32441 #define WUFFS_JSON__CLASS_WHITESPACE 0
32442
32443 #define WUFFS_JSON__CLASS_STRING 1
32444
32445 #define WUFFS_JSON__CLASS_COMMA 2
32446
32447 #define WUFFS_JSON__CLASS_COLON 3
32448
32449 #define WUFFS_JSON__CLASS_NUMBER 4
32450
32451 #define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5
32452
32453 #define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6
32454
32455 #define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7
32456
32457 #define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8
32458
32459 #define WUFFS_JSON__CLASS_FALSE 9
32460
32461 #define WUFFS_JSON__CLASS_TRUE 10
32462
32463 #define WUFFS_JSON__CLASS_NULL_NAN_INF 11
32464
32465 #define WUFFS_JSON__CLASS_COMMENT 12
32466
32467 #define WUFFS_JSON__EXPECT_VALUE 7858
32468
32469 #define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856
32470
32471 #define WUFFS_JSON__EXPECT_STRING 4098
32472
32473 #define WUFFS_JSON__EXPECT_COMMA 4100
32474
32475 #define WUFFS_JSON__EXPECT_COLON 4104
32476
32477 #define WUFFS_JSON__EXPECT_NUMBER 4112
32478
32479 #define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160
32480
32481 #define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352
32482
32483 static const uint8_t
32484 WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32485 15, 15, 15, 15, 15, 15, 15, 15,
32486 15, 0, 0, 15, 15, 0, 15, 15,
32487 15, 15, 15, 15, 15, 15, 15, 15,
32488 15, 15, 15, 15, 15, 15, 15, 15,
32489 0, 15, 1, 15, 15, 15, 15, 15,
32490 15, 15, 15, 11, 2, 4, 15, 12,
32491 4, 4, 4, 4, 4, 4, 4, 4,
32492 4, 4, 3, 15, 15, 15, 15, 15,
32493 15, 15, 15, 15, 15, 15, 15, 15,
32494 15, 11, 15, 15, 15, 15, 11, 15,
32495 15, 15, 15, 15, 15, 15, 15, 15,
32496 15, 15, 15, 7, 15, 8, 15, 15,
32497 15, 15, 15, 15, 15, 15, 9, 15,
32498 15, 11, 15, 15, 15, 15, 11, 15,
32499 15, 15, 15, 15, 10, 15, 15, 15,
32500 15, 15, 15, 5, 15, 6, 15, 15,
32501 15, 15, 15, 15, 15, 15, 15, 15,
32502 15, 15, 15, 15, 15, 15, 15, 15,
32503 15, 15, 15, 15, 15, 15, 15, 15,
32504 15, 15, 15, 15, 15, 15, 15, 15,
32505 15, 15, 15, 15, 15, 15, 15, 15,
32506 15, 15, 15, 15, 15, 15, 15, 15,
32507 15, 15, 15, 15, 15, 15, 15, 15,
32508 15, 15, 15, 15, 15, 15, 15, 15,
32509 15, 15, 15, 15, 15, 15, 15, 15,
32510 15, 15, 15, 15, 15, 15, 15, 15,
32511 15, 15, 15, 15, 15, 15, 15, 15,
32512 15, 15, 15, 15, 15, 15, 15, 15,
32513 15, 15, 15, 15, 15, 15, 15, 15,
32514 15, 15, 15, 15, 15, 15, 15, 15,
32515 15, 15, 15, 15, 15, 15, 15, 15,
32516 15, 15, 15, 15, 15, 15, 15, 15,
32517 };
32518
32519 static const uint8_t
32520 WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32521 0, 0, 0, 0, 0, 0, 0, 0,
32522 0, 0, 0, 0, 0, 0, 0, 0,
32523 0, 0, 0, 0, 0, 0, 0, 0,
32524 0, 0, 0, 0, 0, 0, 0, 0,
32525 0, 0, 0, 0, 0, 0, 0, 0,
32526 0, 0, 0, 0, 0, 0, 0, 0,
32527 128, 129, 130, 131, 132, 133, 134, 135,
32528 136, 137, 0, 0, 0, 0, 0, 0,
32529 0, 0, 0, 0, 0, 0, 0, 0,
32530 0, 0, 0, 0, 0, 0, 0, 0,
32531 0, 0, 0, 0, 0, 0, 0, 0,
32532 0, 0, 0, 0, 0, 0, 0, 0,
32533 0, 0, 0, 0, 0, 0, 0, 0,
32534 0, 0, 0, 0, 0, 0, 0, 0,
32535 0, 0, 0, 0, 0, 0, 0, 0,
32536 0, 0, 0, 0, 0, 0, 0, 0,
32537 0, 0, 0, 0, 0, 0, 0, 0,
32538 0, 0, 0, 0, 0, 0, 0, 0,
32539 0, 0, 0, 0, 0, 0, 0, 0,
32540 0, 0, 0, 0, 0, 0, 0, 0,
32541 0, 0, 0, 0, 0, 0, 0, 0,
32542 0, 0, 0, 0, 0, 0, 0, 0,
32543 0, 0, 0, 0, 0, 0, 0, 0,
32544 0, 0, 0, 0, 0, 0, 0, 0,
32545 0, 0, 0, 0, 0, 0, 0, 0,
32546 0, 0, 0, 0, 0, 0, 0, 0,
32547 0, 0, 0, 0, 0, 0, 0, 0,
32548 0, 0, 0, 0, 0, 0, 0, 0,
32549 0, 0, 0, 0, 0, 0, 0, 0,
32550 0, 0, 0, 0, 0, 0, 0, 0,
32551 0, 0, 0, 0, 0, 0, 0, 0,
32552 0, 0, 0, 0, 0, 0, 0, 0,
32553 };
32554
32555 static const uint8_t
32556 WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
32557 0, 0, 0, 0, 0, 0, 0, 0,
32558 0, 0, 0, 0, 0, 0, 0, 0,
32559 0, 0, 0, 0, 0, 0, 0, 0,
32560 0, 0, 0, 0, 0, 0, 0, 0,
32561 0, 0, 0, 0, 0, 0, 0, 0,
32562 0, 0, 0, 0, 0, 0, 0, 0,
32563 128, 129, 130, 131, 132, 133, 134, 135,
32564 136, 137, 0, 0, 0, 0, 0, 0,
32565 0, 138, 139, 140, 141, 142, 143, 0,
32566 0, 0, 0, 0, 0, 0, 0, 0,
32567 0, 0, 0, 0, 0, 0, 0, 0,
32568 0, 0, 0, 0, 0, 0, 0, 0,
32569 0, 138, 139, 140, 141, 142, 143, 0,
32570 0, 0, 0, 0, 0, 0, 0, 0,
32571 0, 0, 0, 0, 0, 0, 0, 0,
32572 0, 0, 0, 0, 0, 0, 0, 0,
32573 0, 0, 0, 0, 0, 0, 0, 0,
32574 0, 0, 0, 0, 0, 0, 0, 0,
32575 0, 0, 0, 0, 0, 0, 0, 0,
32576 0, 0, 0, 0, 0, 0, 0, 0,
32577 0, 0, 0, 0, 0, 0, 0, 0,
32578 0, 0, 0, 0, 0, 0, 0, 0,
32579 0, 0, 0, 0, 0, 0, 0, 0,
32580 0, 0, 0, 0, 0, 0, 0, 0,
32581 0, 0, 0, 0, 0, 0, 0, 0,
32582 0, 0, 0, 0, 0, 0, 0, 0,
32583 0, 0, 0, 0, 0, 0, 0, 0,
32584 0, 0, 0, 0, 0, 0, 0, 0,
32585 0, 0, 0, 0, 0, 0, 0, 0,
32586 0, 0, 0, 0, 0, 0, 0, 0,
32587 0, 0, 0, 0, 0, 0, 0, 0,
32588 0, 0, 0, 0, 0, 0, 0, 0,
32589 };
32590
32591 #define WUFFS_JSON__QUIRKS_BASE 1225364480
32592
32593 #define WUFFS_JSON__QUIRKS_COUNT 21
32594
32595 // ---------------- Private Initializer Prototypes
32596
32597 // ---------------- Private Function Prototypes
32598
32599 static uint32_t
32600 wuffs_json__decoder__decode_number(
32601 wuffs_json__decoder* self,
32602 wuffs_base__io_buffer* a_src);
32603
32604 static uint32_t
32605 wuffs_json__decoder__decode_digits(
32606 wuffs_json__decoder* self,
32607 wuffs_base__io_buffer* a_src,
32608 uint32_t a_n);
32609
32610 static wuffs_base__status
32611 wuffs_json__decoder__decode_leading(
32612 wuffs_json__decoder* self,
32613 wuffs_base__token_buffer* a_dst,
32614 wuffs_base__io_buffer* a_src);
32615
32616 static wuffs_base__status
32617 wuffs_json__decoder__decode_comment(
32618 wuffs_json__decoder* self,
32619 wuffs_base__token_buffer* a_dst,
32620 wuffs_base__io_buffer* a_src);
32621
32622 static wuffs_base__status
32623 wuffs_json__decoder__decode_inf_nan(
32624 wuffs_json__decoder* self,
32625 wuffs_base__token_buffer* a_dst,
32626 wuffs_base__io_buffer* a_src);
32627
32628 static wuffs_base__status
32629 wuffs_json__decoder__decode_trailer(
32630 wuffs_json__decoder* self,
32631 wuffs_base__token_buffer* a_dst,
32632 wuffs_base__io_buffer* a_src);
32633
32634 // ---------------- VTables
32635
32636 const wuffs_base__token_decoder__func_ptrs
32637 wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
32638 (wuffs_base__status(*)(void*,
32639 wuffs_base__token_buffer*,
32640 wuffs_base__io_buffer*,
32641 wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens),
32642 (wuffs_base__empty_struct(*)(void*,
32643 uint32_t,
32644 bool))(&wuffs_json__decoder__set_quirk_enabled),
32645 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len),
32646 };
32647
32648 // ---------------- Initializer Implementations
32649
32650 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_json__decoder__initialize(wuffs_json__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)32651 wuffs_json__decoder__initialize(
32652 wuffs_json__decoder* self,
32653 size_t sizeof_star_self,
32654 uint64_t wuffs_version,
32655 uint32_t options){
32656 if (!self) {
32657 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32658 }
32659 if (sizeof(*self) != sizeof_star_self) {
32660 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
32661 }
32662 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
32663 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
32664 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
32665 }
32666
32667 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
32668 // The whole point of this if-check is to detect an uninitialized *self.
32669 // We disable the warning on GCC. Clang-5.0 does not have this warning.
32670 #if !defined(__clang__) && defined(__GNUC__)
32671 #pragma GCC diagnostic push
32672 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
32673 #endif
32674 if (self->private_impl.magic != 0) {
32675 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
32676 }
32677 #if !defined(__clang__) && defined(__GNUC__)
32678 #pragma GCC diagnostic pop
32679 #endif
32680 } else {
32681 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
32682 memset(self, 0, sizeof(*self));
32683 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
32684 } else {
32685 memset(&(self->private_impl), 0, sizeof(self->private_impl));
32686 }
32687 }
32688
32689 self->private_impl.magic = WUFFS_BASE__MAGIC;
32690 self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
32691 wuffs_base__token_decoder__vtable_name;
32692 self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
32693 (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
32694 return wuffs_base__make_status(NULL);
32695 }
32696
32697 wuffs_json__decoder*
wuffs_json__decoder__alloc()32698 wuffs_json__decoder__alloc() {
32699 wuffs_json__decoder* x =
32700 (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
32701 if (!x) {
32702 return NULL;
32703 }
32704 if (wuffs_json__decoder__initialize(
32705 x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
32706 free(x);
32707 return NULL;
32708 }
32709 return x;
32710 }
32711
32712 size_t
sizeof__wuffs_json__decoder()32713 sizeof__wuffs_json__decoder() {
32714 return sizeof(wuffs_json__decoder);
32715 }
32716
32717 // ---------------- Function Implementations
32718
32719 // -------- func json.decoder.set_quirk_enabled
32720
32721 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_json__decoder__set_quirk_enabled(wuffs_json__decoder * self,uint32_t a_quirk,bool a_enabled)32722 wuffs_json__decoder__set_quirk_enabled(
32723 wuffs_json__decoder* self,
32724 uint32_t a_quirk,
32725 bool a_enabled) {
32726 if (!self) {
32727 return wuffs_base__make_empty_struct();
32728 }
32729 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32730 return wuffs_base__make_empty_struct();
32731 }
32732
32733 if (a_quirk >= 1225364480) {
32734 a_quirk -= 1225364480;
32735 if (a_quirk < 21) {
32736 self->private_impl.f_quirks[a_quirk] = a_enabled;
32737 }
32738 }
32739 return wuffs_base__make_empty_struct();
32740 }
32741
32742 // -------- func json.decoder.workbuf_len
32743
32744 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_json__decoder__workbuf_len(const wuffs_json__decoder * self)32745 wuffs_json__decoder__workbuf_len(
32746 const wuffs_json__decoder* self) {
32747 if (!self) {
32748 return wuffs_base__utility__empty_range_ii_u64();
32749 }
32750 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
32751 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
32752 return wuffs_base__utility__empty_range_ii_u64();
32753 }
32754
32755 return wuffs_base__utility__empty_range_ii_u64();
32756 }
32757
32758 // -------- func json.decoder.decode_tokens
32759
32760 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_json__decoder__decode_tokens(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)32761 wuffs_json__decoder__decode_tokens(
32762 wuffs_json__decoder* self,
32763 wuffs_base__token_buffer* a_dst,
32764 wuffs_base__io_buffer* a_src,
32765 wuffs_base__slice_u8 a_workbuf) {
32766 if (!self) {
32767 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
32768 }
32769 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
32770 return wuffs_base__make_status(
32771 (self->private_impl.magic == WUFFS_BASE__DISABLED)
32772 ? wuffs_base__error__disabled_by_previous_error
32773 : wuffs_base__error__initialize_not_called);
32774 }
32775 if (!a_dst || !a_src) {
32776 self->private_impl.magic = WUFFS_BASE__DISABLED;
32777 return wuffs_base__make_status(wuffs_base__error__bad_argument);
32778 }
32779 if ((self->private_impl.active_coroutine != 0) &&
32780 (self->private_impl.active_coroutine != 1)) {
32781 self->private_impl.magic = WUFFS_BASE__DISABLED;
32782 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
32783 }
32784 self->private_impl.active_coroutine = 0;
32785 wuffs_base__status status = wuffs_base__make_status(NULL);
32786
32787 uint32_t v_vminor = 0;
32788 uint32_t v_number_length = 0;
32789 uint32_t v_number_status = 0;
32790 uint32_t v_string_length = 0;
32791 uint32_t v_whitespace_length = 0;
32792 uint32_t v_depth = 0;
32793 uint32_t v_stack_byte = 0;
32794 uint32_t v_stack_bit = 0;
32795 uint32_t v_match = 0;
32796 uint32_t v_c4 = 0;
32797 uint8_t v_c = 0;
32798 uint8_t v_backslash = 0;
32799 uint8_t v_char = 0;
32800 uint8_t v_class = 0;
32801 uint32_t v_multi_byte_utf8 = 0;
32802 uint8_t v_backslash_x_ok = 0;
32803 uint8_t v_backslash_x_value = 0;
32804 uint32_t v_backslash_x_string = 0;
32805 uint8_t v_uni4_ok = 0;
32806 uint64_t v_uni4_string = 0;
32807 uint32_t v_uni4_value = 0;
32808 uint32_t v_uni4_high_surrogate = 0;
32809 uint8_t v_uni8_ok = 0;
32810 uint64_t v_uni8_string = 0;
32811 uint32_t v_uni8_value = 0;
32812 uint32_t v_expect = 0;
32813 uint32_t v_expect_after_value = 0;
32814
32815 wuffs_base__token* iop_a_dst = NULL;
32816 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32817 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32818 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32819 if (a_dst) {
32820 io0_a_dst = a_dst->data.ptr;
32821 io1_a_dst = io0_a_dst + a_dst->meta.wi;
32822 iop_a_dst = io1_a_dst;
32823 io2_a_dst = io0_a_dst + a_dst->data.len;
32824 if (a_dst->meta.closed) {
32825 io2_a_dst = iop_a_dst;
32826 }
32827 }
32828 const uint8_t* iop_a_src = NULL;
32829 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32830 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32831 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
32832 if (a_src) {
32833 io0_a_src = a_src->data.ptr;
32834 io1_a_src = io0_a_src + a_src->meta.ri;
32835 iop_a_src = io1_a_src;
32836 io2_a_src = io0_a_src + a_src->meta.wi;
32837 }
32838
32839 uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
32840 if (coro_susp_point) {
32841 v_depth = self->private_data.s_decode_tokens[0].v_depth;
32842 v_expect = self->private_data.s_decode_tokens[0].v_expect;
32843 v_expect_after_value = self->private_data.s_decode_tokens[0].v_expect_after_value;
32844 }
32845 switch (coro_susp_point) {
32846 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
32847
32848 if (self->private_impl.f_end_of_data) {
32849 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
32850 goto ok;
32851 }
32852 if (self->private_impl.f_quirks[18]) {
32853 if (self->private_impl.f_quirks[11] || self->private_impl.f_quirks[12] || self->private_impl.f_quirks[17]) {
32854 status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination);
32855 goto exit;
32856 }
32857 }
32858 if (self->private_impl.f_quirks[15] || self->private_impl.f_quirks[16]) {
32859 if (a_dst) {
32860 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
32861 }
32862 if (a_src) {
32863 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
32864 }
32865 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
32866 status = wuffs_json__decoder__decode_leading(self, a_dst, a_src);
32867 if (a_dst) {
32868 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
32869 }
32870 if (a_src) {
32871 iop_a_src = a_src->data.ptr + a_src->meta.ri;
32872 }
32873 if (status.repr) {
32874 goto suspend;
32875 }
32876 }
32877 v_expect = 7858;
32878 label__outer__continue:;
32879 while (true) {
32880 while (true) {
32881 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32882 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32883 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
32884 goto label__outer__continue;
32885 }
32886 v_whitespace_length = 0;
32887 v_c = 0;
32888 v_class = 0;
32889 while (true) {
32890 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
32891 if (v_whitespace_length > 0) {
32892 *iop_a_dst++ = wuffs_base__make_token(
32893 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32894 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32895 v_whitespace_length = 0;
32896 }
32897 if (a_src && a_src->meta.closed) {
32898 status = wuffs_base__make_status(wuffs_json__error__bad_input);
32899 goto exit;
32900 }
32901 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32902 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
32903 v_whitespace_length = 0;
32904 goto label__outer__continue;
32905 }
32906 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
32907 v_class = WUFFS_JSON__LUT_CLASSES[v_c];
32908 if (v_class != 0) {
32909 goto label__ws__break;
32910 }
32911 iop_a_src += 1;
32912 if (v_whitespace_length >= 65534) {
32913 *iop_a_dst++ = wuffs_base__make_token(
32914 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32915 (((uint64_t)(65535)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32916 v_whitespace_length = 0;
32917 goto label__outer__continue;
32918 }
32919 v_whitespace_length += 1;
32920 }
32921 label__ws__break:;
32922 if (v_whitespace_length > 0) {
32923 *iop_a_dst++ = wuffs_base__make_token(
32924 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32925 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32926 v_whitespace_length = 0;
32927 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32928 goto label__outer__continue;
32929 }
32930 }
32931 if (0 == (v_expect & (((uint32_t)(1)) << v_class))) {
32932 status = wuffs_base__make_status(wuffs_json__error__bad_input);
32933 goto exit;
32934 }
32935 if (v_class == 1) {
32936 *iop_a_dst++ = wuffs_base__make_token(
32937 (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32938 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32939 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32940 iop_a_src += 1;
32941 label__string_loop_outer__continue:;
32942 while (true) {
32943 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
32944 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
32945 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
32946 goto label__string_loop_outer__continue;
32947 }
32948 v_string_length = 0;
32949 label__string_loop_inner__continue:;
32950 while (true) {
32951 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
32952 if (v_string_length > 0) {
32953 *iop_a_dst++ = wuffs_base__make_token(
32954 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32955 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32956 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32957 v_string_length = 0;
32958 }
32959 if (a_src && a_src->meta.closed) {
32960 status = wuffs_base__make_status(wuffs_json__error__bad_input);
32961 goto exit;
32962 }
32963 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
32964 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
32965 v_string_length = 0;
32966 goto label__string_loop_outer__continue;
32967 }
32968 while (((uint64_t)(io2_a_src - iop_a_src)) > 4) {
32969 v_c4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
32970 if (0 != (WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 0))] |
32971 WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 8))] |
32972 WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 16))] |
32973 WUFFS_JSON__LUT_CHARS[(255 & (v_c4 >> 24))])) {
32974 goto label__0__break;
32975 }
32976 iop_a_src += 4;
32977 if (v_string_length > 65527) {
32978 *iop_a_dst++ = wuffs_base__make_token(
32979 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32980 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32981 (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32982 v_string_length = 0;
32983 goto label__string_loop_outer__continue;
32984 }
32985 v_string_length += 4;
32986 }
32987 label__0__break:;
32988 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
32989 v_char = WUFFS_JSON__LUT_CHARS[v_c];
32990 if (v_char == 0) {
32991 iop_a_src += 1;
32992 if (v_string_length >= 65531) {
32993 *iop_a_dst++ = wuffs_base__make_token(
32994 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
32995 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
32996 (((uint64_t)(65532)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
32997 v_string_length = 0;
32998 goto label__string_loop_outer__continue;
32999 }
33000 v_string_length += 1;
33001 goto label__string_loop_inner__continue;
33002 } else if (v_char == 1) {
33003 if (v_string_length != 0) {
33004 *iop_a_dst++ = wuffs_base__make_token(
33005 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33006 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33007 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33008 v_string_length = 0;
33009 }
33010 goto label__string_loop_outer__break;
33011 } else if (v_char == 2) {
33012 if (v_string_length > 0) {
33013 *iop_a_dst++ = wuffs_base__make_token(
33014 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33015 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33016 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33017 v_string_length = 0;
33018 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33019 goto label__string_loop_outer__continue;
33020 }
33021 }
33022 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
33023 if (a_src && a_src->meta.closed) {
33024 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33025 goto exit;
33026 }
33027 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33028 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
33029 v_string_length = 0;
33030 v_char = 0;
33031 goto label__string_loop_outer__continue;
33032 }
33033 v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8)));
33034 v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c];
33035 if ((v_backslash & 128) != 0) {
33036 iop_a_src += 2;
33037 *iop_a_dst++ = wuffs_base__make_token(
33038 (((uint64_t)((6291456 | ((uint32_t)((v_backslash & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33039 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33040 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33041 goto label__string_loop_outer__continue;
33042 } else if (v_backslash != 0) {
33043 if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(v_backslash & 7)]]) {
33044 iop_a_src += 2;
33045 *iop_a_dst++ = wuffs_base__make_token(
33046 (((uint64_t)((6291456 | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(v_backslash & 7)]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33047 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33048 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33049 goto label__string_loop_outer__continue;
33050 }
33051 } else if (v_c == 117) {
33052 if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
33053 if (a_src && a_src->meta.closed) {
33054 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33055 goto exit;
33056 }
33057 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33058 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
33059 v_string_length = 0;
33060 v_char = 0;
33061 goto label__string_loop_outer__continue;
33062 }
33063 v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16);
33064 v_uni4_value = 0;
33065 v_uni4_ok = 128;
33066 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
33067 v_uni4_ok &= v_c;
33068 v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
33069 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
33070 v_uni4_ok &= v_c;
33071 v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
33072 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
33073 v_uni4_ok &= v_c;
33074 v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
33075 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
33076 v_uni4_ok &= v_c;
33077 v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
33078 if (v_uni4_ok == 0) {
33079 } else if ((v_uni4_value < 55296) || (57343 < v_uni4_value)) {
33080 iop_a_src += 6;
33081 *iop_a_dst++ = wuffs_base__make_token(
33082 (((uint64_t)((6291456 | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33083 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33084 (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33085 goto label__string_loop_outer__continue;
33086 } else if (v_uni4_value >= 56320) {
33087 } else {
33088 if (((uint64_t)(io2_a_src - iop_a_src)) < 12) {
33089 if (a_src && a_src->meta.closed) {
33090 if (self->private_impl.f_quirks[20]) {
33091 iop_a_src += 6;
33092 *iop_a_dst++ = wuffs_base__make_token(
33093 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33094 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33095 (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33096 goto label__string_loop_outer__continue;
33097 }
33098 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33099 goto exit;
33100 }
33101 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33102 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
33103 v_string_length = 0;
33104 v_uni4_value = 0;
33105 v_char = 0;
33106 goto label__string_loop_outer__continue;
33107 }
33108 v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4) >> 16);
33109 if (((255 & (v_uni4_string >> 0)) != 92) || ((255 & (v_uni4_string >> 8)) != 117)) {
33110 v_uni4_high_surrogate = 0;
33111 v_uni4_value = 0;
33112 v_uni4_ok = 0;
33113 } else {
33114 v_uni4_high_surrogate = (65536 + ((v_uni4_value - 55296) << 10));
33115 v_uni4_value = 0;
33116 v_uni4_ok = 128;
33117 v_uni4_string >>= 16;
33118 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 0))];
33119 v_uni4_ok &= v_c;
33120 v_uni4_value |= (((uint32_t)((v_c & 15))) << 12);
33121 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 8))];
33122 v_uni4_ok &= v_c;
33123 v_uni4_value |= (((uint32_t)((v_c & 15))) << 8);
33124 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 16))];
33125 v_uni4_ok &= v_c;
33126 v_uni4_value |= (((uint32_t)((v_c & 15))) << 4);
33127 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni4_string >> 24))];
33128 v_uni4_ok &= v_c;
33129 v_uni4_value |= (((uint32_t)((v_c & 15))) << 0);
33130 }
33131 if ((v_uni4_ok != 0) && (56320 <= v_uni4_value) && (v_uni4_value <= 57343)) {
33132 v_uni4_value -= 56320;
33133 iop_a_src += 12;
33134 *iop_a_dst++ = wuffs_base__make_token(
33135 (((uint64_t)((6291456 | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33136 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33137 (((uint64_t)(12)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33138 goto label__string_loop_outer__continue;
33139 }
33140 }
33141 if (self->private_impl.f_quirks[20]) {
33142 if (((uint64_t)(io2_a_src - iop_a_src)) < 6) {
33143 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33144 goto exit;
33145 }
33146 iop_a_src += 6;
33147 *iop_a_dst++ = wuffs_base__make_token(
33148 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33149 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33150 (((uint64_t)(6)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33151 goto label__string_loop_outer__continue;
33152 }
33153 } else if ((v_c == 85) && self->private_impl.f_quirks[2]) {
33154 if (((uint64_t)(io2_a_src - iop_a_src)) < 10) {
33155 if (a_src && a_src->meta.closed) {
33156 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33157 goto exit;
33158 }
33159 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33160 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
33161 v_string_length = 0;
33162 v_char = 0;
33163 goto label__string_loop_outer__continue;
33164 }
33165 v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2);
33166 v_uni8_value = 0;
33167 v_uni8_ok = 128;
33168 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 0))];
33169 v_uni8_ok &= v_c;
33170 v_uni8_value |= (((uint32_t)((v_c & 15))) << 28);
33171 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 8))];
33172 v_uni8_ok &= v_c;
33173 v_uni8_value |= (((uint32_t)((v_c & 15))) << 24);
33174 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 16))];
33175 v_uni8_ok &= v_c;
33176 v_uni8_value |= (((uint32_t)((v_c & 15))) << 20);
33177 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 24))];
33178 v_uni8_ok &= v_c;
33179 v_uni8_value |= (((uint32_t)((v_c & 15))) << 16);
33180 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 32))];
33181 v_uni8_ok &= v_c;
33182 v_uni8_value |= (((uint32_t)((v_c & 15))) << 12);
33183 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 40))];
33184 v_uni8_ok &= v_c;
33185 v_uni8_value |= (((uint32_t)((v_c & 15))) << 8);
33186 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 48))];
33187 v_uni8_ok &= v_c;
33188 v_uni8_value |= (((uint32_t)((v_c & 15))) << 4);
33189 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_uni8_string >> 56))];
33190 v_uni8_ok &= v_c;
33191 v_uni8_value |= (((uint32_t)((v_c & 15))) << 0);
33192 if (v_uni8_ok == 0) {
33193 } else if ((v_uni8_value < 55296) || ((57343 < v_uni8_value) && (v_uni8_value <= 1114111))) {
33194 iop_a_src += 10;
33195 *iop_a_dst++ = wuffs_base__make_token(
33196 (((uint64_t)((6291456 | (v_uni8_value & 2097151)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33197 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33198 (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33199 goto label__string_loop_outer__continue;
33200 } else if (self->private_impl.f_quirks[20]) {
33201 iop_a_src += 10;
33202 *iop_a_dst++ = wuffs_base__make_token(
33203 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33204 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33205 (((uint64_t)(10)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33206 goto label__string_loop_outer__continue;
33207 }
33208 } else if ((v_c == 120) && self->private_impl.f_quirks[9]) {
33209 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33210 if (a_src && a_src->meta.closed) {
33211 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33212 goto exit;
33213 }
33214 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33215 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
33216 v_string_length = 0;
33217 v_char = 0;
33218 goto label__string_loop_outer__continue;
33219 }
33220 v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
33221 v_backslash_x_ok = 128;
33222 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 16))];
33223 v_backslash_x_ok &= v_c;
33224 v_backslash_x_value = ((uint8_t)(((v_c & 15) << 4)));
33225 v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255 & (v_backslash_x_string >> 24))];
33226 v_backslash_x_ok &= v_c;
33227 v_backslash_x_value = ((uint8_t)((v_backslash_x_value | (v_c & 15))));
33228 if ((v_backslash_x_ok == 0) || ((v_backslash_x_string & 65535) != 30812)) {
33229 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33230 goto exit;
33231 }
33232 iop_a_src += 4;
33233 *iop_a_dst++ = wuffs_base__make_token(
33234 (((uint64_t)((6291456 | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33235 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33236 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33237 goto label__string_loop_outer__continue;
33238 }
33239 status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
33240 goto exit;
33241 } else if (v_char == 3) {
33242 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
33243 if (v_string_length > 0) {
33244 *iop_a_dst++ = wuffs_base__make_token(
33245 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33246 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33247 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33248 v_string_length = 0;
33249 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33250 goto label__string_loop_outer__continue;
33251 }
33252 }
33253 if (a_src && a_src->meta.closed) {
33254 if (self->private_impl.f_quirks[20]) {
33255 *iop_a_dst++ = wuffs_base__make_token(
33256 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33257 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33258 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33259 iop_a_src += 1;
33260 goto label__string_loop_outer__continue;
33261 }
33262 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33263 goto exit;
33264 }
33265 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33266 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
33267 v_string_length = 0;
33268 v_char = 0;
33269 goto label__string_loop_outer__continue;
33270 }
33271 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
33272 if ((v_multi_byte_utf8 & 49152) == 32768) {
33273 v_multi_byte_utf8 = ((1984 & ((uint32_t)(v_multi_byte_utf8 << 6))) | (63 & (v_multi_byte_utf8 >> 8)));
33274 iop_a_src += 2;
33275 if (v_string_length >= 65528) {
33276 *iop_a_dst++ = wuffs_base__make_token(
33277 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33278 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33279 (((uint64_t)((v_string_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33280 v_string_length = 0;
33281 goto label__string_loop_outer__continue;
33282 }
33283 v_string_length += 2;
33284 goto label__string_loop_inner__continue;
33285 }
33286 } else if (v_char == 4) {
33287 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
33288 if (v_string_length > 0) {
33289 *iop_a_dst++ = wuffs_base__make_token(
33290 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33291 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33292 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33293 v_string_length = 0;
33294 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33295 goto label__string_loop_outer__continue;
33296 }
33297 }
33298 if (a_src && a_src->meta.closed) {
33299 if (self->private_impl.f_quirks[20]) {
33300 *iop_a_dst++ = wuffs_base__make_token(
33301 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33302 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33303 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33304 iop_a_src += 1;
33305 goto label__string_loop_outer__continue;
33306 }
33307 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33308 goto exit;
33309 }
33310 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33311 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
33312 v_string_length = 0;
33313 v_char = 0;
33314 goto label__string_loop_outer__continue;
33315 }
33316 v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
33317 if ((v_multi_byte_utf8 & 12632064) == 8421376) {
33318 v_multi_byte_utf8 = ((61440 & ((uint32_t)(v_multi_byte_utf8 << 12))) | (4032 & (v_multi_byte_utf8 >> 2)) | (63 & (v_multi_byte_utf8 >> 16)));
33319 if ((2047 < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296) || (57343 < v_multi_byte_utf8))) {
33320 iop_a_src += 3;
33321 if (v_string_length >= 65528) {
33322 *iop_a_dst++ = wuffs_base__make_token(
33323 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33324 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33325 (((uint64_t)((v_string_length + 3))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33326 v_string_length = 0;
33327 goto label__string_loop_outer__continue;
33328 }
33329 v_string_length += 3;
33330 goto label__string_loop_inner__continue;
33331 }
33332 }
33333 } else if (v_char == 5) {
33334 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33335 if (v_string_length > 0) {
33336 *iop_a_dst++ = wuffs_base__make_token(
33337 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33338 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33339 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33340 v_string_length = 0;
33341 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33342 goto label__string_loop_outer__continue;
33343 }
33344 }
33345 if (a_src && a_src->meta.closed) {
33346 if (self->private_impl.f_quirks[20]) {
33347 *iop_a_dst++ = wuffs_base__make_token(
33348 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33349 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33350 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33351 iop_a_src += 1;
33352 goto label__string_loop_outer__continue;
33353 }
33354 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33355 goto exit;
33356 }
33357 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33358 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13);
33359 v_string_length = 0;
33360 v_char = 0;
33361 goto label__string_loop_outer__continue;
33362 }
33363 v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
33364 if ((v_multi_byte_utf8 & 3233857536) == 2155905024) {
33365 v_multi_byte_utf8 = ((1835008 & ((uint32_t)(v_multi_byte_utf8 << 18))) |
33366 (258048 & ((uint32_t)(v_multi_byte_utf8 << 4))) |
33367 (4032 & (v_multi_byte_utf8 >> 10)) |
33368 (63 & (v_multi_byte_utf8 >> 24)));
33369 if ((65535 < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111)) {
33370 iop_a_src += 4;
33371 if (v_string_length >= 65528) {
33372 *iop_a_dst++ = wuffs_base__make_token(
33373 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33374 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33375 (((uint64_t)((v_string_length + 4))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33376 v_string_length = 0;
33377 goto label__string_loop_outer__continue;
33378 }
33379 v_string_length += 4;
33380 goto label__string_loop_inner__continue;
33381 }
33382 }
33383 }
33384 if (v_string_length > 0) {
33385 *iop_a_dst++ = wuffs_base__make_token(
33386 (((uint64_t)(4194819)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33387 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33388 (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33389 v_string_length = 0;
33390 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33391 goto label__string_loop_outer__continue;
33392 }
33393 }
33394 if ((v_char & 128) != 0) {
33395 if (self->private_impl.f_quirks[0]) {
33396 *iop_a_dst++ = wuffs_base__make_token(
33397 (((uint64_t)((6291456 | ((uint32_t)((v_char & 127)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33398 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33399 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33400 iop_a_src += 1;
33401 goto label__string_loop_outer__continue;
33402 }
33403 if (v_char == 138) {
33404 status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string);
33405 goto exit;
33406 }
33407 status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
33408 goto exit;
33409 }
33410 if (self->private_impl.f_quirks[20]) {
33411 *iop_a_dst++ = wuffs_base__make_token(
33412 (((uint64_t)(6356989)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33413 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
33414 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33415 iop_a_src += 1;
33416 goto label__string_loop_outer__continue;
33417 }
33418 status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
33419 goto exit;
33420 }
33421 }
33422 label__string_loop_outer__break:;
33423 label__1__continue:;
33424 while (true) {
33425 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33426 if (a_src && a_src->meta.closed) {
33427 status = wuffs_base__make_status(wuffs_json__error__bad_input);
33428 goto exit;
33429 }
33430 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33431 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14);
33432 goto label__1__continue;
33433 }
33434 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33435 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33436 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15);
33437 goto label__1__continue;
33438 }
33439 iop_a_src += 1;
33440 *iop_a_dst++ = wuffs_base__make_token(
33441 (((uint64_t)(4194579)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33442 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33443 goto label__1__break;
33444 }
33445 label__1__break:;
33446 if (0 == (v_expect & (((uint32_t)(1)) << 4))) {
33447 v_expect = 4104;
33448 goto label__outer__continue;
33449 }
33450 goto label__goto_parsed_a_leaf_value__break;
33451 } else if (v_class == 2) {
33452 iop_a_src += 1;
33453 *iop_a_dst++ = wuffs_base__make_token(
33454 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33455 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33456 if (0 == (v_expect & (((uint32_t)(1)) << 8))) {
33457 if (self->private_impl.f_quirks[13]) {
33458 v_expect = 4162;
33459 } else {
33460 v_expect = 4098;
33461 }
33462 } else {
33463 if (self->private_impl.f_quirks[13]) {
33464 v_expect = 8114;
33465 } else {
33466 v_expect = 7858;
33467 }
33468 }
33469 goto label__outer__continue;
33470 } else if (v_class == 3) {
33471 iop_a_src += 1;
33472 *iop_a_dst++ = wuffs_base__make_token(
33473 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33474 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33475 v_expect = 7858;
33476 goto label__outer__continue;
33477 } else if (v_class == 4) {
33478 while (true) {
33479 if (a_src) {
33480 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33481 }
33482 v_number_length = wuffs_json__decoder__decode_number(self, a_src);
33483 if (a_src) {
33484 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33485 }
33486 v_number_status = (v_number_length >> 8);
33487 v_vminor = 10486787;
33488 if ((v_number_length & 128) != 0) {
33489 v_vminor = 10486785;
33490 }
33491 v_number_length = (v_number_length & 127);
33492 if (v_number_status == 0) {
33493 *iop_a_dst++ = wuffs_base__make_token(
33494 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33495 (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33496 goto label__2__break;
33497 }
33498 while (v_number_length > 0) {
33499 v_number_length -= 1;
33500 if (iop_a_src > io1_a_src) {
33501 iop_a_src--;
33502 } else {
33503 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33504 goto exit;
33505 }
33506 }
33507 if (v_number_status == 1) {
33508 if (self->private_impl.f_quirks[14]) {
33509 if (a_dst) {
33510 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33511 }
33512 if (a_src) {
33513 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33514 }
33515 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
33516 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
33517 if (a_dst) {
33518 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33519 }
33520 if (a_src) {
33521 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33522 }
33523 if (status.repr) {
33524 goto suspend;
33525 }
33526 goto label__2__break;
33527 }
33528 status = wuffs_base__make_status(wuffs_json__error__bad_input);
33529 goto exit;
33530 } else if (v_number_status == 2) {
33531 status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length);
33532 goto exit;
33533 } else {
33534 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33535 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17);
33536 while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
33537 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
33538 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18);
33539 }
33540 }
33541 }
33542 label__2__break:;
33543 goto label__goto_parsed_a_leaf_value__break;
33544 } else if (v_class == 5) {
33545 v_vminor = 2113553;
33546 if (v_depth == 0) {
33547 } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
33548 v_vminor = 2113601;
33549 } else {
33550 v_vminor = 2113569;
33551 }
33552 if (v_depth >= 1024) {
33553 status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
33554 goto exit;
33555 }
33556 v_stack_byte = (v_depth / 32);
33557 v_stack_bit = (v_depth & 31);
33558 self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1)) << v_stack_bit);
33559 v_depth += 1;
33560 iop_a_src += 1;
33561 *iop_a_dst++ = wuffs_base__make_token(
33562 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33563 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33564 v_expect = 4162;
33565 v_expect_after_value = 4164;
33566 goto label__outer__continue;
33567 } else if (v_class == 6) {
33568 iop_a_src += 1;
33569 if (v_depth <= 1) {
33570 *iop_a_dst++ = wuffs_base__make_token(
33571 (((uint64_t)(2101314)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33572 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33573 goto label__outer__break;
33574 }
33575 v_depth -= 1;
33576 v_stack_byte = ((v_depth - 1) / 32);
33577 v_stack_bit = ((v_depth - 1) & 31);
33578 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
33579 *iop_a_dst++ = wuffs_base__make_token(
33580 (((uint64_t)(2105410)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33581 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33582 v_expect = 4356;
33583 v_expect_after_value = 4356;
33584 } else {
33585 *iop_a_dst++ = wuffs_base__make_token(
33586 (((uint64_t)(2113602)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33587 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33588 v_expect = 4164;
33589 v_expect_after_value = 4164;
33590 }
33591 goto label__outer__continue;
33592 } else if (v_class == 7) {
33593 v_vminor = 2105361;
33594 if (v_depth == 0) {
33595 } else if (0 != (v_expect_after_value & (((uint32_t)(1)) << 6))) {
33596 v_vminor = 2105409;
33597 } else {
33598 v_vminor = 2105377;
33599 }
33600 if (v_depth >= 1024) {
33601 status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
33602 goto exit;
33603 }
33604 v_stack_byte = (v_depth / 32);
33605 v_stack_bit = (v_depth & 31);
33606 self->private_data.f_stack[v_stack_byte] &= (4294967295 ^ (((uint32_t)(1)) << v_stack_bit));
33607 v_depth += 1;
33608 iop_a_src += 1;
33609 *iop_a_dst++ = wuffs_base__make_token(
33610 (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33611 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33612 v_expect = 8114;
33613 v_expect_after_value = 4356;
33614 goto label__outer__continue;
33615 } else if (v_class == 8) {
33616 iop_a_src += 1;
33617 if (v_depth <= 1) {
33618 *iop_a_dst++ = wuffs_base__make_token(
33619 (((uint64_t)(2101282)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33620 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33621 goto label__outer__break;
33622 }
33623 v_depth -= 1;
33624 v_stack_byte = ((v_depth - 1) / 32);
33625 v_stack_bit = ((v_depth - 1) & 31);
33626 if (0 == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1)) << v_stack_bit))) {
33627 *iop_a_dst++ = wuffs_base__make_token(
33628 (((uint64_t)(2105378)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33629 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33630 v_expect = 4356;
33631 v_expect_after_value = 4356;
33632 } else {
33633 *iop_a_dst++ = wuffs_base__make_token(
33634 (((uint64_t)(2113570)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33635 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33636 v_expect = 4164;
33637 v_expect_after_value = 4164;
33638 }
33639 goto label__outer__continue;
33640 } else if (v_class == 9) {
33641 v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,111546413966853);
33642 if (v_match == 0) {
33643 *iop_a_dst++ = wuffs_base__make_token(
33644 (((uint64_t)(8388612)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33645 (((uint64_t)(5)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33646 if (((uint64_t)(io2_a_src - iop_a_src)) < 5) {
33647 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33648 goto exit;
33649 }
33650 iop_a_src += 5;
33651 goto label__goto_parsed_a_leaf_value__break;
33652 } else if (v_match == 1) {
33653 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33654 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19);
33655 goto label__outer__continue;
33656 }
33657 } else if (v_class == 10) {
33658 v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,435762131972);
33659 if (v_match == 0) {
33660 *iop_a_dst++ = wuffs_base__make_token(
33661 (((uint64_t)(8388616)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33662 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33663 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33664 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33665 goto exit;
33666 }
33667 iop_a_src += 4;
33668 goto label__goto_parsed_a_leaf_value__break;
33669 } else if (v_match == 1) {
33670 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33671 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20);
33672 goto label__outer__continue;
33673 }
33674 } else if (v_class == 11) {
33675 v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src,465676103172);
33676 if (v_match == 0) {
33677 *iop_a_dst++ = wuffs_base__make_token(
33678 (((uint64_t)(8388610)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
33679 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
33680 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
33681 status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
33682 goto exit;
33683 }
33684 iop_a_src += 4;
33685 goto label__goto_parsed_a_leaf_value__break;
33686 } else if (v_match == 1) {
33687 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
33688 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
33689 goto label__outer__continue;
33690 }
33691 if (self->private_impl.f_quirks[14]) {
33692 if (a_dst) {
33693 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33694 }
33695 if (a_src) {
33696 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33697 }
33698 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
33699 status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
33700 if (a_dst) {
33701 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33702 }
33703 if (a_src) {
33704 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33705 }
33706 if (status.repr) {
33707 goto suspend;
33708 }
33709 goto label__goto_parsed_a_leaf_value__break;
33710 }
33711 } else if (v_class == 12) {
33712 if (self->private_impl.f_quirks[11] || self->private_impl.f_quirks[12]) {
33713 if (a_dst) {
33714 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33715 }
33716 if (a_src) {
33717 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33718 }
33719 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
33720 status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
33721 if (a_dst) {
33722 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33723 }
33724 if (a_src) {
33725 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33726 }
33727 if (status.repr) {
33728 goto suspend;
33729 }
33730 if (self->private_impl.f_comment_type > 0) {
33731 goto label__outer__continue;
33732 }
33733 }
33734 }
33735 status = wuffs_base__make_status(wuffs_json__error__bad_input);
33736 goto exit;
33737 }
33738 label__goto_parsed_a_leaf_value__break:;
33739 if (v_depth == 0) {
33740 goto label__outer__break;
33741 }
33742 v_expect = v_expect_after_value;
33743 }
33744 label__outer__break:;
33745 if (self->private_impl.f_quirks[17] || self->private_impl.f_quirks[18]) {
33746 if (a_dst) {
33747 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33748 }
33749 if (a_src) {
33750 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33751 }
33752 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
33753 status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src);
33754 if (a_dst) {
33755 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
33756 }
33757 if (a_src) {
33758 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33759 }
33760 if (status.repr) {
33761 goto suspend;
33762 }
33763 }
33764 self->private_impl.f_end_of_data = true;
33765
33766 ok:
33767 self->private_impl.p_decode_tokens[0] = 0;
33768 goto exit;
33769 }
33770
33771 goto suspend;
33772 suspend:
33773 self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
33774 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
33775 self->private_data.s_decode_tokens[0].v_depth = v_depth;
33776 self->private_data.s_decode_tokens[0].v_expect = v_expect;
33777 self->private_data.s_decode_tokens[0].v_expect_after_value = v_expect_after_value;
33778
33779 goto exit;
33780 exit:
33781 if (a_dst) {
33782 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
33783 }
33784 if (a_src) {
33785 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33786 }
33787
33788 if (wuffs_base__status__is_error(&status)) {
33789 self->private_impl.magic = WUFFS_BASE__DISABLED;
33790 }
33791 return status;
33792 }
33793
33794 // -------- func json.decoder.decode_number
33795
33796 static uint32_t
wuffs_json__decoder__decode_number(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src)33797 wuffs_json__decoder__decode_number(
33798 wuffs_json__decoder* self,
33799 wuffs_base__io_buffer* a_src) {
33800 uint8_t v_c = 0;
33801 uint32_t v_n = 0;
33802 uint32_t v_floating_point = 0;
33803
33804 const uint8_t* iop_a_src = NULL;
33805 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33806 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33807 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33808 if (a_src) {
33809 io0_a_src = a_src->data.ptr;
33810 io1_a_src = io0_a_src + a_src->meta.ri;
33811 iop_a_src = io1_a_src;
33812 io2_a_src = io0_a_src + a_src->meta.wi;
33813 }
33814
33815 while (true) {
33816 v_n = 0;
33817 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33818 if ( ! (a_src && a_src->meta.closed)) {
33819 v_n |= 768;
33820 }
33821 goto label__goto_done__break;
33822 }
33823 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33824 if (v_c != 45) {
33825 } else {
33826 v_n += 1;
33827 iop_a_src += 1;
33828 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33829 if ( ! (a_src && a_src->meta.closed)) {
33830 v_n |= 768;
33831 }
33832 v_n |= 256;
33833 goto label__goto_done__break;
33834 }
33835 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33836 }
33837 if (v_c == 48) {
33838 v_n += 1;
33839 iop_a_src += 1;
33840 } else {
33841 if (a_src) {
33842 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33843 }
33844 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33845 if (a_src) {
33846 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33847 }
33848 if (v_n > 99) {
33849 goto label__goto_done__break;
33850 }
33851 }
33852 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33853 if ( ! (a_src && a_src->meta.closed)) {
33854 v_n |= 768;
33855 }
33856 goto label__goto_done__break;
33857 }
33858 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33859 if (v_c != 46) {
33860 } else {
33861 if (v_n >= 99) {
33862 v_n |= 512;
33863 goto label__goto_done__break;
33864 }
33865 v_n += 1;
33866 iop_a_src += 1;
33867 v_floating_point = 128;
33868 if (a_src) {
33869 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33870 }
33871 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33872 if (a_src) {
33873 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33874 }
33875 if (v_n > 99) {
33876 goto label__goto_done__break;
33877 }
33878 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33879 if ( ! (a_src && a_src->meta.closed)) {
33880 v_n |= 768;
33881 }
33882 goto label__goto_done__break;
33883 }
33884 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33885 }
33886 if ((v_c != 69) && (v_c != 101)) {
33887 goto label__goto_done__break;
33888 }
33889 if (v_n >= 99) {
33890 v_n |= 512;
33891 goto label__goto_done__break;
33892 }
33893 v_n += 1;
33894 iop_a_src += 1;
33895 v_floating_point = 128;
33896 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33897 if ( ! (a_src && a_src->meta.closed)) {
33898 v_n |= 768;
33899 }
33900 v_n |= 256;
33901 goto label__goto_done__break;
33902 }
33903 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33904 if ((v_c != 43) && (v_c != 45)) {
33905 } else {
33906 if (v_n >= 99) {
33907 v_n |= 512;
33908 goto label__goto_done__break;
33909 }
33910 v_n += 1;
33911 iop_a_src += 1;
33912 }
33913 if (a_src) {
33914 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33915 }
33916 v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
33917 if (a_src) {
33918 iop_a_src = a_src->data.ptr + a_src->meta.ri;
33919 }
33920 goto label__goto_done__break;
33921 }
33922 label__goto_done__break:;
33923 if (a_src) {
33924 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33925 }
33926 return (v_n | v_floating_point);
33927 }
33928
33929 // -------- func json.decoder.decode_digits
33930
33931 static uint32_t
wuffs_json__decoder__decode_digits(wuffs_json__decoder * self,wuffs_base__io_buffer * a_src,uint32_t a_n)33932 wuffs_json__decoder__decode_digits(
33933 wuffs_json__decoder* self,
33934 wuffs_base__io_buffer* a_src,
33935 uint32_t a_n) {
33936 uint8_t v_c = 0;
33937 uint32_t v_n = 0;
33938
33939 const uint8_t* iop_a_src = NULL;
33940 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33941 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33942 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33943 if (a_src) {
33944 io0_a_src = a_src->data.ptr;
33945 io1_a_src = io0_a_src + a_src->meta.ri;
33946 iop_a_src = io1_a_src;
33947 io2_a_src = io0_a_src + a_src->meta.wi;
33948 }
33949
33950 v_n = a_n;
33951 while (true) {
33952 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
33953 if ( ! (a_src && a_src->meta.closed)) {
33954 v_n |= 768;
33955 }
33956 goto label__0__break;
33957 }
33958 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
33959 if (0 == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c]) {
33960 goto label__0__break;
33961 }
33962 if (v_n >= 99) {
33963 v_n |= 512;
33964 goto label__0__break;
33965 }
33966 v_n += 1;
33967 iop_a_src += 1;
33968 }
33969 label__0__break:;
33970 if (v_n == a_n) {
33971 v_n |= 256;
33972 }
33973 if (a_src) {
33974 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
33975 }
33976 return v_n;
33977 }
33978
33979 // -------- func json.decoder.decode_leading
33980
33981 static wuffs_base__status
wuffs_json__decoder__decode_leading(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)33982 wuffs_json__decoder__decode_leading(
33983 wuffs_json__decoder* self,
33984 wuffs_base__token_buffer* a_dst,
33985 wuffs_base__io_buffer* a_src) {
33986 wuffs_base__status status = wuffs_base__make_status(NULL);
33987
33988 uint8_t v_c = 0;
33989 uint32_t v_u = 0;
33990
33991 wuffs_base__token* iop_a_dst = NULL;
33992 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33993 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33994 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
33995 if (a_dst) {
33996 io0_a_dst = a_dst->data.ptr;
33997 io1_a_dst = io0_a_dst + a_dst->meta.wi;
33998 iop_a_dst = io1_a_dst;
33999 io2_a_dst = io0_a_dst + a_dst->data.len;
34000 if (a_dst->meta.closed) {
34001 io2_a_dst = iop_a_dst;
34002 }
34003 }
34004 const uint8_t* iop_a_src = NULL;
34005 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34006 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34007 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34008 if (a_src) {
34009 io0_a_src = a_src->data.ptr;
34010 io1_a_src = io0_a_src + a_src->meta.ri;
34011 iop_a_src = io1_a_src;
34012 io2_a_src = io0_a_src + a_src->meta.wi;
34013 }
34014
34015 uint32_t coro_susp_point = self->private_impl.p_decode_leading[0];
34016 switch (coro_susp_point) {
34017 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34018
34019 self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15];
34020 self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16];
34021 label__0__continue:;
34022 while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) {
34023 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34024 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34025 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34026 goto label__0__continue;
34027 }
34028 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
34029 if (a_src && a_src->meta.closed) {
34030 goto label__0__break;
34031 }
34032 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34033 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34034 goto label__0__continue;
34035 }
34036 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
34037 if ((v_c == 30) && self->private_impl.f_allow_leading_ars) {
34038 self->private_impl.f_allow_leading_ars = false;
34039 iop_a_src += 1;
34040 *iop_a_dst++ = wuffs_base__make_token(
34041 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34042 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34043 goto label__0__continue;
34044 } else if ((v_c == 239) && self->private_impl.f_allow_leading_ubom) {
34045 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
34046 if (a_src && a_src->meta.closed) {
34047 goto label__0__break;
34048 }
34049 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34050 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
34051 goto label__0__continue;
34052 }
34053 v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
34054 if (v_u == 12565487) {
34055 self->private_impl.f_allow_leading_ubom = false;
34056 iop_a_src += 3;
34057 *iop_a_dst++ = wuffs_base__make_token(
34058 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34059 (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34060 goto label__0__continue;
34061 }
34062 }
34063 goto label__0__break;
34064 }
34065 label__0__break:;
34066
34067 ok:
34068 self->private_impl.p_decode_leading[0] = 0;
34069 goto exit;
34070 }
34071
34072 goto suspend;
34073 suspend:
34074 self->private_impl.p_decode_leading[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34075
34076 goto exit;
34077 exit:
34078 if (a_dst) {
34079 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34080 }
34081 if (a_src) {
34082 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34083 }
34084
34085 return status;
34086 }
34087
34088 // -------- func json.decoder.decode_comment
34089
34090 static wuffs_base__status
wuffs_json__decoder__decode_comment(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)34091 wuffs_json__decoder__decode_comment(
34092 wuffs_json__decoder* self,
34093 wuffs_base__token_buffer* a_dst,
34094 wuffs_base__io_buffer* a_src) {
34095 wuffs_base__status status = wuffs_base__make_status(NULL);
34096
34097 uint8_t v_c = 0;
34098 uint16_t v_c2 = 0;
34099 uint32_t v_length = 0;
34100
34101 wuffs_base__token* iop_a_dst = NULL;
34102 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34103 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34104 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34105 if (a_dst) {
34106 io0_a_dst = a_dst->data.ptr;
34107 io1_a_dst = io0_a_dst + a_dst->meta.wi;
34108 iop_a_dst = io1_a_dst;
34109 io2_a_dst = io0_a_dst + a_dst->data.len;
34110 if (a_dst->meta.closed) {
34111 io2_a_dst = iop_a_dst;
34112 }
34113 }
34114 const uint8_t* iop_a_src = NULL;
34115 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34116 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34117 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34118 if (a_src) {
34119 io0_a_src = a_src->data.ptr;
34120 io1_a_src = io0_a_src + a_src->meta.ri;
34121 iop_a_src = io1_a_src;
34122 io2_a_src = io0_a_src + a_src->meta.wi;
34123 }
34124
34125 uint32_t coro_susp_point = self->private_impl.p_decode_comment[0];
34126 switch (coro_susp_point) {
34127 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34128
34129 self->private_impl.f_comment_type = 0;
34130 label__0__continue:;
34131 while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1)) {
34132 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34133 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34134 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34135 goto label__0__continue;
34136 }
34137 if (a_src && a_src->meta.closed) {
34138 status = wuffs_base__make_status(NULL);
34139 goto ok;
34140 }
34141 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34142 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34143 }
34144 v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
34145 if ((v_c2 == 10799) && self->private_impl.f_quirks[11]) {
34146 iop_a_src += 2;
34147 v_length = 2;
34148 label__comment_block__continue:;
34149 while (true) {
34150 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34151 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34152 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
34153 v_length = 0;
34154 goto label__comment_block__continue;
34155 }
34156 while (true) {
34157 if (((uint64_t)(io2_a_src - iop_a_src)) <= 1) {
34158 if (v_length > 0) {
34159 *iop_a_dst++ = wuffs_base__make_token(
34160 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34161 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34162 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34163 }
34164 if (a_src && a_src->meta.closed) {
34165 status = wuffs_base__make_status(wuffs_json__error__bad_input);
34166 goto exit;
34167 }
34168 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34169 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
34170 v_length = 0;
34171 goto label__comment_block__continue;
34172 }
34173 v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
34174 if (v_c2 == 12074) {
34175 iop_a_src += 2;
34176 *iop_a_dst++ = wuffs_base__make_token(
34177 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34178 (((uint64_t)((v_length + 2))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34179 self->private_impl.f_comment_type = 1;
34180 status = wuffs_base__make_status(NULL);
34181 goto ok;
34182 }
34183 iop_a_src += 1;
34184 if (v_length >= 65533) {
34185 *iop_a_dst++ = wuffs_base__make_token(
34186 (((uint64_t)(2)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34187 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34188 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34189 v_length = 0;
34190 goto label__comment_block__continue;
34191 }
34192 v_length += 1;
34193 }
34194 }
34195 } else if ((v_c2 == 12079) && self->private_impl.f_quirks[12]) {
34196 iop_a_src += 2;
34197 v_length = 2;
34198 label__comment_line__continue:;
34199 while (true) {
34200 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34201 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34202 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
34203 v_length = 0;
34204 goto label__comment_line__continue;
34205 }
34206 while (true) {
34207 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
34208 if (a_src && a_src->meta.closed) {
34209 *iop_a_dst++ = wuffs_base__make_token(
34210 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34211 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34212 self->private_impl.f_comment_type = 2;
34213 status = wuffs_base__make_status(NULL);
34214 goto ok;
34215 } else if (v_length > 0) {
34216 *iop_a_dst++ = wuffs_base__make_token(
34217 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34218 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34219 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34220 }
34221 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34222 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
34223 v_length = 0;
34224 goto label__comment_line__continue;
34225 }
34226 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
34227 if (v_c == 10) {
34228 *iop_a_dst++ = wuffs_base__make_token(
34229 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34230 (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34231 self->private_impl.f_comment_type = 2;
34232 status = wuffs_base__make_status(NULL);
34233 goto ok;
34234 }
34235 iop_a_src += 1;
34236 if (v_length >= 65533) {
34237 *iop_a_dst++ = wuffs_base__make_token(
34238 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34239 (((uint64_t)(1)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
34240 (((uint64_t)((v_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34241 v_length = 0;
34242 goto label__comment_line__continue;
34243 }
34244 v_length += 1;
34245 }
34246 }
34247 }
34248
34249 ok:
34250 self->private_impl.p_decode_comment[0] = 0;
34251 goto exit;
34252 }
34253
34254 goto suspend;
34255 suspend:
34256 self->private_impl.p_decode_comment[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34257
34258 goto exit;
34259 exit:
34260 if (a_dst) {
34261 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34262 }
34263 if (a_src) {
34264 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34265 }
34266
34267 return status;
34268 }
34269
34270 // -------- func json.decoder.decode_inf_nan
34271
34272 static wuffs_base__status
wuffs_json__decoder__decode_inf_nan(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)34273 wuffs_json__decoder__decode_inf_nan(
34274 wuffs_json__decoder* self,
34275 wuffs_base__token_buffer* a_dst,
34276 wuffs_base__io_buffer* a_src) {
34277 wuffs_base__status status = wuffs_base__make_status(NULL);
34278
34279 uint32_t v_c4 = 0;
34280 uint32_t v_neg = 0;
34281
34282 wuffs_base__token* iop_a_dst = NULL;
34283 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34284 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34285 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34286 if (a_dst) {
34287 io0_a_dst = a_dst->data.ptr;
34288 io1_a_dst = io0_a_dst + a_dst->meta.wi;
34289 iop_a_dst = io1_a_dst;
34290 io2_a_dst = io0_a_dst + a_dst->data.len;
34291 if (a_dst->meta.closed) {
34292 io2_a_dst = iop_a_dst;
34293 }
34294 }
34295 const uint8_t* iop_a_src = NULL;
34296 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34297 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34298 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34299 if (a_src) {
34300 io0_a_src = a_src->data.ptr;
34301 io1_a_src = io0_a_src + a_src->meta.ri;
34302 iop_a_src = io1_a_src;
34303 io2_a_src = io0_a_src + a_src->meta.wi;
34304 }
34305
34306 uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan[0];
34307 if (coro_susp_point) {
34308 v_neg = self->private_data.s_decode_inf_nan[0].v_neg;
34309 }
34310 switch (coro_susp_point) {
34311 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34312
34313 label__0__continue:;
34314 while (true) {
34315 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34316 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34317 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34318 goto label__0__continue;
34319 }
34320 if (((uint64_t)(io2_a_src - iop_a_src)) <= 2) {
34321 if (a_src && a_src->meta.closed) {
34322 status = wuffs_base__make_status(wuffs_json__error__bad_input);
34323 goto exit;
34324 }
34325 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34326 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34327 goto label__0__continue;
34328 }
34329 v_c4 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
34330 if ((v_c4 | 2105376) == 6712937) {
34331 if (((uint64_t)(io2_a_src - iop_a_src)) > 7) {
34332 if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536) == 8751735898823356009) {
34333 *iop_a_dst++ = wuffs_base__make_token(
34334 (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34335 (((uint64_t)(8)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34336 iop_a_src += 8;
34337 status = wuffs_base__make_status(NULL);
34338 goto ok;
34339 }
34340 } else if ( ! (a_src && a_src->meta.closed)) {
34341 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34342 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
34343 goto label__0__continue;
34344 }
34345 *iop_a_dst++ = wuffs_base__make_token(
34346 (((uint64_t)(10485792)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34347 (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34348 iop_a_src += 3;
34349 status = wuffs_base__make_status(NULL);
34350 goto ok;
34351 } else if ((v_c4 | 2105376) == 7233902) {
34352 *iop_a_dst++ = wuffs_base__make_token(
34353 (((uint64_t)(10485888)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34354 (((uint64_t)(3)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34355 iop_a_src += 3;
34356 status = wuffs_base__make_status(NULL);
34357 goto ok;
34358 } else if ((v_c4 & 255) == 43) {
34359 v_neg = 0;
34360 } else if ((v_c4 & 255) == 45) {
34361 v_neg = 1;
34362 } else {
34363 status = wuffs_base__make_status(wuffs_json__error__bad_input);
34364 goto exit;
34365 }
34366 if (((uint64_t)(io2_a_src - iop_a_src)) <= 3) {
34367 if (a_src && a_src->meta.closed) {
34368 status = wuffs_base__make_status(wuffs_json__error__bad_input);
34369 goto exit;
34370 }
34371 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34372 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
34373 goto label__0__continue;
34374 }
34375 v_c4 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8);
34376 if ((v_c4 | 2105376) == 6712937) {
34377 if (((uint64_t)(io2_a_src - iop_a_src)) > 8) {
34378 if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1) | 2314885530818453536) == 8751735898823356009) {
34379 *iop_a_dst++ = wuffs_base__make_token(
34380 (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34381 (((uint64_t)(9)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34382 iop_a_src += 9;
34383 status = wuffs_base__make_status(NULL);
34384 goto ok;
34385 }
34386 } else if ( ! (a_src && a_src->meta.closed)) {
34387 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34388 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
34389 goto label__0__continue;
34390 }
34391 *iop_a_dst++ = wuffs_base__make_token(
34392 (((uint64_t)((10485760 | (((uint32_t)(32)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34393 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34394 iop_a_src += 4;
34395 status = wuffs_base__make_status(NULL);
34396 goto ok;
34397 } else if ((v_c4 | 2105376) == 7233902) {
34398 *iop_a_dst++ = wuffs_base__make_token(
34399 (((uint64_t)((10485760 | (((uint32_t)(128)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34400 (((uint64_t)(4)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34401 iop_a_src += 4;
34402 status = wuffs_base__make_status(NULL);
34403 goto ok;
34404 }
34405 status = wuffs_base__make_status(wuffs_json__error__bad_input);
34406 goto exit;
34407 }
34408
34409 ok:
34410 self->private_impl.p_decode_inf_nan[0] = 0;
34411 goto exit;
34412 }
34413
34414 goto suspend;
34415 suspend:
34416 self->private_impl.p_decode_inf_nan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34417 self->private_data.s_decode_inf_nan[0].v_neg = v_neg;
34418
34419 goto exit;
34420 exit:
34421 if (a_dst) {
34422 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34423 }
34424 if (a_src) {
34425 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34426 }
34427
34428 return status;
34429 }
34430
34431 // -------- func json.decoder.decode_trailer
34432
34433 static wuffs_base__status
wuffs_json__decoder__decode_trailer(wuffs_json__decoder * self,wuffs_base__token_buffer * a_dst,wuffs_base__io_buffer * a_src)34434 wuffs_json__decoder__decode_trailer(
34435 wuffs_json__decoder* self,
34436 wuffs_base__token_buffer* a_dst,
34437 wuffs_base__io_buffer* a_src) {
34438 wuffs_base__status status = wuffs_base__make_status(NULL);
34439
34440 uint8_t v_c = 0;
34441 uint32_t v_whitespace_length = 0;
34442
34443 wuffs_base__token* iop_a_dst = NULL;
34444 wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34445 wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34446 wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34447 if (a_dst) {
34448 io0_a_dst = a_dst->data.ptr;
34449 io1_a_dst = io0_a_dst + a_dst->meta.wi;
34450 iop_a_dst = io1_a_dst;
34451 io2_a_dst = io0_a_dst + a_dst->data.len;
34452 if (a_dst->meta.closed) {
34453 io2_a_dst = iop_a_dst;
34454 }
34455 }
34456 const uint8_t* iop_a_src = NULL;
34457 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34458 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34459 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34460 if (a_src) {
34461 io0_a_src = a_src->data.ptr;
34462 io1_a_src = io0_a_src + a_src->meta.ri;
34463 iop_a_src = io1_a_src;
34464 io2_a_src = io0_a_src + a_src->meta.wi;
34465 }
34466
34467 uint32_t coro_susp_point = self->private_impl.p_decode_trailer[0];
34468 switch (coro_susp_point) {
34469 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34470
34471 if (self->private_impl.f_quirks[18]) {
34472 self->private_impl.f_trailer_stop = 10;
34473 } else {
34474 self->private_impl.f_trailer_stop = 0;
34475 }
34476 label__outer__continue:;
34477 while (true) {
34478 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
34479 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
34480 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
34481 v_whitespace_length = 0;
34482 goto label__outer__continue;
34483 }
34484 while (true) {
34485 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
34486 if (v_whitespace_length > 0) {
34487 *iop_a_dst++ = wuffs_base__make_token(
34488 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34489 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34490 v_whitespace_length = 0;
34491 }
34492 if (a_src && a_src->meta.closed) {
34493 goto label__outer__break;
34494 }
34495 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34496 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
34497 v_whitespace_length = 0;
34498 goto label__outer__continue;
34499 }
34500 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
34501 if (WUFFS_JSON__LUT_CLASSES[v_c] != 0) {
34502 if (v_whitespace_length > 0) {
34503 *iop_a_dst++ = wuffs_base__make_token(
34504 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34505 (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34506 v_whitespace_length = 0;
34507 }
34508 if (self->private_impl.f_trailer_stop > 0) {
34509 status = wuffs_base__make_status(wuffs_json__error__bad_input);
34510 goto exit;
34511 }
34512 if (a_dst) {
34513 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34514 }
34515 if (a_src) {
34516 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34517 }
34518 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34519 status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
34520 if (a_dst) {
34521 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
34522 }
34523 if (a_src) {
34524 iop_a_src = a_src->data.ptr + a_src->meta.ri;
34525 }
34526 if (status.repr) {
34527 goto suspend;
34528 }
34529 v_c = 0;
34530 v_whitespace_length = 0;
34531 if (self->private_impl.f_comment_type > 0) {
34532 goto label__outer__continue;
34533 }
34534 status = wuffs_base__make_status(NULL);
34535 goto ok;
34536 }
34537 iop_a_src += 1;
34538 if ((v_whitespace_length >= 65534) || (v_c == self->private_impl.f_trailer_stop)) {
34539 *iop_a_dst++ = wuffs_base__make_token(
34540 (((uint64_t)(0)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
34541 (((uint64_t)((v_whitespace_length + 1))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
34542 v_whitespace_length = 0;
34543 if (v_c == self->private_impl.f_trailer_stop) {
34544 status = wuffs_base__make_status(NULL);
34545 goto ok;
34546 }
34547 goto label__outer__continue;
34548 }
34549 v_whitespace_length += 1;
34550 }
34551 }
34552 label__outer__break:;
34553
34554 ok:
34555 self->private_impl.p_decode_trailer[0] = 0;
34556 goto exit;
34557 }
34558
34559 goto suspend;
34560 suspend:
34561 self->private_impl.p_decode_trailer[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34562
34563 goto exit;
34564 exit:
34565 if (a_dst) {
34566 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
34567 }
34568 if (a_src) {
34569 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34570 }
34571
34572 return status;
34573 }
34574
34575 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
34576
34577 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
34578
34579 // ---------------- Status Codes Implementations
34580
34581 const char wuffs_nie__error__bad_header[] = "#nie: bad header";
34582 const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file";
34583 const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read";
34584
34585 // ---------------- Private Consts
34586
34587 // ---------------- Private Initializer Prototypes
34588
34589 // ---------------- Private Function Prototypes
34590
34591 static wuffs_base__status
34592 wuffs_nie__decoder__swizzle(
34593 wuffs_nie__decoder* self,
34594 wuffs_base__pixel_buffer* a_dst,
34595 wuffs_base__io_buffer* a_src);
34596
34597 // ---------------- VTables
34598
34599 const wuffs_base__image_decoder__func_ptrs
34600 wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = {
34601 (wuffs_base__status(*)(void*,
34602 wuffs_base__pixel_buffer*,
34603 wuffs_base__io_buffer*,
34604 wuffs_base__pixel_blend,
34605 wuffs_base__slice_u8,
34606 wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame),
34607 (wuffs_base__status(*)(void*,
34608 wuffs_base__frame_config*,
34609 wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config),
34610 (wuffs_base__status(*)(void*,
34611 wuffs_base__image_config*,
34612 wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config),
34613 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect),
34614 (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops),
34615 (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs),
34616 (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames),
34617 (wuffs_base__status(*)(void*,
34618 uint64_t,
34619 uint64_t))(&wuffs_nie__decoder__restart_frame),
34620 (wuffs_base__empty_struct(*)(void*,
34621 uint32_t,
34622 bool))(&wuffs_nie__decoder__set_quirk_enabled),
34623 (wuffs_base__empty_struct(*)(void*,
34624 uint32_t,
34625 bool))(&wuffs_nie__decoder__set_report_metadata),
34626 (wuffs_base__status(*)(void*,
34627 wuffs_base__io_buffer*,
34628 wuffs_base__more_information*,
34629 wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more),
34630 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len),
34631 };
34632
34633 // ---------------- Initializer Implementations
34634
34635 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_nie__decoder__initialize(wuffs_nie__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)34636 wuffs_nie__decoder__initialize(
34637 wuffs_nie__decoder* self,
34638 size_t sizeof_star_self,
34639 uint64_t wuffs_version,
34640 uint32_t options){
34641 if (!self) {
34642 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34643 }
34644 if (sizeof(*self) != sizeof_star_self) {
34645 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
34646 }
34647 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
34648 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
34649 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
34650 }
34651
34652 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
34653 // The whole point of this if-check is to detect an uninitialized *self.
34654 // We disable the warning on GCC. Clang-5.0 does not have this warning.
34655 #if !defined(__clang__) && defined(__GNUC__)
34656 #pragma GCC diagnostic push
34657 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34658 #endif
34659 if (self->private_impl.magic != 0) {
34660 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
34661 }
34662 #if !defined(__clang__) && defined(__GNUC__)
34663 #pragma GCC diagnostic pop
34664 #endif
34665 } else {
34666 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
34667 memset(self, 0, sizeof(*self));
34668 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
34669 } else {
34670 memset(&(self->private_impl), 0, sizeof(self->private_impl));
34671 }
34672 }
34673
34674 self->private_impl.magic = WUFFS_BASE__MAGIC;
34675 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
34676 wuffs_base__image_decoder__vtable_name;
34677 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
34678 (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder);
34679 return wuffs_base__make_status(NULL);
34680 }
34681
34682 wuffs_nie__decoder*
wuffs_nie__decoder__alloc()34683 wuffs_nie__decoder__alloc() {
34684 wuffs_nie__decoder* x =
34685 (wuffs_nie__decoder*)(calloc(sizeof(wuffs_nie__decoder), 1));
34686 if (!x) {
34687 return NULL;
34688 }
34689 if (wuffs_nie__decoder__initialize(
34690 x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
34691 free(x);
34692 return NULL;
34693 }
34694 return x;
34695 }
34696
34697 size_t
sizeof__wuffs_nie__decoder()34698 sizeof__wuffs_nie__decoder() {
34699 return sizeof(wuffs_nie__decoder);
34700 }
34701
34702 // ---------------- Function Implementations
34703
34704 // -------- func nie.decoder.set_quirk_enabled
34705
34706 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_nie__decoder__set_quirk_enabled(wuffs_nie__decoder * self,uint32_t a_quirk,bool a_enabled)34707 wuffs_nie__decoder__set_quirk_enabled(
34708 wuffs_nie__decoder* self,
34709 uint32_t a_quirk,
34710 bool a_enabled) {
34711 return wuffs_base__make_empty_struct();
34712 }
34713
34714 // -------- func nie.decoder.decode_image_config
34715
34716 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__decode_image_config(wuffs_nie__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)34717 wuffs_nie__decoder__decode_image_config(
34718 wuffs_nie__decoder* self,
34719 wuffs_base__image_config* a_dst,
34720 wuffs_base__io_buffer* a_src) {
34721 if (!self) {
34722 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34723 }
34724 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34725 return wuffs_base__make_status(
34726 (self->private_impl.magic == WUFFS_BASE__DISABLED)
34727 ? wuffs_base__error__disabled_by_previous_error
34728 : wuffs_base__error__initialize_not_called);
34729 }
34730 if (!a_src) {
34731 self->private_impl.magic = WUFFS_BASE__DISABLED;
34732 return wuffs_base__make_status(wuffs_base__error__bad_argument);
34733 }
34734 if ((self->private_impl.active_coroutine != 0) &&
34735 (self->private_impl.active_coroutine != 1)) {
34736 self->private_impl.magic = WUFFS_BASE__DISABLED;
34737 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34738 }
34739 self->private_impl.active_coroutine = 0;
34740 wuffs_base__status status = wuffs_base__make_status(NULL);
34741
34742 uint32_t v_a = 0;
34743
34744 const uint8_t* iop_a_src = NULL;
34745 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34746 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34747 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34748 if (a_src) {
34749 io0_a_src = a_src->data.ptr;
34750 io1_a_src = io0_a_src + a_src->meta.ri;
34751 iop_a_src = io1_a_src;
34752 io2_a_src = io0_a_src + a_src->meta.wi;
34753 }
34754
34755 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
34756 switch (coro_susp_point) {
34757 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34758
34759 if (self->private_impl.f_call_sequence != 0) {
34760 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
34761 goto exit;
34762 }
34763 {
34764 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34765 uint32_t t_0;
34766 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34767 t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34768 iop_a_src += 4;
34769 } else {
34770 self->private_data.s_decode_image_config[0].scratch = 0;
34771 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
34772 while (true) {
34773 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34774 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34775 goto suspend;
34776 }
34777 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34778 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
34779 *scratch <<= 8;
34780 *scratch >>= 8;
34781 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
34782 if (num_bits_0 == 24) {
34783 t_0 = ((uint32_t)(*scratch));
34784 break;
34785 }
34786 num_bits_0 += 8;
34787 *scratch |= ((uint64_t)(num_bits_0)) << 56;
34788 }
34789 }
34790 v_a = t_0;
34791 }
34792 if (v_a != 1169146734) {
34793 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34794 goto exit;
34795 }
34796 {
34797 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
34798 uint32_t t_1;
34799 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34800 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34801 iop_a_src += 4;
34802 } else {
34803 self->private_data.s_decode_image_config[0].scratch = 0;
34804 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
34805 while (true) {
34806 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34807 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34808 goto suspend;
34809 }
34810 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34811 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
34812 *scratch <<= 8;
34813 *scratch >>= 8;
34814 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
34815 if (num_bits_1 == 24) {
34816 t_1 = ((uint32_t)(*scratch));
34817 break;
34818 }
34819 num_bits_1 += 8;
34820 *scratch |= ((uint64_t)(num_bits_1)) << 56;
34821 }
34822 }
34823 v_a = t_1;
34824 }
34825 if (v_a == 879649535) {
34826 self->private_impl.f_pixfmt = 2164295816;
34827 } else if (v_a == 946758399) {
34828 self->private_impl.f_pixfmt = 2164308923;
34829 } else if (v_a == 879780607) {
34830 status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
34831 goto exit;
34832 } else if (v_a == 946889471) {
34833 status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
34834 goto exit;
34835 } else {
34836 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34837 goto exit;
34838 }
34839 {
34840 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
34841 uint32_t t_2;
34842 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34843 t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34844 iop_a_src += 4;
34845 } else {
34846 self->private_data.s_decode_image_config[0].scratch = 0;
34847 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
34848 while (true) {
34849 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34850 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34851 goto suspend;
34852 }
34853 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34854 uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
34855 *scratch <<= 8;
34856 *scratch >>= 8;
34857 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
34858 if (num_bits_2 == 24) {
34859 t_2 = ((uint32_t)(*scratch));
34860 break;
34861 }
34862 num_bits_2 += 8;
34863 *scratch |= ((uint64_t)(num_bits_2)) << 56;
34864 }
34865 }
34866 v_a = t_2;
34867 }
34868 if (v_a >= 2147483648) {
34869 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34870 goto exit;
34871 }
34872 self->private_impl.f_width = v_a;
34873 {
34874 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
34875 uint32_t t_3;
34876 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
34877 t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
34878 iop_a_src += 4;
34879 } else {
34880 self->private_data.s_decode_image_config[0].scratch = 0;
34881 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
34882 while (true) {
34883 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
34884 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
34885 goto suspend;
34886 }
34887 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
34888 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
34889 *scratch <<= 8;
34890 *scratch >>= 8;
34891 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
34892 if (num_bits_3 == 24) {
34893 t_3 = ((uint32_t)(*scratch));
34894 break;
34895 }
34896 num_bits_3 += 8;
34897 *scratch |= ((uint64_t)(num_bits_3)) << 56;
34898 }
34899 }
34900 v_a = t_3;
34901 }
34902 if (v_a >= 2147483648) {
34903 status = wuffs_base__make_status(wuffs_nie__error__bad_header);
34904 goto exit;
34905 }
34906 self->private_impl.f_height = v_a;
34907 if (a_dst != NULL) {
34908 wuffs_base__image_config__set(
34909 a_dst,
34910 self->private_impl.f_pixfmt,
34911 0,
34912 self->private_impl.f_width,
34913 self->private_impl.f_height,
34914 16,
34915 false);
34916 }
34917 self->private_impl.f_call_sequence = 3;
34918
34919 goto ok;
34920 ok:
34921 self->private_impl.p_decode_image_config[0] = 0;
34922 goto exit;
34923 }
34924
34925 goto suspend;
34926 suspend:
34927 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
34928 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
34929
34930 goto exit;
34931 exit:
34932 if (a_src) {
34933 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34934 }
34935
34936 if (wuffs_base__status__is_error(&status)) {
34937 self->private_impl.magic = WUFFS_BASE__DISABLED;
34938 }
34939 return status;
34940 }
34941
34942 // -------- func nie.decoder.decode_frame_config
34943
34944 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__decode_frame_config(wuffs_nie__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)34945 wuffs_nie__decoder__decode_frame_config(
34946 wuffs_nie__decoder* self,
34947 wuffs_base__frame_config* a_dst,
34948 wuffs_base__io_buffer* a_src) {
34949 if (!self) {
34950 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
34951 }
34952 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
34953 return wuffs_base__make_status(
34954 (self->private_impl.magic == WUFFS_BASE__DISABLED)
34955 ? wuffs_base__error__disabled_by_previous_error
34956 : wuffs_base__error__initialize_not_called);
34957 }
34958 if (!a_src) {
34959 self->private_impl.magic = WUFFS_BASE__DISABLED;
34960 return wuffs_base__make_status(wuffs_base__error__bad_argument);
34961 }
34962 if ((self->private_impl.active_coroutine != 0) &&
34963 (self->private_impl.active_coroutine != 2)) {
34964 self->private_impl.magic = WUFFS_BASE__DISABLED;
34965 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
34966 }
34967 self->private_impl.active_coroutine = 0;
34968 wuffs_base__status status = wuffs_base__make_status(NULL);
34969
34970 const uint8_t* iop_a_src = NULL;
34971 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34972 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34973 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
34974 if (a_src) {
34975 io0_a_src = a_src->data.ptr;
34976 io1_a_src = io0_a_src + a_src->meta.ri;
34977 iop_a_src = io1_a_src;
34978 io2_a_src = io0_a_src + a_src->meta.wi;
34979 }
34980
34981 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
34982 switch (coro_susp_point) {
34983 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
34984
34985 if (self->private_impl.f_call_sequence < 3) {
34986 if (a_src) {
34987 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
34988 }
34989 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
34990 status = wuffs_nie__decoder__decode_image_config(self, NULL, a_src);
34991 if (a_src) {
34992 iop_a_src = a_src->data.ptr + a_src->meta.ri;
34993 }
34994 if (status.repr) {
34995 goto suspend;
34996 }
34997 } else if (self->private_impl.f_call_sequence == 3) {
34998 if (16 != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
34999 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
35000 goto exit;
35001 }
35002 } else if (self->private_impl.f_call_sequence == 4) {
35003 self->private_impl.f_call_sequence = 255;
35004 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
35005 goto ok;
35006 } else {
35007 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
35008 goto ok;
35009 }
35010 if (a_dst != NULL) {
35011 wuffs_base__frame_config__set(
35012 a_dst,
35013 wuffs_base__utility__make_rect_ie_u32(
35014 0,
35015 0,
35016 self->private_impl.f_width,
35017 self->private_impl.f_height),
35018 ((wuffs_base__flicks)(0)),
35019 0,
35020 16,
35021 0,
35022 false,
35023 false,
35024 0);
35025 }
35026 self->private_impl.f_call_sequence = 4;
35027
35028 ok:
35029 self->private_impl.p_decode_frame_config[0] = 0;
35030 goto exit;
35031 }
35032
35033 goto suspend;
35034 suspend:
35035 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35036 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
35037
35038 goto exit;
35039 exit:
35040 if (a_src) {
35041 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35042 }
35043
35044 if (wuffs_base__status__is_error(&status)) {
35045 self->private_impl.magic = WUFFS_BASE__DISABLED;
35046 }
35047 return status;
35048 }
35049
35050 // -------- func nie.decoder.decode_frame
35051
35052 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__decode_frame(wuffs_nie__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)35053 wuffs_nie__decoder__decode_frame(
35054 wuffs_nie__decoder* self,
35055 wuffs_base__pixel_buffer* a_dst,
35056 wuffs_base__io_buffer* a_src,
35057 wuffs_base__pixel_blend a_blend,
35058 wuffs_base__slice_u8 a_workbuf,
35059 wuffs_base__decode_frame_options* a_opts) {
35060 if (!self) {
35061 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35062 }
35063 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35064 return wuffs_base__make_status(
35065 (self->private_impl.magic == WUFFS_BASE__DISABLED)
35066 ? wuffs_base__error__disabled_by_previous_error
35067 : wuffs_base__error__initialize_not_called);
35068 }
35069 if (!a_dst || !a_src) {
35070 self->private_impl.magic = WUFFS_BASE__DISABLED;
35071 return wuffs_base__make_status(wuffs_base__error__bad_argument);
35072 }
35073 if ((self->private_impl.active_coroutine != 0) &&
35074 (self->private_impl.active_coroutine != 3)) {
35075 self->private_impl.magic = WUFFS_BASE__DISABLED;
35076 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35077 }
35078 self->private_impl.active_coroutine = 0;
35079 wuffs_base__status status = wuffs_base__make_status(NULL);
35080
35081 wuffs_base__status v_status = wuffs_base__make_status(NULL);
35082
35083 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
35084 switch (coro_susp_point) {
35085 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35086
35087 if (self->private_impl.f_call_sequence < 4) {
35088 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
35089 status = wuffs_nie__decoder__decode_frame_config(self, NULL, a_src);
35090 if (status.repr) {
35091 goto suspend;
35092 }
35093 } else if (self->private_impl.f_call_sequence == 4) {
35094 } else {
35095 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
35096 goto ok;
35097 }
35098 self->private_impl.f_dst_x = 0;
35099 self->private_impl.f_dst_y = 0;
35100 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
35101 wuffs_base__pixel_buffer__pixel_format(a_dst),
35102 wuffs_base__pixel_buffer__palette(a_dst),
35103 wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
35104 wuffs_base__utility__empty_slice_u8(),
35105 a_blend);
35106 if ( ! wuffs_base__status__is_ok(&v_status)) {
35107 status = v_status;
35108 if (wuffs_base__status__is_error(&status)) {
35109 goto exit;
35110 } else if (wuffs_base__status__is_suspension(&status)) {
35111 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
35112 goto exit;
35113 }
35114 goto ok;
35115 }
35116 while (true) {
35117 v_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src);
35118 if (wuffs_base__status__is_ok(&v_status)) {
35119 goto label__0__break;
35120 } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) {
35121 status = v_status;
35122 if (wuffs_base__status__is_error(&status)) {
35123 goto exit;
35124 } else if (wuffs_base__status__is_suspension(&status)) {
35125 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
35126 goto exit;
35127 }
35128 goto ok;
35129 }
35130 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35131 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
35132 }
35133 label__0__break:;
35134 self->private_impl.f_call_sequence = 255;
35135
35136 ok:
35137 self->private_impl.p_decode_frame[0] = 0;
35138 goto exit;
35139 }
35140
35141 goto suspend;
35142 suspend:
35143 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35144 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
35145
35146 goto exit;
35147 exit:
35148 if (wuffs_base__status__is_error(&status)) {
35149 self->private_impl.magic = WUFFS_BASE__DISABLED;
35150 }
35151 return status;
35152 }
35153
35154 // -------- func nie.decoder.swizzle
35155
35156 static wuffs_base__status
wuffs_nie__decoder__swizzle(wuffs_nie__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src)35157 wuffs_nie__decoder__swizzle(
35158 wuffs_nie__decoder* self,
35159 wuffs_base__pixel_buffer* a_dst,
35160 wuffs_base__io_buffer* a_src) {
35161 wuffs_base__status status = wuffs_base__make_status(NULL);
35162
35163 wuffs_base__pixel_format v_dst_pixfmt = {0};
35164 uint32_t v_dst_bits_per_pixel = 0;
35165 uint64_t v_dst_bytes_per_pixel = 0;
35166 uint64_t v_dst_bytes_per_row = 0;
35167 wuffs_base__table_u8 v_tab = {0};
35168 wuffs_base__slice_u8 v_dst = {0};
35169 uint64_t v_i = 0;
35170 uint64_t v_n = 0;
35171
35172 const uint8_t* iop_a_src = NULL;
35173 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35174 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35175 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35176 if (a_src) {
35177 io0_a_src = a_src->data.ptr;
35178 io1_a_src = io0_a_src + a_src->meta.ri;
35179 iop_a_src = io1_a_src;
35180 io2_a_src = io0_a_src + a_src->meta.wi;
35181 }
35182
35183 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
35184 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
35185 if ((v_dst_bits_per_pixel & 7) != 0) {
35186 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
35187 goto exit;
35188 }
35189 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
35190 v_dst_bytes_per_row = (((uint64_t)(self->private_impl.f_width)) * v_dst_bytes_per_pixel);
35191 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
35192 label__0__continue:;
35193 while (true) {
35194 if (self->private_impl.f_dst_x == self->private_impl.f_width) {
35195 self->private_impl.f_dst_x = 0;
35196 self->private_impl.f_dst_y += 1;
35197 if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
35198 goto label__0__break;
35199 }
35200 }
35201 v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
35202 if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
35203 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
35204 }
35205 v_i = (((uint64_t)(self->private_impl.f_dst_x)) * v_dst_bytes_per_pixel);
35206 if (v_i >= ((uint64_t)(v_dst.len))) {
35207 goto label__0__continue;
35208 }
35209 v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
35210 &self->private_impl.f_swizzler,
35211 wuffs_base__slice_u8__subslice_i(v_dst, v_i),
35212 wuffs_base__pixel_buffer__palette(a_dst),
35213 &iop_a_src,
35214 io2_a_src);
35215 if (v_n == 0) {
35216 status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read);
35217 goto ok;
35218 }
35219 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)((v_n & 4294967295))));
35220 }
35221 label__0__break:;
35222 status = wuffs_base__make_status(NULL);
35223 goto ok;
35224
35225 ok:
35226 goto exit;
35227 exit:
35228 if (a_src) {
35229 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35230 }
35231
35232 return status;
35233 }
35234
35235 // -------- func nie.decoder.frame_dirty_rect
35236
35237 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_nie__decoder__frame_dirty_rect(const wuffs_nie__decoder * self)35238 wuffs_nie__decoder__frame_dirty_rect(
35239 const wuffs_nie__decoder* self) {
35240 if (!self) {
35241 return wuffs_base__utility__empty_rect_ie_u32();
35242 }
35243 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35244 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35245 return wuffs_base__utility__empty_rect_ie_u32();
35246 }
35247
35248 return wuffs_base__utility__make_rect_ie_u32(
35249 0,
35250 0,
35251 self->private_impl.f_width,
35252 self->private_impl.f_height);
35253 }
35254
35255 // -------- func nie.decoder.num_animation_loops
35256
35257 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_nie__decoder__num_animation_loops(const wuffs_nie__decoder * self)35258 wuffs_nie__decoder__num_animation_loops(
35259 const wuffs_nie__decoder* self) {
35260 if (!self) {
35261 return 0;
35262 }
35263 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35264 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35265 return 0;
35266 }
35267
35268 return 0;
35269 }
35270
35271 // -------- func nie.decoder.num_decoded_frame_configs
35272
35273 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frame_configs(const wuffs_nie__decoder * self)35274 wuffs_nie__decoder__num_decoded_frame_configs(
35275 const wuffs_nie__decoder* self) {
35276 if (!self) {
35277 return 0;
35278 }
35279 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35280 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35281 return 0;
35282 }
35283
35284 if (self->private_impl.f_call_sequence > 3) {
35285 return 1;
35286 }
35287 return 0;
35288 }
35289
35290 // -------- func nie.decoder.num_decoded_frames
35291
35292 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_nie__decoder__num_decoded_frames(const wuffs_nie__decoder * self)35293 wuffs_nie__decoder__num_decoded_frames(
35294 const wuffs_nie__decoder* self) {
35295 if (!self) {
35296 return 0;
35297 }
35298 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35299 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35300 return 0;
35301 }
35302
35303 if (self->private_impl.f_call_sequence > 4) {
35304 return 1;
35305 }
35306 return 0;
35307 }
35308
35309 // -------- func nie.decoder.restart_frame
35310
35311 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__restart_frame(wuffs_nie__decoder * self,uint64_t a_index,uint64_t a_io_position)35312 wuffs_nie__decoder__restart_frame(
35313 wuffs_nie__decoder* self,
35314 uint64_t a_index,
35315 uint64_t a_io_position) {
35316 if (!self) {
35317 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35318 }
35319 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35320 return wuffs_base__make_status(
35321 (self->private_impl.magic == WUFFS_BASE__DISABLED)
35322 ? wuffs_base__error__disabled_by_previous_error
35323 : wuffs_base__error__initialize_not_called);
35324 }
35325
35326 if (self->private_impl.f_call_sequence < 3) {
35327 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
35328 }
35329 if ((a_index != 0) || (a_io_position != 16)) {
35330 return wuffs_base__make_status(wuffs_base__error__bad_argument);
35331 }
35332 self->private_impl.f_call_sequence = 3;
35333 return wuffs_base__make_status(NULL);
35334 }
35335
35336 // -------- func nie.decoder.set_report_metadata
35337
35338 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_nie__decoder__set_report_metadata(wuffs_nie__decoder * self,uint32_t a_fourcc,bool a_report)35339 wuffs_nie__decoder__set_report_metadata(
35340 wuffs_nie__decoder* self,
35341 uint32_t a_fourcc,
35342 bool a_report) {
35343 return wuffs_base__make_empty_struct();
35344 }
35345
35346 // -------- func nie.decoder.tell_me_more
35347
35348 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_nie__decoder__tell_me_more(wuffs_nie__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)35349 wuffs_nie__decoder__tell_me_more(
35350 wuffs_nie__decoder* self,
35351 wuffs_base__io_buffer* a_dst,
35352 wuffs_base__more_information* a_minfo,
35353 wuffs_base__io_buffer* a_src) {
35354 if (!self) {
35355 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35356 }
35357 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35358 return wuffs_base__make_status(
35359 (self->private_impl.magic == WUFFS_BASE__DISABLED)
35360 ? wuffs_base__error__disabled_by_previous_error
35361 : wuffs_base__error__initialize_not_called);
35362 }
35363 if (!a_dst || !a_src) {
35364 self->private_impl.magic = WUFFS_BASE__DISABLED;
35365 return wuffs_base__make_status(wuffs_base__error__bad_argument);
35366 }
35367 if ((self->private_impl.active_coroutine != 0) &&
35368 (self->private_impl.active_coroutine != 4)) {
35369 self->private_impl.magic = WUFFS_BASE__DISABLED;
35370 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35371 }
35372 self->private_impl.active_coroutine = 0;
35373 wuffs_base__status status = wuffs_base__make_status(NULL);
35374
35375 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
35376 goto exit;
35377
35378 goto ok;
35379 ok:
35380 goto exit;
35381 exit:
35382 if (wuffs_base__status__is_error(&status)) {
35383 self->private_impl.magic = WUFFS_BASE__DISABLED;
35384 }
35385 return status;
35386 }
35387
35388 // -------- func nie.decoder.workbuf_len
35389
35390 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_nie__decoder__workbuf_len(const wuffs_nie__decoder * self)35391 wuffs_nie__decoder__workbuf_len(
35392 const wuffs_nie__decoder* self) {
35393 if (!self) {
35394 return wuffs_base__utility__empty_range_ii_u64();
35395 }
35396 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35397 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35398 return wuffs_base__utility__empty_range_ii_u64();
35399 }
35400
35401 return wuffs_base__utility__make_range_ii_u64(0, 0);
35402 }
35403
35404 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
35405
35406 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
35407
35408 // ---------------- Status Codes Implementations
35409
35410 const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required";
35411 const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum";
35412 const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method";
35413 const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size";
35414 const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check";
35415 const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary";
35416
35417 // ---------------- Private Consts
35418
35419 #define WUFFS_ZLIB__QUIRKS_BASE 2113790976
35420
35421 #define WUFFS_ZLIB__QUIRKS_COUNT 1
35422
35423 // ---------------- Private Initializer Prototypes
35424
35425 // ---------------- Private Function Prototypes
35426
35427 // ---------------- VTables
35428
35429 const wuffs_base__io_transformer__func_ptrs
35430 wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = {
35431 (wuffs_base__empty_struct(*)(void*,
35432 uint32_t,
35433 bool))(&wuffs_zlib__decoder__set_quirk_enabled),
35434 (wuffs_base__status(*)(void*,
35435 wuffs_base__io_buffer*,
35436 wuffs_base__io_buffer*,
35437 wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io),
35438 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len),
35439 };
35440
35441 // ---------------- Initializer Implementations
35442
35443 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_zlib__decoder__initialize(wuffs_zlib__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)35444 wuffs_zlib__decoder__initialize(
35445 wuffs_zlib__decoder* self,
35446 size_t sizeof_star_self,
35447 uint64_t wuffs_version,
35448 uint32_t options){
35449 if (!self) {
35450 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35451 }
35452 if (sizeof(*self) != sizeof_star_self) {
35453 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
35454 }
35455 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
35456 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
35457 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
35458 }
35459
35460 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
35461 // The whole point of this if-check is to detect an uninitialized *self.
35462 // We disable the warning on GCC. Clang-5.0 does not have this warning.
35463 #if !defined(__clang__) && defined(__GNUC__)
35464 #pragma GCC diagnostic push
35465 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
35466 #endif
35467 if (self->private_impl.magic != 0) {
35468 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
35469 }
35470 #if !defined(__clang__) && defined(__GNUC__)
35471 #pragma GCC diagnostic pop
35472 #endif
35473 } else {
35474 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
35475 memset(self, 0, sizeof(*self));
35476 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
35477 } else {
35478 memset(&(self->private_impl), 0, sizeof(self->private_impl));
35479 }
35480 }
35481
35482 {
35483 wuffs_base__status z = wuffs_adler32__hasher__initialize(
35484 &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
35485 if (z.repr) {
35486 return z;
35487 }
35488 }
35489 {
35490 wuffs_base__status z = wuffs_adler32__hasher__initialize(
35491 &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options);
35492 if (z.repr) {
35493 return z;
35494 }
35495 }
35496 {
35497 wuffs_base__status z = wuffs_deflate__decoder__initialize(
35498 &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
35499 if (z.repr) {
35500 return z;
35501 }
35502 }
35503 self->private_impl.magic = WUFFS_BASE__MAGIC;
35504 self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
35505 wuffs_base__io_transformer__vtable_name;
35506 self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
35507 (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer);
35508 return wuffs_base__make_status(NULL);
35509 }
35510
35511 wuffs_zlib__decoder*
wuffs_zlib__decoder__alloc()35512 wuffs_zlib__decoder__alloc() {
35513 wuffs_zlib__decoder* x =
35514 (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
35515 if (!x) {
35516 return NULL;
35517 }
35518 if (wuffs_zlib__decoder__initialize(
35519 x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
35520 free(x);
35521 return NULL;
35522 }
35523 return x;
35524 }
35525
35526 size_t
sizeof__wuffs_zlib__decoder()35527 sizeof__wuffs_zlib__decoder() {
35528 return sizeof(wuffs_zlib__decoder);
35529 }
35530
35531 // ---------------- Function Implementations
35532
35533 // -------- func zlib.decoder.dictionary_id
35534
35535 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_zlib__decoder__dictionary_id(const wuffs_zlib__decoder * self)35536 wuffs_zlib__decoder__dictionary_id(
35537 const wuffs_zlib__decoder* self) {
35538 if (!self) {
35539 return 0;
35540 }
35541 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35542 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35543 return 0;
35544 }
35545
35546 return self->private_impl.f_dict_id_want;
35547 }
35548
35549 // -------- func zlib.decoder.add_dictionary
35550
35551 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_zlib__decoder__add_dictionary(wuffs_zlib__decoder * self,wuffs_base__slice_u8 a_dict)35552 wuffs_zlib__decoder__add_dictionary(
35553 wuffs_zlib__decoder* self,
35554 wuffs_base__slice_u8 a_dict) {
35555 if (!self) {
35556 return wuffs_base__make_empty_struct();
35557 }
35558 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35559 return wuffs_base__make_empty_struct();
35560 }
35561
35562 if (self->private_impl.f_header_complete) {
35563 self->private_impl.f_bad_call_sequence = true;
35564 } else {
35565 self->private_impl.f_dict_id_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict);
35566 wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict);
35567 }
35568 self->private_impl.f_got_dictionary = true;
35569 return wuffs_base__make_empty_struct();
35570 }
35571
35572 // -------- func zlib.decoder.set_quirk_enabled
35573
35574 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_zlib__decoder__set_quirk_enabled(wuffs_zlib__decoder * self,uint32_t a_quirk,bool a_enabled)35575 wuffs_zlib__decoder__set_quirk_enabled(
35576 wuffs_zlib__decoder* self,
35577 uint32_t a_quirk,
35578 bool a_enabled) {
35579 if (!self) {
35580 return wuffs_base__make_empty_struct();
35581 }
35582 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35583 return wuffs_base__make_empty_struct();
35584 }
35585
35586 if (self->private_impl.f_header_complete) {
35587 self->private_impl.f_bad_call_sequence = true;
35588 } else if (a_quirk == 1) {
35589 self->private_impl.f_ignore_checksum = a_enabled;
35590 } else if (a_quirk >= 2113790976) {
35591 a_quirk -= 2113790976;
35592 if (a_quirk < 1) {
35593 self->private_impl.f_quirks[a_quirk] = a_enabled;
35594 }
35595 }
35596 return wuffs_base__make_empty_struct();
35597 }
35598
35599 // -------- func zlib.decoder.workbuf_len
35600
35601 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_zlib__decoder__workbuf_len(const wuffs_zlib__decoder * self)35602 wuffs_zlib__decoder__workbuf_len(
35603 const wuffs_zlib__decoder* self) {
35604 if (!self) {
35605 return wuffs_base__utility__empty_range_ii_u64();
35606 }
35607 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
35608 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
35609 return wuffs_base__utility__empty_range_ii_u64();
35610 }
35611
35612 return wuffs_base__utility__make_range_ii_u64(1, 1);
35613 }
35614
35615 // -------- func zlib.decoder.transform_io
35616
35617 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_zlib__decoder__transform_io(wuffs_zlib__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)35618 wuffs_zlib__decoder__transform_io(
35619 wuffs_zlib__decoder* self,
35620 wuffs_base__io_buffer* a_dst,
35621 wuffs_base__io_buffer* a_src,
35622 wuffs_base__slice_u8 a_workbuf) {
35623 if (!self) {
35624 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
35625 }
35626 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
35627 return wuffs_base__make_status(
35628 (self->private_impl.magic == WUFFS_BASE__DISABLED)
35629 ? wuffs_base__error__disabled_by_previous_error
35630 : wuffs_base__error__initialize_not_called);
35631 }
35632 if (!a_dst || !a_src) {
35633 self->private_impl.magic = WUFFS_BASE__DISABLED;
35634 return wuffs_base__make_status(wuffs_base__error__bad_argument);
35635 }
35636 if ((self->private_impl.active_coroutine != 0) &&
35637 (self->private_impl.active_coroutine != 1)) {
35638 self->private_impl.magic = WUFFS_BASE__DISABLED;
35639 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
35640 }
35641 self->private_impl.active_coroutine = 0;
35642 wuffs_base__status status = wuffs_base__make_status(NULL);
35643
35644 uint16_t v_x = 0;
35645 uint32_t v_checksum_got = 0;
35646 wuffs_base__status v_status = wuffs_base__make_status(NULL);
35647 uint32_t v_checksum_want = 0;
35648 uint64_t v_mark = 0;
35649
35650 uint8_t* iop_a_dst = NULL;
35651 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35652 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35653 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35654 if (a_dst) {
35655 io0_a_dst = a_dst->data.ptr;
35656 io1_a_dst = io0_a_dst + a_dst->meta.wi;
35657 iop_a_dst = io1_a_dst;
35658 io2_a_dst = io0_a_dst + a_dst->data.len;
35659 if (a_dst->meta.closed) {
35660 io2_a_dst = iop_a_dst;
35661 }
35662 }
35663 const uint8_t* iop_a_src = NULL;
35664 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35665 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35666 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
35667 if (a_src) {
35668 io0_a_src = a_src->data.ptr;
35669 io1_a_src = io0_a_src + a_src->meta.ri;
35670 iop_a_src = io1_a_src;
35671 io2_a_src = io0_a_src + a_src->meta.wi;
35672 }
35673
35674 uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
35675 if (coro_susp_point) {
35676 v_checksum_got = self->private_data.s_transform_io[0].v_checksum_got;
35677 }
35678 switch (coro_susp_point) {
35679 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
35680
35681 if (self->private_impl.f_bad_call_sequence) {
35682 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
35683 goto exit;
35684 } else if (self->private_impl.f_quirks[0]) {
35685 } else if ( ! self->private_impl.f_want_dictionary) {
35686 {
35687 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
35688 uint16_t t_0;
35689 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
35690 t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
35691 iop_a_src += 2;
35692 } else {
35693 self->private_data.s_transform_io[0].scratch = 0;
35694 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
35695 while (true) {
35696 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35697 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35698 goto suspend;
35699 }
35700 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35701 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
35702 *scratch >>= 8;
35703 *scratch <<= 8;
35704 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
35705 if (num_bits_0 == 8) {
35706 t_0 = ((uint16_t)(*scratch >> 48));
35707 break;
35708 }
35709 num_bits_0 += 8;
35710 *scratch |= ((uint64_t)(num_bits_0));
35711 }
35712 }
35713 v_x = t_0;
35714 }
35715 if (((v_x >> 8) & 15) != 8) {
35716 status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method);
35717 goto exit;
35718 }
35719 if ((v_x >> 12) > 7) {
35720 status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size);
35721 goto exit;
35722 }
35723 if ((v_x % 31) != 0) {
35724 status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check);
35725 goto exit;
35726 }
35727 self->private_impl.f_want_dictionary = ((v_x & 32) != 0);
35728 if (self->private_impl.f_want_dictionary) {
35729 self->private_impl.f_dict_id_got = 1;
35730 {
35731 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
35732 uint32_t t_1;
35733 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
35734 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
35735 iop_a_src += 4;
35736 } else {
35737 self->private_data.s_transform_io[0].scratch = 0;
35738 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
35739 while (true) {
35740 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35741 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35742 goto suspend;
35743 }
35744 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35745 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
35746 *scratch >>= 8;
35747 *scratch <<= 8;
35748 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
35749 if (num_bits_1 == 24) {
35750 t_1 = ((uint32_t)(*scratch >> 32));
35751 break;
35752 }
35753 num_bits_1 += 8;
35754 *scratch |= ((uint64_t)(num_bits_1));
35755 }
35756 }
35757 self->private_impl.f_dict_id_want = t_1;
35758 }
35759 status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
35760 goto ok;
35761 } else if (self->private_impl.f_got_dictionary) {
35762 status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
35763 goto exit;
35764 }
35765 } else if (self->private_impl.f_dict_id_got != self->private_impl.f_dict_id_want) {
35766 if (self->private_impl.f_got_dictionary) {
35767 status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
35768 goto exit;
35769 }
35770 status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
35771 goto ok;
35772 }
35773 self->private_impl.f_header_complete = true;
35774 while (true) {
35775 v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
35776 {
35777 if (a_dst) {
35778 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35779 }
35780 if (a_src) {
35781 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35782 }
35783 wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
35784 v_status = t_2;
35785 if (a_dst) {
35786 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
35787 }
35788 if (a_src) {
35789 iop_a_src = a_src->data.ptr + a_src->meta.ri;
35790 }
35791 }
35792 if ( ! self->private_impl.f_ignore_checksum && ! self->private_impl.f_quirks[0]) {
35793 v_checksum_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
35794 }
35795 if (wuffs_base__status__is_ok(&v_status)) {
35796 goto label__0__break;
35797 }
35798 status = v_status;
35799 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
35800 }
35801 label__0__break:;
35802 if ( ! self->private_impl.f_quirks[0]) {
35803 {
35804 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
35805 uint32_t t_3;
35806 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
35807 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
35808 iop_a_src += 4;
35809 } else {
35810 self->private_data.s_transform_io[0].scratch = 0;
35811 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
35812 while (true) {
35813 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
35814 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
35815 goto suspend;
35816 }
35817 uint64_t* scratch = &self->private_data.s_transform_io[0].scratch;
35818 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
35819 *scratch >>= 8;
35820 *scratch <<= 8;
35821 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
35822 if (num_bits_3 == 24) {
35823 t_3 = ((uint32_t)(*scratch >> 32));
35824 break;
35825 }
35826 num_bits_3 += 8;
35827 *scratch |= ((uint64_t)(num_bits_3));
35828 }
35829 }
35830 v_checksum_want = t_3;
35831 }
35832 if ( ! self->private_impl.f_ignore_checksum && (v_checksum_got != v_checksum_want)) {
35833 status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum);
35834 goto exit;
35835 }
35836 }
35837
35838 ok:
35839 self->private_impl.p_transform_io[0] = 0;
35840 goto exit;
35841 }
35842
35843 goto suspend;
35844 suspend:
35845 self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
35846 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
35847 self->private_data.s_transform_io[0].v_checksum_got = v_checksum_got;
35848
35849 goto exit;
35850 exit:
35851 if (a_dst) {
35852 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
35853 }
35854 if (a_src) {
35855 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
35856 }
35857
35858 if (wuffs_base__status__is_error(&status)) {
35859 self->private_impl.magic = WUFFS_BASE__DISABLED;
35860 }
35861 return status;
35862 }
35863
35864 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
35865
35866 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
35867
35868 // ---------------- Status Codes Implementations
35869
35870 const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number";
35871 const char wuffs_png__error__bad_checksum[] = "#png: bad checksum";
35872 const char wuffs_png__error__bad_chunk[] = "#png: bad chunk";
35873 const char wuffs_png__error__bad_filter[] = "#png: bad filter";
35874 const char wuffs_png__error__bad_header[] = "#png: bad header";
35875 const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)";
35876 const char wuffs_png__error__missing_palette[] = "#png: missing palette";
35877 const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method";
35878 const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file";
35879 const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O";
35880 const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type";
35881 const char wuffs_png__error__internal_error_inconsistent_frame_bounds[] = "#png: internal error: inconsistent frame bounds";
35882 const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length";
35883 const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input";
35884
35885 // ---------------- Private Consts
35886
35887 #define WUFFS_PNG__ANCILLARY_BIT 32
35888
35889 static const uint8_t
35890 WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = {
35891 {
35892 0, 0, 0, 0, 0, 0,
35893 }, {
35894 3, 7, 0, 3, 7, 0,
35895 }, {
35896 3, 3, 4, 3, 7, 0,
35897 }, {
35898 2, 3, 0, 3, 3, 4,
35899 }, {
35900 2, 1, 2, 2, 3, 0,
35901 }, {
35902 1, 1, 0, 2, 1, 2,
35903 }, {
35904 1, 0, 1, 1, 1, 0,
35905 }, {
35906 0, 0, 0, 1, 0, 1,
35907 },
35908 };
35909
35910 static const uint8_t
35911 WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35912 0, 255, 85, 0, 17, 0, 0, 0,
35913 };
35914
35915 static const uint8_t
35916 WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35917 0, 8, 4, 0, 2, 0, 0, 0,
35918 };
35919
35920 static const uint8_t
35921 WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
35922 1, 0, 3, 1, 2, 0, 4, 0,
35923 };
35924
35925 static const uint16_t
35926 WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
35927 0, 0, 0, 0, 0, 0, 0, 0,
35928 0, 0, 0, 0, 0, 0, 0, 0,
35929 0, 0, 0, 0, 0, 0, 0, 0,
35930 0, 0, 0, 0, 0, 0, 0, 0,
35931 32, 33, 34, 35, 36, 37, 38, 39,
35932 40, 41, 42, 43, 44, 45, 46, 47,
35933 48, 49, 50, 51, 52, 53, 54, 55,
35934 56, 57, 58, 59, 60, 61, 62, 63,
35935 64, 65, 66, 67, 68, 69, 70, 71,
35936 72, 73, 74, 75, 76, 77, 78, 79,
35937 80, 81, 82, 83, 84, 85, 86, 87,
35938 88, 89, 90, 91, 92, 93, 94, 95,
35939 96, 97, 98, 99, 100, 101, 102, 103,
35940 104, 105, 106, 107, 108, 109, 110, 111,
35941 112, 113, 114, 115, 116, 117, 118, 119,
35942 120, 121, 122, 123, 124, 125, 126, 0,
35943 0, 0, 0, 0, 0, 0, 0, 0,
35944 0, 0, 0, 0, 0, 0, 0, 0,
35945 0, 0, 0, 0, 0, 0, 0, 0,
35946 0, 0, 0, 0, 0, 0, 0, 0,
35947 0, 41410, 41666, 41922, 42178, 42434, 42690, 42946,
35948 43202, 43458, 43714, 43970, 44226, 44482, 44738, 44994,
35949 45250, 45506, 45762, 46018, 46274, 46530, 46786, 47042,
35950 47298, 47554, 47810, 48066, 48322, 48578, 48834, 49090,
35951 32963, 33219, 33475, 33731, 33987, 34243, 34499, 34755,
35952 35011, 35267, 35523, 35779, 36035, 36291, 36547, 36803,
35953 37059, 37315, 37571, 37827, 38083, 38339, 38595, 38851,
35954 39107, 39363, 39619, 39875, 40131, 40387, 40643, 40899,
35955 41155, 41411, 41667, 41923, 42179, 42435, 42691, 42947,
35956 43203, 43459, 43715, 43971, 44227, 44483, 44739, 44995,
35957 45251, 45507, 45763, 46019, 46275, 46531, 46787, 47043,
35958 47299, 47555, 47811, 48067, 48323, 48579, 48835, 49091,
35959 };
35960
35961 // ---------------- Private Initializer Prototypes
35962
35963 // ---------------- Private Function Prototypes
35964
35965 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35966 static wuffs_base__empty_struct
35967 wuffs_png__decoder__filter_1_distance_4_arm_neon(
35968 wuffs_png__decoder* self,
35969 wuffs_base__slice_u8 a_curr);
35970 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35971
35972 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35973 static wuffs_base__empty_struct
35974 wuffs_png__decoder__filter_3_distance_4_arm_neon(
35975 wuffs_png__decoder* self,
35976 wuffs_base__slice_u8 a_curr,
35977 wuffs_base__slice_u8 a_prev);
35978 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35979
35980 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35981 static wuffs_base__empty_struct
35982 wuffs_png__decoder__filter_4_distance_3_arm_neon(
35983 wuffs_png__decoder* self,
35984 wuffs_base__slice_u8 a_curr,
35985 wuffs_base__slice_u8 a_prev);
35986 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35987
35988 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35989 static wuffs_base__empty_struct
35990 wuffs_png__decoder__filter_4_distance_4_arm_neon(
35991 wuffs_png__decoder* self,
35992 wuffs_base__slice_u8 a_curr,
35993 wuffs_base__slice_u8 a_prev);
35994 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
35995
35996 static wuffs_base__empty_struct
35997 wuffs_png__decoder__filter_1(
35998 wuffs_png__decoder* self,
35999 wuffs_base__slice_u8 a_curr);
36000
36001 static wuffs_base__empty_struct
36002 wuffs_png__decoder__filter_1__choosy_default(
36003 wuffs_png__decoder* self,
36004 wuffs_base__slice_u8 a_curr);
36005
36006 static wuffs_base__empty_struct
36007 wuffs_png__decoder__filter_1_distance_3_fallback(
36008 wuffs_png__decoder* self,
36009 wuffs_base__slice_u8 a_curr);
36010
36011 static wuffs_base__empty_struct
36012 wuffs_png__decoder__filter_1_distance_4_fallback(
36013 wuffs_png__decoder* self,
36014 wuffs_base__slice_u8 a_curr);
36015
36016 static wuffs_base__empty_struct
36017 wuffs_png__decoder__filter_2(
36018 wuffs_png__decoder* self,
36019 wuffs_base__slice_u8 a_curr,
36020 wuffs_base__slice_u8 a_prev);
36021
36022 static wuffs_base__empty_struct
36023 wuffs_png__decoder__filter_3(
36024 wuffs_png__decoder* self,
36025 wuffs_base__slice_u8 a_curr,
36026 wuffs_base__slice_u8 a_prev);
36027
36028 static wuffs_base__empty_struct
36029 wuffs_png__decoder__filter_3__choosy_default(
36030 wuffs_png__decoder* self,
36031 wuffs_base__slice_u8 a_curr,
36032 wuffs_base__slice_u8 a_prev);
36033
36034 static wuffs_base__empty_struct
36035 wuffs_png__decoder__filter_3_distance_3_fallback(
36036 wuffs_png__decoder* self,
36037 wuffs_base__slice_u8 a_curr,
36038 wuffs_base__slice_u8 a_prev);
36039
36040 static wuffs_base__empty_struct
36041 wuffs_png__decoder__filter_3_distance_4_fallback(
36042 wuffs_png__decoder* self,
36043 wuffs_base__slice_u8 a_curr,
36044 wuffs_base__slice_u8 a_prev);
36045
36046 static wuffs_base__empty_struct
36047 wuffs_png__decoder__filter_4(
36048 wuffs_png__decoder* self,
36049 wuffs_base__slice_u8 a_curr,
36050 wuffs_base__slice_u8 a_prev);
36051
36052 static wuffs_base__empty_struct
36053 wuffs_png__decoder__filter_4__choosy_default(
36054 wuffs_png__decoder* self,
36055 wuffs_base__slice_u8 a_curr,
36056 wuffs_base__slice_u8 a_prev);
36057
36058 static wuffs_base__empty_struct
36059 wuffs_png__decoder__filter_4_distance_3_fallback(
36060 wuffs_png__decoder* self,
36061 wuffs_base__slice_u8 a_curr,
36062 wuffs_base__slice_u8 a_prev);
36063
36064 static wuffs_base__empty_struct
36065 wuffs_png__decoder__filter_4_distance_4_fallback(
36066 wuffs_png__decoder* self,
36067 wuffs_base__slice_u8 a_curr,
36068 wuffs_base__slice_u8 a_prev);
36069
36070 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36071 static wuffs_base__empty_struct
36072 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
36073 wuffs_png__decoder* self,
36074 wuffs_base__slice_u8 a_curr);
36075 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36076
36077 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36078 static wuffs_base__empty_struct
36079 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
36080 wuffs_png__decoder* self,
36081 wuffs_base__slice_u8 a_curr,
36082 wuffs_base__slice_u8 a_prev);
36083 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36084
36085 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36086 static wuffs_base__empty_struct
36087 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
36088 wuffs_png__decoder* self,
36089 wuffs_base__slice_u8 a_curr,
36090 wuffs_base__slice_u8 a_prev);
36091 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36092
36093 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36094 static wuffs_base__empty_struct
36095 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
36096 wuffs_png__decoder* self,
36097 wuffs_base__slice_u8 a_curr,
36098 wuffs_base__slice_u8 a_prev);
36099 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
36100
36101 static wuffs_base__status
36102 wuffs_png__decoder__decode_ihdr(
36103 wuffs_png__decoder* self,
36104 wuffs_base__io_buffer* a_src);
36105
36106 static wuffs_base__empty_struct
36107 wuffs_png__decoder__assign_filter_distance(
36108 wuffs_png__decoder* self);
36109
36110 static uint64_t
36111 wuffs_png__decoder__calculate_bytes_per_row(
36112 const wuffs_png__decoder* self,
36113 uint32_t a_width);
36114
36115 static wuffs_base__empty_struct
36116 wuffs_png__decoder__choose_filter_implementations(
36117 wuffs_png__decoder* self);
36118
36119 static wuffs_base__status
36120 wuffs_png__decoder__decode_other_chunk(
36121 wuffs_png__decoder* self,
36122 wuffs_base__io_buffer* a_src);
36123
36124 static wuffs_base__status
36125 wuffs_png__decoder__decode_actl(
36126 wuffs_png__decoder* self,
36127 wuffs_base__io_buffer* a_src);
36128
36129 static wuffs_base__status
36130 wuffs_png__decoder__decode_chrm(
36131 wuffs_png__decoder* self,
36132 wuffs_base__io_buffer* a_src);
36133
36134 static wuffs_base__status
36135 wuffs_png__decoder__decode_exif(
36136 wuffs_png__decoder* self,
36137 wuffs_base__io_buffer* a_src);
36138
36139 static wuffs_base__status
36140 wuffs_png__decoder__decode_fctl(
36141 wuffs_png__decoder* self,
36142 wuffs_base__io_buffer* a_src);
36143
36144 static wuffs_base__status
36145 wuffs_png__decoder__decode_gama(
36146 wuffs_png__decoder* self,
36147 wuffs_base__io_buffer* a_src);
36148
36149 static wuffs_base__status
36150 wuffs_png__decoder__decode_iccp(
36151 wuffs_png__decoder* self,
36152 wuffs_base__io_buffer* a_src);
36153
36154 static wuffs_base__status
36155 wuffs_png__decoder__decode_plte(
36156 wuffs_png__decoder* self,
36157 wuffs_base__io_buffer* a_src);
36158
36159 static wuffs_base__status
36160 wuffs_png__decoder__decode_srgb(
36161 wuffs_png__decoder* self,
36162 wuffs_base__io_buffer* a_src);
36163
36164 static wuffs_base__status
36165 wuffs_png__decoder__decode_trns(
36166 wuffs_png__decoder* self,
36167 wuffs_base__io_buffer* a_src);
36168
36169 static wuffs_base__status
36170 wuffs_png__decoder__skip_frame(
36171 wuffs_png__decoder* self,
36172 wuffs_base__io_buffer* a_src);
36173
36174 static wuffs_base__status
36175 wuffs_png__decoder__decode_pass(
36176 wuffs_png__decoder* self,
36177 wuffs_base__io_buffer* a_src,
36178 wuffs_base__slice_u8 a_workbuf);
36179
36180 static wuffs_base__status
36181 wuffs_png__decoder__filter_and_swizzle(
36182 wuffs_png__decoder* self,
36183 wuffs_base__pixel_buffer* a_dst,
36184 wuffs_base__slice_u8 a_workbuf);
36185
36186 static wuffs_base__status
36187 wuffs_png__decoder__filter_and_swizzle__choosy_default(
36188 wuffs_png__decoder* self,
36189 wuffs_base__pixel_buffer* a_dst,
36190 wuffs_base__slice_u8 a_workbuf);
36191
36192 static wuffs_base__status
36193 wuffs_png__decoder__filter_and_swizzle_tricky(
36194 wuffs_png__decoder* self,
36195 wuffs_base__pixel_buffer* a_dst,
36196 wuffs_base__slice_u8 a_workbuf);
36197
36198 // ---------------- VTables
36199
36200 const wuffs_base__image_decoder__func_ptrs
36201 wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = {
36202 (wuffs_base__status(*)(void*,
36203 wuffs_base__pixel_buffer*,
36204 wuffs_base__io_buffer*,
36205 wuffs_base__pixel_blend,
36206 wuffs_base__slice_u8,
36207 wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame),
36208 (wuffs_base__status(*)(void*,
36209 wuffs_base__frame_config*,
36210 wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config),
36211 (wuffs_base__status(*)(void*,
36212 wuffs_base__image_config*,
36213 wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config),
36214 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect),
36215 (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops),
36216 (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs),
36217 (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames),
36218 (wuffs_base__status(*)(void*,
36219 uint64_t,
36220 uint64_t))(&wuffs_png__decoder__restart_frame),
36221 (wuffs_base__empty_struct(*)(void*,
36222 uint32_t,
36223 bool))(&wuffs_png__decoder__set_quirk_enabled),
36224 (wuffs_base__empty_struct(*)(void*,
36225 uint32_t,
36226 bool))(&wuffs_png__decoder__set_report_metadata),
36227 (wuffs_base__status(*)(void*,
36228 wuffs_base__io_buffer*,
36229 wuffs_base__more_information*,
36230 wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more),
36231 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len),
36232 };
36233
36234 // ---------------- Initializer Implementations
36235
36236 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_png__decoder__initialize(wuffs_png__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)36237 wuffs_png__decoder__initialize(
36238 wuffs_png__decoder* self,
36239 size_t sizeof_star_self,
36240 uint64_t wuffs_version,
36241 uint32_t options){
36242 if (!self) {
36243 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
36244 }
36245 if (sizeof(*self) != sizeof_star_self) {
36246 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
36247 }
36248 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
36249 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
36250 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
36251 }
36252
36253 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
36254 // The whole point of this if-check is to detect an uninitialized *self.
36255 // We disable the warning on GCC. Clang-5.0 does not have this warning.
36256 #if !defined(__clang__) && defined(__GNUC__)
36257 #pragma GCC diagnostic push
36258 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
36259 #endif
36260 if (self->private_impl.magic != 0) {
36261 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
36262 }
36263 #if !defined(__clang__) && defined(__GNUC__)
36264 #pragma GCC diagnostic pop
36265 #endif
36266 } else {
36267 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
36268 memset(self, 0, sizeof(*self));
36269 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
36270 } else {
36271 memset(&(self->private_impl), 0, sizeof(self->private_impl));
36272 }
36273 }
36274
36275 self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default;
36276 self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default;
36277 self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default;
36278 self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default;
36279
36280 {
36281 wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
36282 &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
36283 if (z.repr) {
36284 return z;
36285 }
36286 }
36287 {
36288 wuffs_base__status z = wuffs_zlib__decoder__initialize(
36289 &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options);
36290 if (z.repr) {
36291 return z;
36292 }
36293 }
36294 self->private_impl.magic = WUFFS_BASE__MAGIC;
36295 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
36296 wuffs_base__image_decoder__vtable_name;
36297 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
36298 (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder);
36299 return wuffs_base__make_status(NULL);
36300 }
36301
36302 wuffs_png__decoder*
wuffs_png__decoder__alloc()36303 wuffs_png__decoder__alloc() {
36304 wuffs_png__decoder* x =
36305 (wuffs_png__decoder*)(calloc(sizeof(wuffs_png__decoder), 1));
36306 if (!x) {
36307 return NULL;
36308 }
36309 if (wuffs_png__decoder__initialize(
36310 x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
36311 free(x);
36312 return NULL;
36313 }
36314 return x;
36315 }
36316
36317 size_t
sizeof__wuffs_png__decoder()36318 sizeof__wuffs_png__decoder() {
36319 return sizeof(wuffs_png__decoder);
36320 }
36321
36322 // ---------------- Function Implementations
36323
36324 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36325 // -------- func png.decoder.filter_1_distance_4_arm_neon
36326
36327 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36328 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36329 wuffs_png__decoder__filter_1_distance_4_arm_neon(
36330 wuffs_png__decoder* self,
36331 wuffs_base__slice_u8 a_curr) {
36332 wuffs_base__slice_u8 v_curr = {0};
36333 uint8x8_t v_fa = {0};
36334 uint8x8_t v_fx = {0};
36335
36336 {
36337 wuffs_base__slice_u8 i_slice_curr = a_curr;
36338 v_curr.ptr = i_slice_curr.ptr;
36339 v_curr.len = 4;
36340 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36341 while (v_curr.ptr < i_end0_curr) {
36342 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36343 v_fx = vadd_u8(v_fx, v_fa);
36344 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36345 v_fa = v_fx;
36346 v_curr.ptr += 4;
36347 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36348 v_fx = vadd_u8(v_fx, v_fa);
36349 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36350 v_fa = v_fx;
36351 v_curr.ptr += 4;
36352 }
36353 v_curr.len = 4;
36354 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36355 while (v_curr.ptr < i_end1_curr) {
36356 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36357 v_fx = vadd_u8(v_fx, v_fa);
36358 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36359 v_fa = v_fx;
36360 v_curr.ptr += 4;
36361 }
36362 v_curr.len = 0;
36363 }
36364 return wuffs_base__make_empty_struct();
36365 }
36366 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36367 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36368
36369 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36370 // -------- func png.decoder.filter_3_distance_4_arm_neon
36371
36372 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36373 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36374 wuffs_png__decoder__filter_3_distance_4_arm_neon(
36375 wuffs_png__decoder* self,
36376 wuffs_base__slice_u8 a_curr,
36377 wuffs_base__slice_u8 a_prev) {
36378 wuffs_base__slice_u8 v_curr = {0};
36379 wuffs_base__slice_u8 v_prev = {0};
36380 uint8x8_t v_fa = {0};
36381 uint8x8_t v_fb = {0};
36382 uint8x8_t v_fx = {0};
36383
36384 if (((uint64_t)(a_prev.len)) == 0) {
36385 {
36386 wuffs_base__slice_u8 i_slice_curr = a_curr;
36387 v_curr.ptr = i_slice_curr.ptr;
36388 v_curr.len = 4;
36389 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36390 while (v_curr.ptr < i_end0_curr) {
36391 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36392 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36393 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36394 v_fa = v_fx;
36395 v_curr.ptr += 4;
36396 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36397 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36398 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36399 v_fa = v_fx;
36400 v_curr.ptr += 4;
36401 }
36402 v_curr.len = 4;
36403 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36404 while (v_curr.ptr < i_end1_curr) {
36405 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36406 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36407 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36408 v_fa = v_fx;
36409 v_curr.ptr += 4;
36410 }
36411 v_curr.len = 0;
36412 }
36413 } else {
36414 {
36415 wuffs_base__slice_u8 i_slice_curr = a_curr;
36416 v_curr.ptr = i_slice_curr.ptr;
36417 wuffs_base__slice_u8 i_slice_prev = a_prev;
36418 v_prev.ptr = i_slice_prev.ptr;
36419 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36420 v_curr.len = 4;
36421 v_prev.len = 4;
36422 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36423 while (v_curr.ptr < i_end0_curr) {
36424 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36425 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36426 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36427 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36428 v_fa = v_fx;
36429 v_curr.ptr += 4;
36430 v_prev.ptr += 4;
36431 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36432 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36433 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36434 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36435 v_fa = v_fx;
36436 v_curr.ptr += 4;
36437 v_prev.ptr += 4;
36438 }
36439 v_curr.len = 4;
36440 v_prev.len = 4;
36441 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36442 while (v_curr.ptr < i_end1_curr) {
36443 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36444 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36445 v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
36446 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36447 v_fa = v_fx;
36448 v_curr.ptr += 4;
36449 v_prev.ptr += 4;
36450 }
36451 v_curr.len = 0;
36452 v_prev.len = 0;
36453 }
36454 }
36455 return wuffs_base__make_empty_struct();
36456 }
36457 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36458 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36459
36460 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36461 // -------- func png.decoder.filter_4_distance_3_arm_neon
36462
36463 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36464 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_3_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36465 wuffs_png__decoder__filter_4_distance_3_arm_neon(
36466 wuffs_png__decoder* self,
36467 wuffs_base__slice_u8 a_curr,
36468 wuffs_base__slice_u8 a_prev) {
36469 wuffs_base__slice_u8 v_curr = {0};
36470 wuffs_base__slice_u8 v_prev = {0};
36471 uint8x8_t v_fa = {0};
36472 uint8x8_t v_fb = {0};
36473 uint8x8_t v_fc = {0};
36474 uint8x8_t v_fx = {0};
36475 uint16x8_t v_fafb = {0};
36476 uint16x8_t v_fcfc = {0};
36477 uint16x8_t v_pa = {0};
36478 uint16x8_t v_pb = {0};
36479 uint16x8_t v_pc = {0};
36480 uint16x8_t v_cmpab = {0};
36481 uint16x8_t v_cmpac = {0};
36482 uint8x8_t v_picka = {0};
36483 uint8x8_t v_pickb = {0};
36484
36485 {
36486 wuffs_base__slice_u8 i_slice_curr = a_curr;
36487 v_curr.ptr = i_slice_curr.ptr;
36488 wuffs_base__slice_u8 i_slice_prev = a_prev;
36489 v_prev.ptr = i_slice_prev.ptr;
36490 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36491 v_curr.len = 4;
36492 v_prev.len = 4;
36493 uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6);
36494 while (v_curr.ptr < i_end0_curr) {
36495 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36496 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36497 v_fafb = vaddl_u8(v_fa, v_fb);
36498 v_fcfc = vaddl_u8(v_fc, v_fc);
36499 v_pa = vabdl_u8(v_fb, v_fc);
36500 v_pb = vabdl_u8(v_fa, v_fc);
36501 v_pc = vabdq_u16(v_fafb, v_fcfc);
36502 v_cmpab = vcleq_u16(v_pa, v_pb);
36503 v_cmpac = vcleq_u16(v_pa, v_pc);
36504 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36505 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36506 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36507 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36508 v_fc = v_fb;
36509 v_fa = v_fx;
36510 v_curr.ptr += 3;
36511 v_prev.ptr += 3;
36512 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36513 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36514 v_fafb = vaddl_u8(v_fa, v_fb);
36515 v_fcfc = vaddl_u8(v_fc, v_fc);
36516 v_pa = vabdl_u8(v_fb, v_fc);
36517 v_pb = vabdl_u8(v_fa, v_fc);
36518 v_pc = vabdq_u16(v_fafb, v_fcfc);
36519 v_cmpab = vcleq_u16(v_pa, v_pb);
36520 v_cmpac = vcleq_u16(v_pa, v_pc);
36521 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36522 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36523 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36524 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36525 v_fc = v_fb;
36526 v_fa = v_fx;
36527 v_curr.ptr += 3;
36528 v_prev.ptr += 3;
36529 }
36530 v_curr.len = 4;
36531 v_prev.len = 4;
36532 uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3);
36533 while (v_curr.ptr < i_end1_curr) {
36534 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36535 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36536 v_fafb = vaddl_u8(v_fa, v_fb);
36537 v_fcfc = vaddl_u8(v_fc, v_fc);
36538 v_pa = vabdl_u8(v_fb, v_fc);
36539 v_pb = vabdl_u8(v_fa, v_fc);
36540 v_pc = vabdq_u16(v_fafb, v_fcfc);
36541 v_cmpab = vcleq_u16(v_pa, v_pb);
36542 v_cmpac = vcleq_u16(v_pa, v_pc);
36543 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36544 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36545 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36546 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36547 v_fc = v_fb;
36548 v_fa = v_fx;
36549 v_curr.ptr += 3;
36550 v_prev.ptr += 3;
36551 }
36552 v_curr.len = 3;
36553 v_prev.len = 3;
36554 uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36555 while (v_curr.ptr < i_end2_curr) {
36556 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
36557 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
36558 v_fafb = vaddl_u8(v_fa, v_fb);
36559 v_fcfc = vaddl_u8(v_fc, v_fc);
36560 v_pa = vabdl_u8(v_fb, v_fc);
36561 v_pb = vabdl_u8(v_fa, v_fc);
36562 v_pc = vabdq_u16(v_fafb, v_fcfc);
36563 v_cmpab = vcleq_u16(v_pa, v_pb);
36564 v_cmpac = vcleq_u16(v_pa, v_pc);
36565 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36566 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36567 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36568 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36569 v_curr.ptr += 3;
36570 v_prev.ptr += 3;
36571 }
36572 v_curr.len = 0;
36573 v_prev.len = 0;
36574 }
36575 return wuffs_base__make_empty_struct();
36576 }
36577 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36578 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36579
36580 // ‼ WUFFS MULTI-FILE SECTION +arm_neon
36581 // -------- func png.decoder.filter_4_distance_4_arm_neon
36582
36583 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36584 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_4_arm_neon(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36585 wuffs_png__decoder__filter_4_distance_4_arm_neon(
36586 wuffs_png__decoder* self,
36587 wuffs_base__slice_u8 a_curr,
36588 wuffs_base__slice_u8 a_prev) {
36589 wuffs_base__slice_u8 v_curr = {0};
36590 wuffs_base__slice_u8 v_prev = {0};
36591 uint8x8_t v_fa = {0};
36592 uint8x8_t v_fb = {0};
36593 uint8x8_t v_fc = {0};
36594 uint8x8_t v_fx = {0};
36595 uint16x8_t v_fafb = {0};
36596 uint16x8_t v_fcfc = {0};
36597 uint16x8_t v_pa = {0};
36598 uint16x8_t v_pb = {0};
36599 uint16x8_t v_pc = {0};
36600 uint16x8_t v_cmpab = {0};
36601 uint16x8_t v_cmpac = {0};
36602 uint8x8_t v_picka = {0};
36603 uint8x8_t v_pickb = {0};
36604
36605 {
36606 wuffs_base__slice_u8 i_slice_curr = a_curr;
36607 v_curr.ptr = i_slice_curr.ptr;
36608 wuffs_base__slice_u8 i_slice_prev = a_prev;
36609 v_prev.ptr = i_slice_prev.ptr;
36610 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36611 v_curr.len = 4;
36612 v_prev.len = 4;
36613 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
36614 while (v_curr.ptr < i_end0_curr) {
36615 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36616 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36617 v_fafb = vaddl_u8(v_fa, v_fb);
36618 v_fcfc = vaddl_u8(v_fc, v_fc);
36619 v_pa = vabdl_u8(v_fb, v_fc);
36620 v_pb = vabdl_u8(v_fa, v_fc);
36621 v_pc = vabdq_u16(v_fafb, v_fcfc);
36622 v_cmpab = vcleq_u16(v_pa, v_pb);
36623 v_cmpac = vcleq_u16(v_pa, v_pc);
36624 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36625 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36626 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36627 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36628 v_fc = v_fb;
36629 v_fa = v_fx;
36630 v_curr.ptr += 4;
36631 v_prev.ptr += 4;
36632 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36633 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36634 v_fafb = vaddl_u8(v_fa, v_fb);
36635 v_fcfc = vaddl_u8(v_fc, v_fc);
36636 v_pa = vabdl_u8(v_fb, v_fc);
36637 v_pb = vabdl_u8(v_fa, v_fc);
36638 v_pc = vabdq_u16(v_fafb, v_fcfc);
36639 v_cmpab = vcleq_u16(v_pa, v_pb);
36640 v_cmpac = vcleq_u16(v_pa, v_pc);
36641 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36642 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36643 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36644 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36645 v_fc = v_fb;
36646 v_fa = v_fx;
36647 v_curr.ptr += 4;
36648 v_prev.ptr += 4;
36649 }
36650 v_curr.len = 4;
36651 v_prev.len = 4;
36652 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36653 while (v_curr.ptr < i_end1_curr) {
36654 v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
36655 v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
36656 v_fafb = vaddl_u8(v_fa, v_fb);
36657 v_fcfc = vaddl_u8(v_fc, v_fc);
36658 v_pa = vabdl_u8(v_fb, v_fc);
36659 v_pb = vabdl_u8(v_fa, v_fc);
36660 v_pc = vabdq_u16(v_fafb, v_fcfc);
36661 v_cmpab = vcleq_u16(v_pa, v_pb);
36662 v_cmpac = vcleq_u16(v_pa, v_pc);
36663 v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
36664 v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
36665 v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
36666 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0));
36667 v_fc = v_fb;
36668 v_fa = v_fx;
36669 v_curr.ptr += 4;
36670 v_prev.ptr += 4;
36671 }
36672 v_curr.len = 0;
36673 v_prev.len = 0;
36674 }
36675 return wuffs_base__make_empty_struct();
36676 }
36677 #endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
36678 // ‼ WUFFS MULTI-FILE SECTION -arm_neon
36679
36680 // -------- func png.decoder.filter_1
36681
36682 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36683 wuffs_png__decoder__filter_1(
36684 wuffs_png__decoder* self,
36685 wuffs_base__slice_u8 a_curr) {
36686 return (*self->private_impl.choosy_filter_1)(self, a_curr);
36687 }
36688
36689 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36690 wuffs_png__decoder__filter_1__choosy_default(
36691 wuffs_png__decoder* self,
36692 wuffs_base__slice_u8 a_curr) {
36693 uint64_t v_filter_distance = 0;
36694 uint8_t v_fa = 0;
36695 uint64_t v_i_start = 0;
36696 uint64_t v_i = 0;
36697
36698 v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
36699 v_i_start = 0;
36700 while (v_i_start < v_filter_distance) {
36701 v_fa = 0;
36702 v_i = v_i_start;
36703 while (v_i < ((uint64_t)(a_curr.len))) {
36704 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa));
36705 v_fa = a_curr.ptr[v_i];
36706 v_i += v_filter_distance;
36707 }
36708 v_i_start += 1;
36709 }
36710 return wuffs_base__make_empty_struct();
36711 }
36712
36713 // -------- func png.decoder.filter_1_distance_3_fallback
36714
36715 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36716 wuffs_png__decoder__filter_1_distance_3_fallback(
36717 wuffs_png__decoder* self,
36718 wuffs_base__slice_u8 a_curr) {
36719 wuffs_base__slice_u8 v_curr = {0};
36720 uint8_t v_fa0 = 0;
36721 uint8_t v_fa1 = 0;
36722 uint8_t v_fa2 = 0;
36723
36724 {
36725 wuffs_base__slice_u8 i_slice_curr = a_curr;
36726 v_curr.ptr = i_slice_curr.ptr;
36727 v_curr.len = 3;
36728 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36729 while (v_curr.ptr < i_end0_curr) {
36730 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36731 v_curr.ptr[0] = v_fa0;
36732 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36733 v_curr.ptr[1] = v_fa1;
36734 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36735 v_curr.ptr[2] = v_fa2;
36736 v_curr.ptr += 3;
36737 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36738 v_curr.ptr[0] = v_fa0;
36739 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36740 v_curr.ptr[1] = v_fa1;
36741 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36742 v_curr.ptr[2] = v_fa2;
36743 v_curr.ptr += 3;
36744 }
36745 v_curr.len = 3;
36746 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36747 while (v_curr.ptr < i_end1_curr) {
36748 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36749 v_curr.ptr[0] = v_fa0;
36750 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36751 v_curr.ptr[1] = v_fa1;
36752 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36753 v_curr.ptr[2] = v_fa2;
36754 v_curr.ptr += 3;
36755 }
36756 v_curr.len = 0;
36757 }
36758 return wuffs_base__make_empty_struct();
36759 }
36760
36761 // -------- func png.decoder.filter_1_distance_4_fallback
36762
36763 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)36764 wuffs_png__decoder__filter_1_distance_4_fallback(
36765 wuffs_png__decoder* self,
36766 wuffs_base__slice_u8 a_curr) {
36767 wuffs_base__slice_u8 v_curr = {0};
36768 uint8_t v_fa0 = 0;
36769 uint8_t v_fa1 = 0;
36770 uint8_t v_fa2 = 0;
36771 uint8_t v_fa3 = 0;
36772
36773 {
36774 wuffs_base__slice_u8 i_slice_curr = a_curr;
36775 v_curr.ptr = i_slice_curr.ptr;
36776 v_curr.len = 4;
36777 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36778 while (v_curr.ptr < i_end0_curr) {
36779 v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0]));
36780 v_curr.ptr[0] = v_fa0;
36781 v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1]));
36782 v_curr.ptr[1] = v_fa1;
36783 v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2]));
36784 v_curr.ptr[2] = v_fa2;
36785 v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3]));
36786 v_curr.ptr[3] = v_fa3;
36787 v_curr.ptr += 4;
36788 }
36789 v_curr.len = 0;
36790 }
36791 return wuffs_base__make_empty_struct();
36792 }
36793
36794 // -------- func png.decoder.filter_2
36795
36796 static wuffs_base__empty_struct
wuffs_png__decoder__filter_2(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36797 wuffs_png__decoder__filter_2(
36798 wuffs_png__decoder* self,
36799 wuffs_base__slice_u8 a_curr,
36800 wuffs_base__slice_u8 a_prev) {
36801 uint64_t v_n = 0;
36802 uint64_t v_i = 0;
36803
36804 v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
36805 v_i = 0;
36806 while (v_i < v_n) {
36807 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
36808 v_i += 1;
36809 }
36810 return wuffs_base__make_empty_struct();
36811 }
36812
36813 // -------- func png.decoder.filter_3
36814
36815 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36816 wuffs_png__decoder__filter_3(
36817 wuffs_png__decoder* self,
36818 wuffs_base__slice_u8 a_curr,
36819 wuffs_base__slice_u8 a_prev) {
36820 return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev);
36821 }
36822
36823 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36824 wuffs_png__decoder__filter_3__choosy_default(
36825 wuffs_png__decoder* self,
36826 wuffs_base__slice_u8 a_curr,
36827 wuffs_base__slice_u8 a_prev) {
36828 uint64_t v_filter_distance = 0;
36829 uint64_t v_n = 0;
36830 uint64_t v_i = 0;
36831
36832 v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
36833 if (((uint64_t)(a_prev.len)) == 0) {
36834 v_i = v_filter_distance;
36835 while (v_i < ((uint64_t)(a_curr.len))) {
36836 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_curr.ptr[(v_i - v_filter_distance)] / 2)));
36837 v_i += 1;
36838 }
36839 } else {
36840 v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
36841 v_i = 0;
36842 while ((v_i < v_n) && (v_i < v_filter_distance)) {
36843 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_prev.ptr[v_i] / 2)));
36844 v_i += 1;
36845 }
36846 v_i = v_filter_distance;
36847 while (v_i < v_n) {
36848 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(((((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])) + ((uint32_t)(a_prev.ptr[v_i]))) / 2)))));
36849 v_i += 1;
36850 }
36851 }
36852 return wuffs_base__make_empty_struct();
36853 }
36854
36855 // -------- func png.decoder.filter_3_distance_3_fallback
36856
36857 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36858 wuffs_png__decoder__filter_3_distance_3_fallback(
36859 wuffs_png__decoder* self,
36860 wuffs_base__slice_u8 a_curr,
36861 wuffs_base__slice_u8 a_prev) {
36862 wuffs_base__slice_u8 v_curr = {0};
36863 wuffs_base__slice_u8 v_prev = {0};
36864 uint8_t v_fa0 = 0;
36865 uint8_t v_fa1 = 0;
36866 uint8_t v_fa2 = 0;
36867
36868 if (((uint64_t)(a_prev.len)) == 0) {
36869 {
36870 wuffs_base__slice_u8 i_slice_curr = a_curr;
36871 v_curr.ptr = i_slice_curr.ptr;
36872 v_curr.len = 3;
36873 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36874 while (v_curr.ptr < i_end0_curr) {
36875 v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36876 v_curr.ptr[0] = v_fa0;
36877 v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36878 v_curr.ptr[1] = v_fa1;
36879 v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36880 v_curr.ptr[2] = v_fa2;
36881 v_curr.ptr += 3;
36882 v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36883 v_curr.ptr[0] = v_fa0;
36884 v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36885 v_curr.ptr[1] = v_fa1;
36886 v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36887 v_curr.ptr[2] = v_fa2;
36888 v_curr.ptr += 3;
36889 }
36890 v_curr.len = 3;
36891 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36892 while (v_curr.ptr < i_end1_curr) {
36893 v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36894 v_curr.ptr[0] = v_fa0;
36895 v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36896 v_curr.ptr[1] = v_fa1;
36897 v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36898 v_curr.ptr[2] = v_fa2;
36899 v_curr.ptr += 3;
36900 }
36901 v_curr.len = 0;
36902 }
36903 } else {
36904 {
36905 wuffs_base__slice_u8 i_slice_curr = a_curr;
36906 v_curr.ptr = i_slice_curr.ptr;
36907 wuffs_base__slice_u8 i_slice_prev = a_prev;
36908 v_prev.ptr = i_slice_prev.ptr;
36909 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36910 v_curr.len = 3;
36911 v_prev.len = 3;
36912 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
36913 while (v_curr.ptr < i_end0_curr) {
36914 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36915 v_curr.ptr[0] = v_fa0;
36916 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36917 v_curr.ptr[1] = v_fa1;
36918 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36919 v_curr.ptr[2] = v_fa2;
36920 v_curr.ptr += 3;
36921 v_prev.ptr += 3;
36922 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36923 v_curr.ptr[0] = v_fa0;
36924 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36925 v_curr.ptr[1] = v_fa1;
36926 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36927 v_curr.ptr[2] = v_fa2;
36928 v_curr.ptr += 3;
36929 v_prev.ptr += 3;
36930 }
36931 v_curr.len = 3;
36932 v_prev.len = 3;
36933 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
36934 while (v_curr.ptr < i_end1_curr) {
36935 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36936 v_curr.ptr[0] = v_fa0;
36937 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36938 v_curr.ptr[1] = v_fa1;
36939 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
36940 v_curr.ptr[2] = v_fa2;
36941 v_curr.ptr += 3;
36942 v_prev.ptr += 3;
36943 }
36944 v_curr.len = 0;
36945 v_prev.len = 0;
36946 }
36947 }
36948 return wuffs_base__make_empty_struct();
36949 }
36950
36951 // -------- func png.decoder.filter_3_distance_4_fallback
36952
36953 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)36954 wuffs_png__decoder__filter_3_distance_4_fallback(
36955 wuffs_png__decoder* self,
36956 wuffs_base__slice_u8 a_curr,
36957 wuffs_base__slice_u8 a_prev) {
36958 wuffs_base__slice_u8 v_curr = {0};
36959 wuffs_base__slice_u8 v_prev = {0};
36960 uint8_t v_fa0 = 0;
36961 uint8_t v_fa1 = 0;
36962 uint8_t v_fa2 = 0;
36963 uint8_t v_fa3 = 0;
36964
36965 if (((uint64_t)(a_prev.len)) == 0) {
36966 {
36967 wuffs_base__slice_u8 i_slice_curr = a_curr;
36968 v_curr.ptr = i_slice_curr.ptr;
36969 v_curr.len = 4;
36970 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36971 while (v_curr.ptr < i_end0_curr) {
36972 v_fa0 = ((uint8_t)((v_fa0 / 2) + v_curr.ptr[0]));
36973 v_curr.ptr[0] = v_fa0;
36974 v_fa1 = ((uint8_t)((v_fa1 / 2) + v_curr.ptr[1]));
36975 v_curr.ptr[1] = v_fa1;
36976 v_fa2 = ((uint8_t)((v_fa2 / 2) + v_curr.ptr[2]));
36977 v_curr.ptr[2] = v_fa2;
36978 v_fa3 = ((uint8_t)((v_fa3 / 2) + v_curr.ptr[3]));
36979 v_curr.ptr[3] = v_fa3;
36980 v_curr.ptr += 4;
36981 }
36982 v_curr.len = 0;
36983 }
36984 } else {
36985 {
36986 wuffs_base__slice_u8 i_slice_curr = a_curr;
36987 v_curr.ptr = i_slice_curr.ptr;
36988 wuffs_base__slice_u8 i_slice_prev = a_prev;
36989 v_prev.ptr = i_slice_prev.ptr;
36990 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
36991 v_curr.len = 4;
36992 v_prev.len = 4;
36993 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
36994 while (v_curr.ptr < i_end0_curr) {
36995 v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0]))) / 2))) + v_curr.ptr[0]));
36996 v_curr.ptr[0] = v_fa0;
36997 v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1]))) / 2))) + v_curr.ptr[1]));
36998 v_curr.ptr[1] = v_fa1;
36999 v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2]))) / 2))) + v_curr.ptr[2]));
37000 v_curr.ptr[2] = v_fa2;
37001 v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3]))) / 2))) + v_curr.ptr[3]));
37002 v_curr.ptr[3] = v_fa3;
37003 v_curr.ptr += 4;
37004 v_prev.ptr += 4;
37005 }
37006 v_curr.len = 0;
37007 v_prev.len = 0;
37008 }
37009 }
37010 return wuffs_base__make_empty_struct();
37011 }
37012
37013 // -------- func png.decoder.filter_4
37014
37015 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)37016 wuffs_png__decoder__filter_4(
37017 wuffs_png__decoder* self,
37018 wuffs_base__slice_u8 a_curr,
37019 wuffs_base__slice_u8 a_prev) {
37020 return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev);
37021 }
37022
37023 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4__choosy_default(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)37024 wuffs_png__decoder__filter_4__choosy_default(
37025 wuffs_png__decoder* self,
37026 wuffs_base__slice_u8 a_curr,
37027 wuffs_base__slice_u8 a_prev) {
37028 uint64_t v_filter_distance = 0;
37029 uint64_t v_n = 0;
37030 uint64_t v_i = 0;
37031 uint32_t v_fa = 0;
37032 uint32_t v_fb = 0;
37033 uint32_t v_fc = 0;
37034 uint32_t v_pp = 0;
37035 uint32_t v_pa = 0;
37036 uint32_t v_pb = 0;
37037 uint32_t v_pc = 0;
37038
37039 v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
37040 v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
37041 v_i = 0;
37042 while ((v_i < v_n) && (v_i < v_filter_distance)) {
37043 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
37044 v_i += 1;
37045 }
37046 v_i = v_filter_distance;
37047 while (v_i < v_n) {
37048 v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
37049 v_fb = ((uint32_t)(a_prev.ptr[v_i]));
37050 v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
37051 v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc));
37052 v_pa = ((uint32_t)(v_pp - v_fa));
37053 if (v_pa >= 2147483648) {
37054 v_pa = ((uint32_t)(0 - v_pa));
37055 }
37056 v_pb = ((uint32_t)(v_pp - v_fb));
37057 if (v_pb >= 2147483648) {
37058 v_pb = ((uint32_t)(0 - v_pb));
37059 }
37060 v_pc = ((uint32_t)(v_pp - v_fc));
37061 if (v_pc >= 2147483648) {
37062 v_pc = ((uint32_t)(0 - v_pc));
37063 }
37064 if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
37065 } else if (v_pb <= v_pc) {
37066 v_fa = v_fb;
37067 } else {
37068 v_fa = v_fc;
37069 }
37070 a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)((v_fa & 255)))));
37071 v_i += 1;
37072 }
37073 return wuffs_base__make_empty_struct();
37074 }
37075
37076 // -------- func png.decoder.filter_4_distance_3_fallback
37077
37078 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_3_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)37079 wuffs_png__decoder__filter_4_distance_3_fallback(
37080 wuffs_png__decoder* self,
37081 wuffs_base__slice_u8 a_curr,
37082 wuffs_base__slice_u8 a_prev) {
37083 wuffs_base__slice_u8 v_curr = {0};
37084 wuffs_base__slice_u8 v_prev = {0};
37085 uint32_t v_fa0 = 0;
37086 uint32_t v_fa1 = 0;
37087 uint32_t v_fa2 = 0;
37088 uint32_t v_fb0 = 0;
37089 uint32_t v_fb1 = 0;
37090 uint32_t v_fb2 = 0;
37091 uint32_t v_fc0 = 0;
37092 uint32_t v_fc1 = 0;
37093 uint32_t v_fc2 = 0;
37094 uint32_t v_pp0 = 0;
37095 uint32_t v_pp1 = 0;
37096 uint32_t v_pp2 = 0;
37097 uint32_t v_pa0 = 0;
37098 uint32_t v_pa1 = 0;
37099 uint32_t v_pa2 = 0;
37100 uint32_t v_pb0 = 0;
37101 uint32_t v_pb1 = 0;
37102 uint32_t v_pb2 = 0;
37103 uint32_t v_pc0 = 0;
37104 uint32_t v_pc1 = 0;
37105 uint32_t v_pc2 = 0;
37106
37107 {
37108 wuffs_base__slice_u8 i_slice_curr = a_curr;
37109 v_curr.ptr = i_slice_curr.ptr;
37110 wuffs_base__slice_u8 i_slice_prev = a_prev;
37111 v_prev.ptr = i_slice_prev.ptr;
37112 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37113 v_curr.len = 3;
37114 v_prev.len = 3;
37115 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
37116 while (v_curr.ptr < i_end0_curr) {
37117 v_fb0 = ((uint32_t)(v_prev.ptr[0]));
37118 v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
37119 v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
37120 if (v_pa0 >= 2147483648) {
37121 v_pa0 = ((uint32_t)(0 - v_pa0));
37122 }
37123 v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
37124 if (v_pb0 >= 2147483648) {
37125 v_pb0 = ((uint32_t)(0 - v_pb0));
37126 }
37127 v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
37128 if (v_pc0 >= 2147483648) {
37129 v_pc0 = ((uint32_t)(0 - v_pc0));
37130 }
37131 if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
37132 } else if (v_pb0 <= v_pc0) {
37133 v_fa0 = v_fb0;
37134 } else {
37135 v_fa0 = v_fc0;
37136 }
37137 v_curr.ptr[0] = ((uint8_t)(v_curr.ptr[0] + ((uint8_t)((v_fa0 & 255)))));
37138 v_fa0 = ((uint32_t)(v_curr.ptr[0]));
37139 v_fc0 = v_fb0;
37140 v_fb1 = ((uint32_t)(v_prev.ptr[1]));
37141 v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
37142 v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
37143 if (v_pa1 >= 2147483648) {
37144 v_pa1 = ((uint32_t)(0 - v_pa1));
37145 }
37146 v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
37147 if (v_pb1 >= 2147483648) {
37148 v_pb1 = ((uint32_t)(0 - v_pb1));
37149 }
37150 v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
37151 if (v_pc1 >= 2147483648) {
37152 v_pc1 = ((uint32_t)(0 - v_pc1));
37153 }
37154 if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
37155 } else if (v_pb1 <= v_pc1) {
37156 v_fa1 = v_fb1;
37157 } else {
37158 v_fa1 = v_fc1;
37159 }
37160 v_curr.ptr[1] = ((uint8_t)(v_curr.ptr[1] + ((uint8_t)((v_fa1 & 255)))));
37161 v_fa1 = ((uint32_t)(v_curr.ptr[1]));
37162 v_fc1 = v_fb1;
37163 v_fb2 = ((uint32_t)(v_prev.ptr[2]));
37164 v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
37165 v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
37166 if (v_pa2 >= 2147483648) {
37167 v_pa2 = ((uint32_t)(0 - v_pa2));
37168 }
37169 v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
37170 if (v_pb2 >= 2147483648) {
37171 v_pb2 = ((uint32_t)(0 - v_pb2));
37172 }
37173 v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
37174 if (v_pc2 >= 2147483648) {
37175 v_pc2 = ((uint32_t)(0 - v_pc2));
37176 }
37177 if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
37178 } else if (v_pb2 <= v_pc2) {
37179 v_fa2 = v_fb2;
37180 } else {
37181 v_fa2 = v_fc2;
37182 }
37183 v_curr.ptr[2] = ((uint8_t)(v_curr.ptr[2] + ((uint8_t)((v_fa2 & 255)))));
37184 v_fa2 = ((uint32_t)(v_curr.ptr[2]));
37185 v_fc2 = v_fb2;
37186 v_curr.ptr += 3;
37187 v_prev.ptr += 3;
37188 }
37189 v_curr.len = 0;
37190 v_prev.len = 0;
37191 }
37192 return wuffs_base__make_empty_struct();
37193 }
37194
37195 // -------- func png.decoder.filter_4_distance_4_fallback
37196
37197 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_4_fallback(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)37198 wuffs_png__decoder__filter_4_distance_4_fallback(
37199 wuffs_png__decoder* self,
37200 wuffs_base__slice_u8 a_curr,
37201 wuffs_base__slice_u8 a_prev) {
37202 wuffs_base__slice_u8 v_curr = {0};
37203 wuffs_base__slice_u8 v_prev = {0};
37204 uint32_t v_fa0 = 0;
37205 uint32_t v_fa1 = 0;
37206 uint32_t v_fa2 = 0;
37207 uint32_t v_fa3 = 0;
37208 uint32_t v_fb0 = 0;
37209 uint32_t v_fb1 = 0;
37210 uint32_t v_fb2 = 0;
37211 uint32_t v_fb3 = 0;
37212 uint32_t v_fc0 = 0;
37213 uint32_t v_fc1 = 0;
37214 uint32_t v_fc2 = 0;
37215 uint32_t v_fc3 = 0;
37216 uint32_t v_pp0 = 0;
37217 uint32_t v_pp1 = 0;
37218 uint32_t v_pp2 = 0;
37219 uint32_t v_pp3 = 0;
37220 uint32_t v_pa0 = 0;
37221 uint32_t v_pa1 = 0;
37222 uint32_t v_pa2 = 0;
37223 uint32_t v_pa3 = 0;
37224 uint32_t v_pb0 = 0;
37225 uint32_t v_pb1 = 0;
37226 uint32_t v_pb2 = 0;
37227 uint32_t v_pb3 = 0;
37228 uint32_t v_pc0 = 0;
37229 uint32_t v_pc1 = 0;
37230 uint32_t v_pc2 = 0;
37231 uint32_t v_pc3 = 0;
37232
37233 {
37234 wuffs_base__slice_u8 i_slice_curr = a_curr;
37235 v_curr.ptr = i_slice_curr.ptr;
37236 wuffs_base__slice_u8 i_slice_prev = a_prev;
37237 v_prev.ptr = i_slice_prev.ptr;
37238 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37239 v_curr.len = 4;
37240 v_prev.len = 4;
37241 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37242 while (v_curr.ptr < i_end0_curr) {
37243 v_fb0 = ((uint32_t)(v_prev.ptr[0]));
37244 v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
37245 v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
37246 if (v_pa0 >= 2147483648) {
37247 v_pa0 = ((uint32_t)(0 - v_pa0));
37248 }
37249 v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
37250 if (v_pb0 >= 2147483648) {
37251 v_pb0 = ((uint32_t)(0 - v_pb0));
37252 }
37253 v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
37254 if (v_pc0 >= 2147483648) {
37255 v_pc0 = ((uint32_t)(0 - v_pc0));
37256 }
37257 if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
37258 } else if (v_pb0 <= v_pc0) {
37259 v_fa0 = v_fb0;
37260 } else {
37261 v_fa0 = v_fc0;
37262 }
37263 v_curr.ptr[0] = ((uint8_t)(v_curr.ptr[0] + ((uint8_t)((v_fa0 & 255)))));
37264 v_fa0 = ((uint32_t)(v_curr.ptr[0]));
37265 v_fc0 = v_fb0;
37266 v_fb1 = ((uint32_t)(v_prev.ptr[1]));
37267 v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
37268 v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
37269 if (v_pa1 >= 2147483648) {
37270 v_pa1 = ((uint32_t)(0 - v_pa1));
37271 }
37272 v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
37273 if (v_pb1 >= 2147483648) {
37274 v_pb1 = ((uint32_t)(0 - v_pb1));
37275 }
37276 v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
37277 if (v_pc1 >= 2147483648) {
37278 v_pc1 = ((uint32_t)(0 - v_pc1));
37279 }
37280 if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
37281 } else if (v_pb1 <= v_pc1) {
37282 v_fa1 = v_fb1;
37283 } else {
37284 v_fa1 = v_fc1;
37285 }
37286 v_curr.ptr[1] = ((uint8_t)(v_curr.ptr[1] + ((uint8_t)((v_fa1 & 255)))));
37287 v_fa1 = ((uint32_t)(v_curr.ptr[1]));
37288 v_fc1 = v_fb1;
37289 v_fb2 = ((uint32_t)(v_prev.ptr[2]));
37290 v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
37291 v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
37292 if (v_pa2 >= 2147483648) {
37293 v_pa2 = ((uint32_t)(0 - v_pa2));
37294 }
37295 v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
37296 if (v_pb2 >= 2147483648) {
37297 v_pb2 = ((uint32_t)(0 - v_pb2));
37298 }
37299 v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
37300 if (v_pc2 >= 2147483648) {
37301 v_pc2 = ((uint32_t)(0 - v_pc2));
37302 }
37303 if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
37304 } else if (v_pb2 <= v_pc2) {
37305 v_fa2 = v_fb2;
37306 } else {
37307 v_fa2 = v_fc2;
37308 }
37309 v_curr.ptr[2] = ((uint8_t)(v_curr.ptr[2] + ((uint8_t)((v_fa2 & 255)))));
37310 v_fa2 = ((uint32_t)(v_curr.ptr[2]));
37311 v_fc2 = v_fb2;
37312 v_fb3 = ((uint32_t)(v_prev.ptr[3]));
37313 v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3));
37314 v_pa3 = ((uint32_t)(v_pp3 - v_fa3));
37315 if (v_pa3 >= 2147483648) {
37316 v_pa3 = ((uint32_t)(0 - v_pa3));
37317 }
37318 v_pb3 = ((uint32_t)(v_pp3 - v_fb3));
37319 if (v_pb3 >= 2147483648) {
37320 v_pb3 = ((uint32_t)(0 - v_pb3));
37321 }
37322 v_pc3 = ((uint32_t)(v_pp3 - v_fc3));
37323 if (v_pc3 >= 2147483648) {
37324 v_pc3 = ((uint32_t)(0 - v_pc3));
37325 }
37326 if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) {
37327 } else if (v_pb3 <= v_pc3) {
37328 v_fa3 = v_fb3;
37329 } else {
37330 v_fa3 = v_fc3;
37331 }
37332 v_curr.ptr[3] = ((uint8_t)(v_curr.ptr[3] + ((uint8_t)((v_fa3 & 255)))));
37333 v_fa3 = ((uint32_t)(v_curr.ptr[3]));
37334 v_fc3 = v_fb3;
37335 v_curr.ptr += 4;
37336 v_prev.ptr += 4;
37337 }
37338 v_curr.len = 0;
37339 v_prev.len = 0;
37340 }
37341 return wuffs_base__make_empty_struct();
37342 }
37343
37344 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37345 // -------- func png.decoder.filter_1_distance_4_x86_sse42
37346
37347 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37348 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37349 static wuffs_base__empty_struct
wuffs_png__decoder__filter_1_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr)37350 wuffs_png__decoder__filter_1_distance_4_x86_sse42(
37351 wuffs_png__decoder* self,
37352 wuffs_base__slice_u8 a_curr) {
37353 wuffs_base__slice_u8 v_curr = {0};
37354 __m128i v_x128 = {0};
37355 __m128i v_a128 = {0};
37356
37357 {
37358 wuffs_base__slice_u8 i_slice_curr = a_curr;
37359 v_curr.ptr = i_slice_curr.ptr;
37360 v_curr.len = 4;
37361 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37362 while (v_curr.ptr < i_end0_curr) {
37363 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37364 v_x128 = _mm_add_epi8(v_x128, v_a128);
37365 v_a128 = v_x128;
37366 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37367 v_curr.ptr += 4;
37368 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37369 v_x128 = _mm_add_epi8(v_x128, v_a128);
37370 v_a128 = v_x128;
37371 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37372 v_curr.ptr += 4;
37373 }
37374 v_curr.len = 4;
37375 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37376 while (v_curr.ptr < i_end1_curr) {
37377 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37378 v_x128 = _mm_add_epi8(v_x128, v_a128);
37379 v_a128 = v_x128;
37380 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37381 v_curr.ptr += 4;
37382 }
37383 v_curr.len = 0;
37384 }
37385 return wuffs_base__make_empty_struct();
37386 }
37387 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37388 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37389
37390 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37391 // -------- func png.decoder.filter_3_distance_4_x86_sse42
37392
37393 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37394 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37395 static wuffs_base__empty_struct
wuffs_png__decoder__filter_3_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)37396 wuffs_png__decoder__filter_3_distance_4_x86_sse42(
37397 wuffs_png__decoder* self,
37398 wuffs_base__slice_u8 a_curr,
37399 wuffs_base__slice_u8 a_prev) {
37400 wuffs_base__slice_u8 v_curr = {0};
37401 wuffs_base__slice_u8 v_prev = {0};
37402 __m128i v_x128 = {0};
37403 __m128i v_a128 = {0};
37404 __m128i v_b128 = {0};
37405 __m128i v_p128 = {0};
37406 __m128i v_k128 = {0};
37407
37408 if (((uint64_t)(a_prev.len)) == 0) {
37409 v_k128 = _mm_set1_epi8((int8_t)(254));
37410 {
37411 wuffs_base__slice_u8 i_slice_curr = a_curr;
37412 v_curr.ptr = i_slice_curr.ptr;
37413 v_curr.len = 4;
37414 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37415 while (v_curr.ptr < i_end0_curr) {
37416 v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
37417 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37418 v_x128 = _mm_add_epi8(v_x128, v_p128);
37419 v_a128 = v_x128;
37420 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37421 v_curr.ptr += 4;
37422 v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
37423 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37424 v_x128 = _mm_add_epi8(v_x128, v_p128);
37425 v_a128 = v_x128;
37426 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37427 v_curr.ptr += 4;
37428 }
37429 v_curr.len = 4;
37430 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37431 while (v_curr.ptr < i_end1_curr) {
37432 v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
37433 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37434 v_x128 = _mm_add_epi8(v_x128, v_p128);
37435 v_a128 = v_x128;
37436 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37437 v_curr.ptr += 4;
37438 }
37439 v_curr.len = 0;
37440 }
37441 } else {
37442 v_k128 = _mm_set1_epi8((int8_t)(1));
37443 {
37444 wuffs_base__slice_u8 i_slice_curr = a_curr;
37445 v_curr.ptr = i_slice_curr.ptr;
37446 wuffs_base__slice_u8 i_slice_prev = a_prev;
37447 v_prev.ptr = i_slice_prev.ptr;
37448 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37449 v_curr.len = 4;
37450 v_prev.len = 4;
37451 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37452 while (v_curr.ptr < i_end0_curr) {
37453 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37454 v_p128 = _mm_avg_epu8(v_a128, v_b128);
37455 v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
37456 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37457 v_x128 = _mm_add_epi8(v_x128, v_p128);
37458 v_a128 = v_x128;
37459 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37460 v_curr.ptr += 4;
37461 v_prev.ptr += 4;
37462 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37463 v_p128 = _mm_avg_epu8(v_a128, v_b128);
37464 v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
37465 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37466 v_x128 = _mm_add_epi8(v_x128, v_p128);
37467 v_a128 = v_x128;
37468 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37469 v_curr.ptr += 4;
37470 v_prev.ptr += 4;
37471 }
37472 v_curr.len = 4;
37473 v_prev.len = 4;
37474 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37475 while (v_curr.ptr < i_end1_curr) {
37476 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37477 v_p128 = _mm_avg_epu8(v_a128, v_b128);
37478 v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
37479 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37480 v_x128 = _mm_add_epi8(v_x128, v_p128);
37481 v_a128 = v_x128;
37482 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37483 v_curr.ptr += 4;
37484 v_prev.ptr += 4;
37485 }
37486 v_curr.len = 0;
37487 v_prev.len = 0;
37488 }
37489 }
37490 return wuffs_base__make_empty_struct();
37491 }
37492 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37493 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37494
37495 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37496 // -------- func png.decoder.filter_4_distance_3_x86_sse42
37497
37498 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37499 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37500 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_3_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)37501 wuffs_png__decoder__filter_4_distance_3_x86_sse42(
37502 wuffs_png__decoder* self,
37503 wuffs_base__slice_u8 a_curr,
37504 wuffs_base__slice_u8 a_prev) {
37505 wuffs_base__slice_u8 v_curr = {0};
37506 wuffs_base__slice_u8 v_prev = {0};
37507 __m128i v_x128 = {0};
37508 __m128i v_a128 = {0};
37509 __m128i v_b128 = {0};
37510 __m128i v_c128 = {0};
37511 __m128i v_p128 = {0};
37512 __m128i v_pa128 = {0};
37513 __m128i v_pb128 = {0};
37514 __m128i v_pc128 = {0};
37515 __m128i v_smallest128 = {0};
37516 __m128i v_z128 = {0};
37517
37518 {
37519 wuffs_base__slice_u8 i_slice_curr = a_curr;
37520 v_curr.ptr = i_slice_curr.ptr;
37521 wuffs_base__slice_u8 i_slice_prev = a_prev;
37522 v_prev.ptr = i_slice_prev.ptr;
37523 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37524 v_curr.len = 4;
37525 v_prev.len = 4;
37526 uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6);
37527 while (v_curr.ptr < i_end0_curr) {
37528 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37529 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37530 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37531 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37532 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37533 v_pa128 = _mm_abs_epi16(v_pa128);
37534 v_pb128 = _mm_abs_epi16(v_pb128);
37535 v_pc128 = _mm_abs_epi16(v_pc128);
37536 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37537 v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
37538 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37539 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37540 v_x128 = _mm_add_epi8(v_x128, v_p128);
37541 v_a128 = v_x128;
37542 v_c128 = v_b128;
37543 v_x128 = _mm_packus_epi16(v_x128, v_x128);
37544 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37545 v_curr.ptr += 3;
37546 v_prev.ptr += 3;
37547 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37548 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37549 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37550 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37551 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37552 v_pa128 = _mm_abs_epi16(v_pa128);
37553 v_pb128 = _mm_abs_epi16(v_pb128);
37554 v_pc128 = _mm_abs_epi16(v_pc128);
37555 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37556 v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
37557 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37558 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37559 v_x128 = _mm_add_epi8(v_x128, v_p128);
37560 v_a128 = v_x128;
37561 v_c128 = v_b128;
37562 v_x128 = _mm_packus_epi16(v_x128, v_x128);
37563 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37564 v_curr.ptr += 3;
37565 v_prev.ptr += 3;
37566 }
37567 v_curr.len = 4;
37568 v_prev.len = 4;
37569 uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3);
37570 while (v_curr.ptr < i_end1_curr) {
37571 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37572 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37573 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37574 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37575 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37576 v_pa128 = _mm_abs_epi16(v_pa128);
37577 v_pb128 = _mm_abs_epi16(v_pb128);
37578 v_pc128 = _mm_abs_epi16(v_pc128);
37579 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37580 v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
37581 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37582 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37583 v_x128 = _mm_add_epi8(v_x128, v_p128);
37584 v_a128 = v_x128;
37585 v_c128 = v_b128;
37586 v_x128 = _mm_packus_epi16(v_x128, v_x128);
37587 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37588 v_curr.ptr += 3;
37589 v_prev.ptr += 3;
37590 }
37591 v_curr.len = 3;
37592 v_prev.len = 3;
37593 uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
37594 while (v_curr.ptr < i_end2_curr) {
37595 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
37596 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37597 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37598 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37599 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37600 v_pa128 = _mm_abs_epi16(v_pa128);
37601 v_pb128 = _mm_abs_epi16(v_pb128);
37602 v_pc128 = _mm_abs_epi16(v_pc128);
37603 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37604 v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
37605 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
37606 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37607 v_x128 = _mm_add_epi8(v_x128, v_p128);
37608 v_x128 = _mm_packus_epi16(v_x128, v_x128);
37609 wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37610 v_curr.ptr += 3;
37611 v_prev.ptr += 3;
37612 }
37613 v_curr.len = 0;
37614 v_prev.len = 0;
37615 }
37616 return wuffs_base__make_empty_struct();
37617 }
37618 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37619 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37620
37621 // ‼ WUFFS MULTI-FILE SECTION +x86_sse42
37622 // -------- func png.decoder.filter_4_distance_4_x86_sse42
37623
37624 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37625 WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
37626 static wuffs_base__empty_struct
wuffs_png__decoder__filter_4_distance_4_x86_sse42(wuffs_png__decoder * self,wuffs_base__slice_u8 a_curr,wuffs_base__slice_u8 a_prev)37627 wuffs_png__decoder__filter_4_distance_4_x86_sse42(
37628 wuffs_png__decoder* self,
37629 wuffs_base__slice_u8 a_curr,
37630 wuffs_base__slice_u8 a_prev) {
37631 wuffs_base__slice_u8 v_curr = {0};
37632 wuffs_base__slice_u8 v_prev = {0};
37633 __m128i v_x128 = {0};
37634 __m128i v_a128 = {0};
37635 __m128i v_b128 = {0};
37636 __m128i v_c128 = {0};
37637 __m128i v_p128 = {0};
37638 __m128i v_pa128 = {0};
37639 __m128i v_pb128 = {0};
37640 __m128i v_pc128 = {0};
37641 __m128i v_smallest128 = {0};
37642 __m128i v_z128 = {0};
37643
37644 {
37645 wuffs_base__slice_u8 i_slice_curr = a_curr;
37646 v_curr.ptr = i_slice_curr.ptr;
37647 wuffs_base__slice_u8 i_slice_prev = a_prev;
37648 v_prev.ptr = i_slice_prev.ptr;
37649 i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
37650 v_curr.len = 4;
37651 v_prev.len = 4;
37652 uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
37653 while (v_curr.ptr < i_end0_curr) {
37654 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37655 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37656 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37657 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37658 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37659 v_pa128 = _mm_abs_epi16(v_pa128);
37660 v_pb128 = _mm_abs_epi16(v_pb128);
37661 v_pc128 = _mm_abs_epi16(v_pc128);
37662 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37663 v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
37664 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37665 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37666 v_x128 = _mm_add_epi8(v_x128, v_p128);
37667 v_a128 = v_x128;
37668 v_c128 = v_b128;
37669 v_x128 = _mm_packus_epi16(v_x128, v_x128);
37670 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37671 v_curr.ptr += 4;
37672 v_prev.ptr += 4;
37673 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37674 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37675 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37676 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37677 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37678 v_pa128 = _mm_abs_epi16(v_pa128);
37679 v_pb128 = _mm_abs_epi16(v_pb128);
37680 v_pc128 = _mm_abs_epi16(v_pc128);
37681 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37682 v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
37683 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37684 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37685 v_x128 = _mm_add_epi8(v_x128, v_p128);
37686 v_a128 = v_x128;
37687 v_c128 = v_b128;
37688 v_x128 = _mm_packus_epi16(v_x128, v_x128);
37689 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37690 v_curr.ptr += 4;
37691 v_prev.ptr += 4;
37692 }
37693 v_curr.len = 4;
37694 v_prev.len = 4;
37695 uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
37696 while (v_curr.ptr < i_end1_curr) {
37697 v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
37698 v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
37699 v_pa128 = _mm_sub_epi16(v_b128, v_c128);
37700 v_pb128 = _mm_sub_epi16(v_a128, v_c128);
37701 v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
37702 v_pa128 = _mm_abs_epi16(v_pa128);
37703 v_pb128 = _mm_abs_epi16(v_pb128);
37704 v_pc128 = _mm_abs_epi16(v_pc128);
37705 v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
37706 v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
37707 v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
37708 v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
37709 v_x128 = _mm_add_epi8(v_x128, v_p128);
37710 v_a128 = v_x128;
37711 v_c128 = v_b128;
37712 v_x128 = _mm_packus_epi16(v_x128, v_x128);
37713 wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
37714 v_curr.ptr += 4;
37715 v_prev.ptr += 4;
37716 }
37717 v_curr.len = 0;
37718 v_prev.len = 0;
37719 }
37720 return wuffs_base__make_empty_struct();
37721 }
37722 #endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
37723 // ‼ WUFFS MULTI-FILE SECTION -x86_sse42
37724
37725 // -------- func png.decoder.set_quirk_enabled
37726
37727 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_png__decoder__set_quirk_enabled(wuffs_png__decoder * self,uint32_t a_quirk,bool a_enabled)37728 wuffs_png__decoder__set_quirk_enabled(
37729 wuffs_png__decoder* self,
37730 uint32_t a_quirk,
37731 bool a_enabled) {
37732 if (!self) {
37733 return wuffs_base__make_empty_struct();
37734 }
37735 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37736 return wuffs_base__make_empty_struct();
37737 }
37738
37739 if (a_quirk == 1) {
37740 self->private_impl.f_ignore_checksum = a_enabled;
37741 wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, a_quirk, a_enabled);
37742 }
37743 return wuffs_base__make_empty_struct();
37744 }
37745
37746 // -------- func png.decoder.decode_image_config
37747
37748 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__decode_image_config(wuffs_png__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)37749 wuffs_png__decoder__decode_image_config(
37750 wuffs_png__decoder* self,
37751 wuffs_base__image_config* a_dst,
37752 wuffs_base__io_buffer* a_src) {
37753 if (!self) {
37754 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
37755 }
37756 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
37757 return wuffs_base__make_status(
37758 (self->private_impl.magic == WUFFS_BASE__DISABLED)
37759 ? wuffs_base__error__disabled_by_previous_error
37760 : wuffs_base__error__initialize_not_called);
37761 }
37762 if (!a_src) {
37763 self->private_impl.magic = WUFFS_BASE__DISABLED;
37764 return wuffs_base__make_status(wuffs_base__error__bad_argument);
37765 }
37766 if ((self->private_impl.active_coroutine != 0) &&
37767 (self->private_impl.active_coroutine != 1)) {
37768 self->private_impl.magic = WUFFS_BASE__DISABLED;
37769 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
37770 }
37771 self->private_impl.active_coroutine = 0;
37772 wuffs_base__status status = wuffs_base__make_status(NULL);
37773
37774 uint64_t v_magic = 0;
37775 uint64_t v_mark = 0;
37776 uint32_t v_checksum_have = 0;
37777 uint32_t v_checksum_want = 0;
37778 wuffs_base__status v_status = wuffs_base__make_status(NULL);
37779
37780 const uint8_t* iop_a_src = NULL;
37781 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37782 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37783 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
37784 if (a_src) {
37785 io0_a_src = a_src->data.ptr;
37786 io1_a_src = io0_a_src + a_src->meta.ri;
37787 iop_a_src = io1_a_src;
37788 io2_a_src = io0_a_src + a_src->meta.wi;
37789 }
37790
37791 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
37792 if (coro_susp_point) {
37793 v_checksum_have = self->private_data.s_decode_image_config[0].v_checksum_have;
37794 }
37795 switch (coro_susp_point) {
37796 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
37797
37798 if (self->private_impl.f_call_sequence == 2) {
37799 if (self->private_impl.f_metadata_fourcc != 0) {
37800 self->private_impl.f_call_sequence = 1;
37801 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
37802 goto ok;
37803 }
37804 } else if (self->private_impl.f_call_sequence != 0) {
37805 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
37806 goto exit;
37807 } else {
37808 {
37809 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
37810 uint64_t t_0;
37811 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
37812 t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
37813 iop_a_src += 8;
37814 } else {
37815 self->private_data.s_decode_image_config[0].scratch = 0;
37816 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
37817 while (true) {
37818 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37819 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37820 goto suspend;
37821 }
37822 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37823 uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
37824 *scratch <<= 8;
37825 *scratch >>= 8;
37826 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
37827 if (num_bits_0 == 56) {
37828 t_0 = ((uint64_t)(*scratch));
37829 break;
37830 }
37831 num_bits_0 += 8;
37832 *scratch |= ((uint64_t)(num_bits_0)) << 56;
37833 }
37834 }
37835 v_magic = t_0;
37836 }
37837 if (v_magic != 727905341920923785) {
37838 status = wuffs_base__make_status(wuffs_png__error__bad_header);
37839 goto exit;
37840 }
37841 {
37842 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
37843 uint64_t t_1;
37844 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
37845 t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
37846 iop_a_src += 8;
37847 } else {
37848 self->private_data.s_decode_image_config[0].scratch = 0;
37849 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
37850 while (true) {
37851 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37852 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37853 goto suspend;
37854 }
37855 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37856 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
37857 *scratch <<= 8;
37858 *scratch >>= 8;
37859 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
37860 if (num_bits_1 == 56) {
37861 t_1 = ((uint64_t)(*scratch));
37862 break;
37863 }
37864 num_bits_1 += 8;
37865 *scratch |= ((uint64_t)(num_bits_1)) << 56;
37866 }
37867 }
37868 v_magic = t_1;
37869 }
37870 if (v_magic != 5927942488114331648) {
37871 status = wuffs_base__make_status(wuffs_png__error__bad_header);
37872 goto exit;
37873 }
37874 self->private_impl.f_chunk_type_array[0] = 73;
37875 self->private_impl.f_chunk_type_array[1] = 72;
37876 self->private_impl.f_chunk_type_array[2] = 68;
37877 self->private_impl.f_chunk_type_array[3] = 82;
37878 wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
37879 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
37880 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
37881 while (true) {
37882 v_mark = ((uint64_t)(iop_a_src - io0_a_src));
37883 {
37884 if (a_src) {
37885 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37886 }
37887 wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src);
37888 v_status = t_2;
37889 if (a_src) {
37890 iop_a_src = a_src->data.ptr + a_src->meta.ri;
37891 }
37892 }
37893 if ( ! self->private_impl.f_ignore_checksum) {
37894 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
37895 }
37896 if (wuffs_base__status__is_ok(&v_status)) {
37897 goto label__0__break;
37898 }
37899 status = v_status;
37900 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
37901 }
37902 label__0__break:;
37903 {
37904 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
37905 uint32_t t_3;
37906 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
37907 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37908 iop_a_src += 4;
37909 } else {
37910 self->private_data.s_decode_image_config[0].scratch = 0;
37911 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
37912 while (true) {
37913 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
37914 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37915 goto suspend;
37916 }
37917 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
37918 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
37919 *scratch >>= 8;
37920 *scratch <<= 8;
37921 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
37922 if (num_bits_3 == 24) {
37923 t_3 = ((uint32_t)(*scratch >> 32));
37924 break;
37925 }
37926 num_bits_3 += 8;
37927 *scratch |= ((uint64_t)(num_bits_3));
37928 }
37929 }
37930 v_checksum_want = t_3;
37931 }
37932 if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) {
37933 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
37934 goto exit;
37935 }
37936 }
37937 while (true) {
37938 while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
37939 if (a_src && a_src->meta.closed) {
37940 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37941 goto exit;
37942 }
37943 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
37944 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
37945 }
37946 self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
37947 self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
37948 if (self->private_impl.f_chunk_type == 1413563465) {
37949 if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) {
37950 goto label__1__break;
37951 }
37952 self->private_impl.f_seen_idat = true;
37953 } else if (self->private_impl.f_chunk_type == 1413571686) {
37954 if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) {
37955 goto label__1__break;
37956 }
37957 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
37958 goto exit;
37959 }
37960 iop_a_src += 8;
37961 if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0)) {
37962 self->private_impl.f_chunk_type_array[0] = ((uint8_t)(((self->private_impl.f_chunk_type >> 0) & 255)));
37963 self->private_impl.f_chunk_type_array[1] = ((uint8_t)(((self->private_impl.f_chunk_type >> 8) & 255)));
37964 self->private_impl.f_chunk_type_array[2] = ((uint8_t)(((self->private_impl.f_chunk_type >> 16) & 255)));
37965 self->private_impl.f_chunk_type_array[3] = ((uint8_t)(((self->private_impl.f_chunk_type >> 24) & 255)));
37966 wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
37967 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
37968 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
37969 }
37970 while (true) {
37971 v_mark = ((uint64_t)(iop_a_src - io0_a_src));
37972 {
37973 if (a_src) {
37974 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
37975 }
37976 wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src);
37977 v_status = t_4;
37978 if (a_src) {
37979 iop_a_src = a_src->data.ptr + a_src->meta.ri;
37980 }
37981 }
37982 if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0)) {
37983 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
37984 }
37985 if (wuffs_base__status__is_ok(&v_status)) {
37986 goto label__2__break;
37987 }
37988 status = v_status;
37989 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
37990 }
37991 label__2__break:;
37992 if (self->private_impl.f_metadata_fourcc != 0) {
37993 self->private_impl.f_call_sequence = 1;
37994 status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
37995 goto ok;
37996 }
37997 {
37998 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
37999 uint32_t t_5;
38000 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38001 t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38002 iop_a_src += 4;
38003 } else {
38004 self->private_data.s_decode_image_config[0].scratch = 0;
38005 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
38006 while (true) {
38007 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38008 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38009 goto suspend;
38010 }
38011 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
38012 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
38013 *scratch >>= 8;
38014 *scratch <<= 8;
38015 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
38016 if (num_bits_5 == 24) {
38017 t_5 = ((uint32_t)(*scratch >> 32));
38018 break;
38019 }
38020 num_bits_5 += 8;
38021 *scratch |= ((uint64_t)(num_bits_5));
38022 }
38023 }
38024 v_checksum_want = t_5;
38025 }
38026 if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32) == 0) && (v_checksum_have != v_checksum_want)) {
38027 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
38028 goto exit;
38029 }
38030 }
38031 label__1__break:;
38032 if ((self->private_impl.f_color_type == 3) && ! self->private_impl.f_seen_plte) {
38033 status = wuffs_base__make_status(wuffs_png__error__missing_palette);
38034 goto exit;
38035 }
38036 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
38037 self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position;
38038 if (a_dst != NULL) {
38039 wuffs_base__image_config__set(
38040 a_dst,
38041 self->private_impl.f_dst_pixfmt,
38042 0,
38043 self->private_impl.f_width,
38044 self->private_impl.f_height,
38045 self->private_impl.f_first_config_io_position,
38046 ((self->private_impl.f_color_type <= 3) && ! self->private_impl.f_seen_trns));
38047 }
38048 if ( ! self->private_impl.f_seen_actl) {
38049 self->private_impl.f_num_animation_frames_value = 1;
38050 self->private_impl.f_first_rect_x0 = 0;
38051 self->private_impl.f_first_rect_y0 = 0;
38052 self->private_impl.f_first_rect_x1 = self->private_impl.f_width;
38053 self->private_impl.f_first_rect_y1 = self->private_impl.f_height;
38054 self->private_impl.f_first_duration = 0;
38055 self->private_impl.f_first_disposal = 0;
38056 self->private_impl.f_first_overwrite_instead_of_blend = false;
38057 }
38058 self->private_impl.f_call_sequence = 3;
38059
38060 ok:
38061 self->private_impl.p_decode_image_config[0] = 0;
38062 goto exit;
38063 }
38064
38065 goto suspend;
38066 suspend:
38067 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38068 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
38069 self->private_data.s_decode_image_config[0].v_checksum_have = v_checksum_have;
38070
38071 goto exit;
38072 exit:
38073 if (a_src) {
38074 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38075 }
38076
38077 if (wuffs_base__status__is_error(&status)) {
38078 self->private_impl.magic = WUFFS_BASE__DISABLED;
38079 }
38080 return status;
38081 }
38082
38083 // -------- func png.decoder.decode_ihdr
38084
38085 static wuffs_base__status
wuffs_png__decoder__decode_ihdr(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38086 wuffs_png__decoder__decode_ihdr(
38087 wuffs_png__decoder* self,
38088 wuffs_base__io_buffer* a_src) {
38089 wuffs_base__status status = wuffs_base__make_status(NULL);
38090
38091 uint32_t v_a32 = 0;
38092 uint8_t v_a8 = 0;
38093
38094 const uint8_t* iop_a_src = NULL;
38095 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38096 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38097 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38098 if (a_src) {
38099 io0_a_src = a_src->data.ptr;
38100 io1_a_src = io0_a_src + a_src->meta.ri;
38101 iop_a_src = io1_a_src;
38102 io2_a_src = io0_a_src + a_src->meta.wi;
38103 }
38104
38105 uint32_t coro_susp_point = self->private_impl.p_decode_ihdr[0];
38106 switch (coro_susp_point) {
38107 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38108
38109 {
38110 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38111 uint32_t t_0;
38112 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38113 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38114 iop_a_src += 4;
38115 } else {
38116 self->private_data.s_decode_ihdr[0].scratch = 0;
38117 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38118 while (true) {
38119 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38120 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38121 goto suspend;
38122 }
38123 uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
38124 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38125 *scratch >>= 8;
38126 *scratch <<= 8;
38127 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38128 if (num_bits_0 == 24) {
38129 t_0 = ((uint32_t)(*scratch >> 32));
38130 break;
38131 }
38132 num_bits_0 += 8;
38133 *scratch |= ((uint64_t)(num_bits_0));
38134 }
38135 }
38136 v_a32 = t_0;
38137 }
38138 if ((v_a32 == 0) || (v_a32 >= 2147483648)) {
38139 status = wuffs_base__make_status(wuffs_png__error__bad_header);
38140 goto exit;
38141 } else if (v_a32 >= 16777216) {
38142 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38143 goto exit;
38144 }
38145 self->private_impl.f_width = v_a32;
38146 {
38147 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38148 uint32_t t_1;
38149 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38150 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38151 iop_a_src += 4;
38152 } else {
38153 self->private_data.s_decode_ihdr[0].scratch = 0;
38154 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38155 while (true) {
38156 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38157 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38158 goto suspend;
38159 }
38160 uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
38161 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38162 *scratch >>= 8;
38163 *scratch <<= 8;
38164 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38165 if (num_bits_1 == 24) {
38166 t_1 = ((uint32_t)(*scratch >> 32));
38167 break;
38168 }
38169 num_bits_1 += 8;
38170 *scratch |= ((uint64_t)(num_bits_1));
38171 }
38172 }
38173 v_a32 = t_1;
38174 }
38175 if ((v_a32 == 0) || (v_a32 >= 2147483648)) {
38176 status = wuffs_base__make_status(wuffs_png__error__bad_header);
38177 goto exit;
38178 } else if (v_a32 >= 16777216) {
38179 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38180 goto exit;
38181 }
38182 self->private_impl.f_height = v_a32;
38183 {
38184 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38185 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38186 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38187 goto suspend;
38188 }
38189 uint8_t t_2 = *iop_a_src++;
38190 v_a8 = t_2;
38191 }
38192 if (v_a8 > 16) {
38193 status = wuffs_base__make_status(wuffs_png__error__bad_header);
38194 goto exit;
38195 }
38196 self->private_impl.f_depth = v_a8;
38197 {
38198 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38199 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38200 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38201 goto suspend;
38202 }
38203 uint8_t t_3 = *iop_a_src++;
38204 v_a8 = t_3;
38205 }
38206 if ((v_a8 == 1) || (v_a8 == 5) || (v_a8 > 6)) {
38207 status = wuffs_base__make_status(wuffs_png__error__bad_header);
38208 goto exit;
38209 }
38210 self->private_impl.f_color_type = v_a8;
38211 {
38212 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38213 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38214 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38215 goto suspend;
38216 }
38217 uint8_t t_4 = *iop_a_src++;
38218 v_a8 = t_4;
38219 }
38220 if (v_a8 != 0) {
38221 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
38222 goto exit;
38223 }
38224 {
38225 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38226 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38227 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38228 goto suspend;
38229 }
38230 uint8_t t_5 = *iop_a_src++;
38231 v_a8 = t_5;
38232 }
38233 if (v_a8 != 0) {
38234 status = wuffs_base__make_status(wuffs_png__error__bad_header);
38235 goto exit;
38236 }
38237 {
38238 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38239 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38240 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38241 goto suspend;
38242 }
38243 uint8_t t_6 = *iop_a_src++;
38244 v_a8 = t_6;
38245 }
38246 if (v_a8 == 0) {
38247 self->private_impl.f_interlace_pass = 0;
38248 } else if (v_a8 == 1) {
38249 self->private_impl.f_interlace_pass = 1;
38250 self->private_impl.choosy_filter_and_swizzle = (
38251 &wuffs_png__decoder__filter_and_swizzle_tricky);
38252 } else {
38253 status = wuffs_base__make_status(wuffs_png__error__bad_header);
38254 goto exit;
38255 }
38256 self->private_impl.f_filter_distance = 0;
38257 wuffs_png__decoder__assign_filter_distance(self);
38258 if (self->private_impl.f_filter_distance == 0) {
38259 status = wuffs_base__make_status(wuffs_png__error__bad_header);
38260 goto exit;
38261 }
38262 self->private_impl.f_overall_workbuf_length = (((uint64_t)(self->private_impl.f_height)) * (1 + wuffs_png__decoder__calculate_bytes_per_row(self, self->private_impl.f_width)));
38263 wuffs_png__decoder__choose_filter_implementations(self);
38264
38265 goto ok;
38266 ok:
38267 self->private_impl.p_decode_ihdr[0] = 0;
38268 goto exit;
38269 }
38270
38271 goto suspend;
38272 suspend:
38273 self->private_impl.p_decode_ihdr[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38274
38275 goto exit;
38276 exit:
38277 if (a_src) {
38278 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38279 }
38280
38281 return status;
38282 }
38283
38284 // -------- func png.decoder.assign_filter_distance
38285
38286 static wuffs_base__empty_struct
wuffs_png__decoder__assign_filter_distance(wuffs_png__decoder * self)38287 wuffs_png__decoder__assign_filter_distance(
38288 wuffs_png__decoder* self) {
38289 if (self->private_impl.f_depth < 8) {
38290 if ((self->private_impl.f_depth != 1) && (self->private_impl.f_depth != 2) && (self->private_impl.f_depth != 4)) {
38291 return wuffs_base__make_empty_struct();
38292 } else if (self->private_impl.f_color_type == 0) {
38293 self->private_impl.f_dst_pixfmt = 536870920;
38294 self->private_impl.f_src_pixfmt = 536870920;
38295 } else if (self->private_impl.f_color_type == 3) {
38296 self->private_impl.f_dst_pixfmt = 2198077448;
38297 self->private_impl.f_src_pixfmt = 2198077448;
38298 } else {
38299 return wuffs_base__make_empty_struct();
38300 }
38301 self->private_impl.f_filter_distance = 1;
38302 self->private_impl.choosy_filter_and_swizzle = (
38303 &wuffs_png__decoder__filter_and_swizzle_tricky);
38304 } else if (self->private_impl.f_color_type == 0) {
38305 if (self->private_impl.f_depth == 8) {
38306 self->private_impl.f_dst_pixfmt = 536870920;
38307 self->private_impl.f_src_pixfmt = 536870920;
38308 self->private_impl.f_filter_distance = 1;
38309 } else if (self->private_impl.f_depth == 16) {
38310 if (self->private_impl.f_interlace_pass == 0) {
38311 self->private_impl.f_dst_pixfmt = 536870923;
38312 self->private_impl.f_src_pixfmt = 537919499;
38313 } else {
38314 self->private_impl.f_dst_pixfmt = 2164308923;
38315 self->private_impl.f_src_pixfmt = 2164308923;
38316 }
38317 self->private_impl.f_filter_distance = 2;
38318 }
38319 } else if (self->private_impl.f_color_type == 2) {
38320 if (self->private_impl.f_depth == 8) {
38321 self->private_impl.f_dst_pixfmt = 2147485832;
38322 self->private_impl.f_src_pixfmt = 2684356744;
38323 self->private_impl.f_filter_distance = 3;
38324 } else if (self->private_impl.f_depth == 16) {
38325 self->private_impl.f_dst_pixfmt = 2164308923;
38326 self->private_impl.f_src_pixfmt = 2164308923;
38327 self->private_impl.f_filter_distance = 6;
38328 self->private_impl.choosy_filter_and_swizzle = (
38329 &wuffs_png__decoder__filter_and_swizzle_tricky);
38330 }
38331 } else if (self->private_impl.f_color_type == 3) {
38332 if (self->private_impl.f_depth == 8) {
38333 self->private_impl.f_dst_pixfmt = 2198077448;
38334 self->private_impl.f_src_pixfmt = 2198077448;
38335 self->private_impl.f_filter_distance = 1;
38336 }
38337 } else if (self->private_impl.f_color_type == 4) {
38338 if (self->private_impl.f_depth == 8) {
38339 self->private_impl.f_dst_pixfmt = 2164295816;
38340 self->private_impl.f_src_pixfmt = 2164295816;
38341 self->private_impl.f_filter_distance = 2;
38342 self->private_impl.choosy_filter_and_swizzle = (
38343 &wuffs_png__decoder__filter_and_swizzle_tricky);
38344 } else if (self->private_impl.f_depth == 16) {
38345 self->private_impl.f_dst_pixfmt = 2164308923;
38346 self->private_impl.f_src_pixfmt = 2164308923;
38347 self->private_impl.f_filter_distance = 4;
38348 self->private_impl.choosy_filter_and_swizzle = (
38349 &wuffs_png__decoder__filter_and_swizzle_tricky);
38350 }
38351 } else if (self->private_impl.f_color_type == 6) {
38352 if (self->private_impl.f_depth == 8) {
38353 self->private_impl.f_dst_pixfmt = 2164295816;
38354 self->private_impl.f_src_pixfmt = 2701166728;
38355 self->private_impl.f_filter_distance = 4;
38356 } else if (self->private_impl.f_depth == 16) {
38357 self->private_impl.f_dst_pixfmt = 2164308923;
38358 self->private_impl.f_src_pixfmt = 2164308923;
38359 self->private_impl.f_filter_distance = 8;
38360 self->private_impl.choosy_filter_and_swizzle = (
38361 &wuffs_png__decoder__filter_and_swizzle_tricky);
38362 }
38363 }
38364 return wuffs_base__make_empty_struct();
38365 }
38366
38367 // -------- func png.decoder.calculate_bytes_per_row
38368
38369 static uint64_t
wuffs_png__decoder__calculate_bytes_per_row(const wuffs_png__decoder * self,uint32_t a_width)38370 wuffs_png__decoder__calculate_bytes_per_row(
38371 const wuffs_png__decoder* self,
38372 uint32_t a_width) {
38373 uint64_t v_bytes_per_channel = 0;
38374
38375 if (self->private_impl.f_depth == 1) {
38376 return ((uint64_t)(((a_width + 7) / 8)));
38377 } else if (self->private_impl.f_depth == 2) {
38378 return ((uint64_t)(((a_width + 3) / 4)));
38379 } else if (self->private_impl.f_depth == 4) {
38380 return ((uint64_t)(((a_width + 1) / 2)));
38381 }
38382 v_bytes_per_channel = ((uint64_t)((self->private_impl.f_depth >> 3)));
38383 return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])));
38384 }
38385
38386 // -------- func png.decoder.choose_filter_implementations
38387
38388 static wuffs_base__empty_struct
wuffs_png__decoder__choose_filter_implementations(wuffs_png__decoder * self)38389 wuffs_png__decoder__choose_filter_implementations(
38390 wuffs_png__decoder* self) {
38391 if (self->private_impl.f_filter_distance == 3) {
38392 self->private_impl.choosy_filter_1 = (
38393 &wuffs_png__decoder__filter_1_distance_3_fallback);
38394 self->private_impl.choosy_filter_3 = (
38395 &wuffs_png__decoder__filter_3_distance_3_fallback);
38396 self->private_impl.choosy_filter_4 = (
38397 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38398 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon :
38399 #endif
38400 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38401 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 :
38402 #endif
38403 &wuffs_png__decoder__filter_4_distance_3_fallback);
38404 } else if (self->private_impl.f_filter_distance == 4) {
38405 self->private_impl.choosy_filter_1 = (
38406 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38407 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon :
38408 #endif
38409 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38410 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 :
38411 #endif
38412 &wuffs_png__decoder__filter_1_distance_4_fallback);
38413 self->private_impl.choosy_filter_3 = (
38414 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38415 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon :
38416 #endif
38417 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38418 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 :
38419 #endif
38420 &wuffs_png__decoder__filter_3_distance_4_fallback);
38421 self->private_impl.choosy_filter_4 = (
38422 #if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
38423 wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon :
38424 #endif
38425 #if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
38426 wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 :
38427 #endif
38428 &wuffs_png__decoder__filter_4_distance_4_fallback);
38429 }
38430 return wuffs_base__make_empty_struct();
38431 }
38432
38433 // -------- func png.decoder.decode_other_chunk
38434
38435 static wuffs_base__status
wuffs_png__decoder__decode_other_chunk(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38436 wuffs_png__decoder__decode_other_chunk(
38437 wuffs_png__decoder* self,
38438 wuffs_base__io_buffer* a_src) {
38439 wuffs_base__status status = wuffs_base__make_status(NULL);
38440
38441 const uint8_t* iop_a_src = NULL;
38442 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38443 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38444 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38445 if (a_src) {
38446 io0_a_src = a_src->data.ptr;
38447 io1_a_src = io0_a_src + a_src->meta.ri;
38448 iop_a_src = io1_a_src;
38449 io2_a_src = io0_a_src + a_src->meta.wi;
38450 }
38451
38452 uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk[0];
38453 switch (coro_susp_point) {
38454 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38455
38456 if (self->private_impl.f_chunk_type == 1163152464) {
38457 if (self->private_impl.f_seen_plte) {
38458 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38459 goto exit;
38460 } else if (self->private_impl.f_color_type == 3) {
38461 if (a_src) {
38462 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38463 }
38464 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38465 status = wuffs_png__decoder__decode_plte(self, a_src);
38466 if (a_src) {
38467 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38468 }
38469 if (status.repr) {
38470 goto suspend;
38471 }
38472 } else if ((self->private_impl.f_color_type == 2) || (self->private_impl.f_color_type == 6)) {
38473 } else {
38474 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38475 goto exit;
38476 }
38477 self->private_impl.f_seen_plte = true;
38478 } else if ((self->private_impl.f_chunk_type & 32) == 0) {
38479 if (self->private_impl.f_chunk_type != 1413563465) {
38480 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38481 goto exit;
38482 }
38483 } else if (self->private_impl.f_chunk_type == 1280598881) {
38484 if (self->private_impl.f_seen_actl) {
38485 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38486 goto exit;
38487 }
38488 if (a_src) {
38489 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38490 }
38491 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38492 status = wuffs_png__decoder__decode_actl(self, a_src);
38493 if (a_src) {
38494 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38495 }
38496 if (status.repr) {
38497 goto suspend;
38498 }
38499 self->private_impl.f_seen_actl = true;
38500 } else if (self->private_impl.f_chunk_type == 1297238115) {
38501 if (self->private_impl.f_report_metadata_chrm) {
38502 if (self->private_impl.f_seen_chrm) {
38503 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38504 goto exit;
38505 }
38506 if (a_src) {
38507 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38508 }
38509 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38510 status = wuffs_png__decoder__decode_chrm(self, a_src);
38511 if (a_src) {
38512 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38513 }
38514 if (status.repr) {
38515 goto suspend;
38516 }
38517 self->private_impl.f_seen_chrm = true;
38518 }
38519 } else if (self->private_impl.f_chunk_type == 1716082789) {
38520 if (self->private_impl.f_report_metadata_exif) {
38521 if (self->private_impl.f_seen_exif) {
38522 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38523 goto exit;
38524 }
38525 if (a_src) {
38526 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38527 }
38528 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38529 status = wuffs_png__decoder__decode_exif(self, a_src);
38530 if (a_src) {
38531 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38532 }
38533 if (status.repr) {
38534 goto suspend;
38535 }
38536 self->private_impl.f_seen_exif = true;
38537 }
38538 } else if (self->private_impl.f_chunk_type == 1280598886) {
38539 if (self->private_impl.f_seen_fctl) {
38540 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38541 goto exit;
38542 }
38543 if (a_src) {
38544 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38545 }
38546 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38547 status = wuffs_png__decoder__decode_fctl(self, a_src);
38548 if (a_src) {
38549 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38550 }
38551 if (status.repr) {
38552 goto suspend;
38553 }
38554 self->private_impl.f_seen_fctl = true;
38555 } else if (self->private_impl.f_chunk_type == 1095582055) {
38556 if (self->private_impl.f_report_metadata_gama) {
38557 if (self->private_impl.f_seen_gama) {
38558 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38559 goto exit;
38560 }
38561 if (a_src) {
38562 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38563 }
38564 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38565 status = wuffs_png__decoder__decode_gama(self, a_src);
38566 if (a_src) {
38567 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38568 }
38569 if (status.repr) {
38570 goto suspend;
38571 }
38572 self->private_impl.f_seen_gama = true;
38573 }
38574 } else if (self->private_impl.f_chunk_type == 1346585449) {
38575 if (self->private_impl.f_report_metadata_iccp) {
38576 if (self->private_impl.f_seen_iccp) {
38577 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38578 goto exit;
38579 }
38580 if (a_src) {
38581 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38582 }
38583 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38584 status = wuffs_png__decoder__decode_iccp(self, a_src);
38585 if (a_src) {
38586 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38587 }
38588 if (status.repr) {
38589 goto suspend;
38590 }
38591 self->private_impl.f_seen_iccp = true;
38592 }
38593 } else if (self->private_impl.f_chunk_type == 1111970419) {
38594 if (self->private_impl.f_report_metadata_srgb) {
38595 if (self->private_impl.f_seen_srgb) {
38596 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38597 goto exit;
38598 }
38599 if (a_src) {
38600 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38601 }
38602 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38603 status = wuffs_png__decoder__decode_srgb(self, a_src);
38604 if (a_src) {
38605 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38606 }
38607 if (status.repr) {
38608 goto suspend;
38609 }
38610 self->private_impl.f_seen_srgb = true;
38611 }
38612 } else if (self->private_impl.f_chunk_type == 1397641844) {
38613 if (self->private_impl.f_seen_trns || (self->private_impl.f_color_type > 3) || ((self->private_impl.f_color_type == 3) && ! self->private_impl.f_seen_plte)) {
38614 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38615 goto exit;
38616 }
38617 if (a_src) {
38618 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38619 }
38620 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38621 status = wuffs_png__decoder__decode_trns(self, a_src);
38622 if (a_src) {
38623 iop_a_src = a_src->data.ptr + a_src->meta.ri;
38624 }
38625 if (status.repr) {
38626 goto suspend;
38627 }
38628 self->private_impl.f_seen_trns = true;
38629 } else if ((self->private_impl.f_chunk_type == 1951945833) || (self->private_impl.f_chunk_type == 1951942004) || (self->private_impl.f_chunk_type == 1951945850)) {
38630 if (self->private_impl.f_report_metadata_kvp) {
38631 self->private_impl.f_metadata_flavor = 4;
38632 self->private_impl.f_metadata_fourcc = 1263947851;
38633 self->private_impl.f_metadata_x = 0;
38634 self->private_impl.f_metadata_y = 0;
38635 self->private_impl.f_metadata_z = 0;
38636 }
38637 }
38638 if (self->private_impl.f_metadata_fourcc == 0) {
38639 self->private_data.s_decode_other_chunk[0].scratch = self->private_impl.f_chunk_length;
38640 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
38641 if (self->private_data.s_decode_other_chunk[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
38642 self->private_data.s_decode_other_chunk[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
38643 iop_a_src = io2_a_src;
38644 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38645 goto suspend;
38646 }
38647 iop_a_src += self->private_data.s_decode_other_chunk[0].scratch;
38648 }
38649
38650 goto ok;
38651 ok:
38652 self->private_impl.p_decode_other_chunk[0] = 0;
38653 goto exit;
38654 }
38655
38656 goto suspend;
38657 suspend:
38658 self->private_impl.p_decode_other_chunk[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38659
38660 goto exit;
38661 exit:
38662 if (a_src) {
38663 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38664 }
38665
38666 return status;
38667 }
38668
38669 // -------- func png.decoder.decode_actl
38670
38671 static wuffs_base__status
wuffs_png__decoder__decode_actl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38672 wuffs_png__decoder__decode_actl(
38673 wuffs_png__decoder* self,
38674 wuffs_base__io_buffer* a_src) {
38675 wuffs_base__status status = wuffs_base__make_status(NULL);
38676
38677 const uint8_t* iop_a_src = NULL;
38678 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38679 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38680 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38681 if (a_src) {
38682 io0_a_src = a_src->data.ptr;
38683 io1_a_src = io0_a_src + a_src->meta.ri;
38684 iop_a_src = io1_a_src;
38685 io2_a_src = io0_a_src + a_src->meta.wi;
38686 }
38687
38688 uint32_t coro_susp_point = self->private_impl.p_decode_actl[0];
38689 switch (coro_susp_point) {
38690 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38691
38692 if (self->private_impl.f_chunk_length != 8) {
38693 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38694 goto exit;
38695 } else if (self->private_impl.f_interlace_pass > 0) {
38696 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
38697 goto exit;
38698 }
38699 self->private_impl.f_chunk_length = 0;
38700 {
38701 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38702 uint32_t t_0;
38703 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38704 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38705 iop_a_src += 4;
38706 } else {
38707 self->private_data.s_decode_actl[0].scratch = 0;
38708 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38709 while (true) {
38710 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38711 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38712 goto suspend;
38713 }
38714 uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
38715 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38716 *scratch >>= 8;
38717 *scratch <<= 8;
38718 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38719 if (num_bits_0 == 24) {
38720 t_0 = ((uint32_t)(*scratch >> 32));
38721 break;
38722 }
38723 num_bits_0 += 8;
38724 *scratch |= ((uint64_t)(num_bits_0));
38725 }
38726 }
38727 self->private_impl.f_num_animation_frames_value = t_0;
38728 }
38729 if (self->private_impl.f_num_animation_frames_value == 0) {
38730 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38731 goto exit;
38732 }
38733 {
38734 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38735 uint32_t t_1;
38736 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38737 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
38738 iop_a_src += 4;
38739 } else {
38740 self->private_data.s_decode_actl[0].scratch = 0;
38741 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38742 while (true) {
38743 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38744 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38745 goto suspend;
38746 }
38747 uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
38748 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38749 *scratch >>= 8;
38750 *scratch <<= 8;
38751 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38752 if (num_bits_1 == 24) {
38753 t_1 = ((uint32_t)(*scratch >> 32));
38754 break;
38755 }
38756 num_bits_1 += 8;
38757 *scratch |= ((uint64_t)(num_bits_1));
38758 }
38759 }
38760 self->private_impl.f_num_animation_loops_value = t_1;
38761 }
38762
38763 goto ok;
38764 ok:
38765 self->private_impl.p_decode_actl[0] = 0;
38766 goto exit;
38767 }
38768
38769 goto suspend;
38770 suspend:
38771 self->private_impl.p_decode_actl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
38772
38773 goto exit;
38774 exit:
38775 if (a_src) {
38776 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
38777 }
38778
38779 return status;
38780 }
38781
38782 // -------- func png.decoder.decode_chrm
38783
38784 static wuffs_base__status
wuffs_png__decoder__decode_chrm(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)38785 wuffs_png__decoder__decode_chrm(
38786 wuffs_png__decoder* self,
38787 wuffs_base__io_buffer* a_src) {
38788 wuffs_base__status status = wuffs_base__make_status(NULL);
38789
38790 uint64_t v_u = 0;
38791
38792 const uint8_t* iop_a_src = NULL;
38793 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38794 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38795 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
38796 if (a_src) {
38797 io0_a_src = a_src->data.ptr;
38798 io1_a_src = io0_a_src + a_src->meta.ri;
38799 iop_a_src = io1_a_src;
38800 io2_a_src = io0_a_src + a_src->meta.wi;
38801 }
38802
38803 uint32_t coro_susp_point = self->private_impl.p_decode_chrm[0];
38804 switch (coro_susp_point) {
38805 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
38806
38807 if (self->private_impl.f_chunk_length != 32) {
38808 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
38809 goto exit;
38810 }
38811 self->private_impl.f_chunk_length = 0;
38812 self->private_impl.f_metadata_flavor = 5;
38813 self->private_impl.f_metadata_fourcc = 1128813133;
38814 self->private_impl.f_metadata_x = 0;
38815 self->private_impl.f_metadata_y = 0;
38816 self->private_impl.f_metadata_z = 0;
38817 {
38818 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
38819 uint64_t t_0;
38820 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38821 t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38822 iop_a_src += 4;
38823 } else {
38824 self->private_data.s_decode_chrm[0].scratch = 0;
38825 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
38826 while (true) {
38827 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38828 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38829 goto suspend;
38830 }
38831 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38832 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
38833 *scratch >>= 8;
38834 *scratch <<= 8;
38835 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
38836 if (num_bits_0 == 24) {
38837 t_0 = ((uint64_t)(*scratch >> 32));
38838 break;
38839 }
38840 num_bits_0 += 8;
38841 *scratch |= ((uint64_t)(num_bits_0));
38842 }
38843 }
38844 v_u = t_0;
38845 }
38846 self->private_impl.f_metadata_x |= ((16777215 & v_u) << 0);
38847 {
38848 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
38849 uint64_t t_1;
38850 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38851 t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38852 iop_a_src += 4;
38853 } else {
38854 self->private_data.s_decode_chrm[0].scratch = 0;
38855 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
38856 while (true) {
38857 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38858 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38859 goto suspend;
38860 }
38861 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38862 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
38863 *scratch >>= 8;
38864 *scratch <<= 8;
38865 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
38866 if (num_bits_1 == 24) {
38867 t_1 = ((uint64_t)(*scratch >> 32));
38868 break;
38869 }
38870 num_bits_1 += 8;
38871 *scratch |= ((uint64_t)(num_bits_1));
38872 }
38873 }
38874 v_u = t_1;
38875 }
38876 self->private_impl.f_metadata_x |= ((16777215 & v_u) << 24);
38877 {
38878 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
38879 uint64_t t_2;
38880 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38881 t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38882 iop_a_src += 4;
38883 } else {
38884 self->private_data.s_decode_chrm[0].scratch = 0;
38885 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
38886 while (true) {
38887 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38888 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38889 goto suspend;
38890 }
38891 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38892 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
38893 *scratch >>= 8;
38894 *scratch <<= 8;
38895 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
38896 if (num_bits_2 == 24) {
38897 t_2 = ((uint64_t)(*scratch >> 32));
38898 break;
38899 }
38900 num_bits_2 += 8;
38901 *scratch |= ((uint64_t)(num_bits_2));
38902 }
38903 }
38904 v_u = t_2;
38905 }
38906 self->private_impl.f_metadata_x |= ((uint64_t)((16777215 & v_u) << 48));
38907 self->private_impl.f_metadata_y |= ((16777215 & v_u) >> 16);
38908 {
38909 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
38910 uint64_t t_3;
38911 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38912 t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38913 iop_a_src += 4;
38914 } else {
38915 self->private_data.s_decode_chrm[0].scratch = 0;
38916 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
38917 while (true) {
38918 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38919 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38920 goto suspend;
38921 }
38922 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38923 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
38924 *scratch >>= 8;
38925 *scratch <<= 8;
38926 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
38927 if (num_bits_3 == 24) {
38928 t_3 = ((uint64_t)(*scratch >> 32));
38929 break;
38930 }
38931 num_bits_3 += 8;
38932 *scratch |= ((uint64_t)(num_bits_3));
38933 }
38934 }
38935 v_u = t_3;
38936 }
38937 self->private_impl.f_metadata_y |= ((16777215 & v_u) << 8);
38938 {
38939 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
38940 uint64_t t_4;
38941 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38942 t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38943 iop_a_src += 4;
38944 } else {
38945 self->private_data.s_decode_chrm[0].scratch = 0;
38946 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
38947 while (true) {
38948 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38949 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38950 goto suspend;
38951 }
38952 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38953 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
38954 *scratch >>= 8;
38955 *scratch <<= 8;
38956 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
38957 if (num_bits_4 == 24) {
38958 t_4 = ((uint64_t)(*scratch >> 32));
38959 break;
38960 }
38961 num_bits_4 += 8;
38962 *scratch |= ((uint64_t)(num_bits_4));
38963 }
38964 }
38965 v_u = t_4;
38966 }
38967 self->private_impl.f_metadata_y |= ((16777215 & v_u) << 32);
38968 {
38969 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
38970 uint64_t t_5;
38971 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
38972 t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
38973 iop_a_src += 4;
38974 } else {
38975 self->private_data.s_decode_chrm[0].scratch = 0;
38976 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
38977 while (true) {
38978 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
38979 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
38980 goto suspend;
38981 }
38982 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
38983 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
38984 *scratch >>= 8;
38985 *scratch <<= 8;
38986 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
38987 if (num_bits_5 == 24) {
38988 t_5 = ((uint64_t)(*scratch >> 32));
38989 break;
38990 }
38991 num_bits_5 += 8;
38992 *scratch |= ((uint64_t)(num_bits_5));
38993 }
38994 }
38995 v_u = t_5;
38996 }
38997 self->private_impl.f_metadata_y |= ((uint64_t)((16777215 & v_u) << 56));
38998 self->private_impl.f_metadata_z |= ((16777215 & v_u) >> 8);
38999 {
39000 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
39001 uint64_t t_6;
39002 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39003 t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
39004 iop_a_src += 4;
39005 } else {
39006 self->private_data.s_decode_chrm[0].scratch = 0;
39007 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
39008 while (true) {
39009 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39010 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39011 goto suspend;
39012 }
39013 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
39014 uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFF));
39015 *scratch >>= 8;
39016 *scratch <<= 8;
39017 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
39018 if (num_bits_6 == 24) {
39019 t_6 = ((uint64_t)(*scratch >> 32));
39020 break;
39021 }
39022 num_bits_6 += 8;
39023 *scratch |= ((uint64_t)(num_bits_6));
39024 }
39025 }
39026 v_u = t_6;
39027 }
39028 self->private_impl.f_metadata_z |= ((16777215 & v_u) << 16);
39029 {
39030 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
39031 uint64_t t_7;
39032 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39033 t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
39034 iop_a_src += 4;
39035 } else {
39036 self->private_data.s_decode_chrm[0].scratch = 0;
39037 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
39038 while (true) {
39039 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39040 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39041 goto suspend;
39042 }
39043 uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
39044 uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFF));
39045 *scratch >>= 8;
39046 *scratch <<= 8;
39047 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7);
39048 if (num_bits_7 == 24) {
39049 t_7 = ((uint64_t)(*scratch >> 32));
39050 break;
39051 }
39052 num_bits_7 += 8;
39053 *scratch |= ((uint64_t)(num_bits_7));
39054 }
39055 }
39056 v_u = t_7;
39057 }
39058 self->private_impl.f_metadata_z |= ((16777215 & v_u) << 40);
39059
39060 goto ok;
39061 ok:
39062 self->private_impl.p_decode_chrm[0] = 0;
39063 goto exit;
39064 }
39065
39066 goto suspend;
39067 suspend:
39068 self->private_impl.p_decode_chrm[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39069
39070 goto exit;
39071 exit:
39072 if (a_src) {
39073 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39074 }
39075
39076 return status;
39077 }
39078
39079 // -------- func png.decoder.decode_exif
39080
39081 static wuffs_base__status
wuffs_png__decoder__decode_exif(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39082 wuffs_png__decoder__decode_exif(
39083 wuffs_png__decoder* self,
39084 wuffs_base__io_buffer* a_src) {
39085 wuffs_base__status status = wuffs_base__make_status(NULL);
39086
39087 const uint8_t* iop_a_src = NULL;
39088 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39089 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39090 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39091 if (a_src) {
39092 io0_a_src = a_src->data.ptr;
39093 io1_a_src = io0_a_src + a_src->meta.ri;
39094 iop_a_src = io1_a_src;
39095 io2_a_src = io0_a_src + a_src->meta.wi;
39096 }
39097
39098 if (self->private_impl.f_chunk_length < 4) {
39099 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39100 goto exit;
39101 }
39102 self->private_impl.f_metadata_flavor = 3;
39103 self->private_impl.f_metadata_fourcc = 1163413830;
39104 self->private_impl.f_metadata_x = 0;
39105 self->private_impl.f_metadata_y = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
39106 self->private_impl.f_metadata_z = wuffs_base__u64__sat_add(self->private_impl.f_metadata_y, ((uint64_t)(self->private_impl.f_chunk_length)));
39107 self->private_impl.f_chunk_length = 0;
39108
39109 goto ok;
39110 ok:
39111 goto exit;
39112 exit:
39113 if (a_src) {
39114 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39115 }
39116
39117 return status;
39118 }
39119
39120 // -------- func png.decoder.decode_fctl
39121
39122 static wuffs_base__status
wuffs_png__decoder__decode_fctl(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39123 wuffs_png__decoder__decode_fctl(
39124 wuffs_png__decoder* self,
39125 wuffs_base__io_buffer* a_src) {
39126 wuffs_base__status status = wuffs_base__make_status(NULL);
39127
39128 uint32_t v_x0 = 0;
39129 uint32_t v_y0 = 0;
39130 uint32_t v_x1 = 0;
39131 uint32_t v_y1 = 0;
39132
39133 const uint8_t* iop_a_src = NULL;
39134 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39135 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39136 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39137 if (a_src) {
39138 io0_a_src = a_src->data.ptr;
39139 io1_a_src = io0_a_src + a_src->meta.ri;
39140 iop_a_src = io1_a_src;
39141 io2_a_src = io0_a_src + a_src->meta.wi;
39142 }
39143
39144 uint32_t coro_susp_point = self->private_impl.p_decode_fctl[0];
39145 if (coro_susp_point) {
39146 v_x0 = self->private_data.s_decode_fctl[0].v_x0;
39147 v_x1 = self->private_data.s_decode_fctl[0].v_x1;
39148 v_y1 = self->private_data.s_decode_fctl[0].v_y1;
39149 }
39150 switch (coro_susp_point) {
39151 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39152
39153 if (self->private_impl.f_chunk_length != 26) {
39154 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39155 goto exit;
39156 }
39157 self->private_impl.f_chunk_length = 0;
39158 {
39159 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39160 uint32_t t_0;
39161 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39162 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39163 iop_a_src += 4;
39164 } else {
39165 self->private_data.s_decode_fctl[0].scratch = 0;
39166 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39167 while (true) {
39168 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39169 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39170 goto suspend;
39171 }
39172 uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39173 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39174 *scratch >>= 8;
39175 *scratch <<= 8;
39176 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39177 if (num_bits_0 == 24) {
39178 t_0 = ((uint32_t)(*scratch >> 32));
39179 break;
39180 }
39181 num_bits_0 += 8;
39182 *scratch |= ((uint64_t)(num_bits_0));
39183 }
39184 }
39185 v_x0 = t_0;
39186 }
39187 if (v_x0 != self->private_impl.f_next_animation_seq_num) {
39188 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
39189 goto exit;
39190 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
39191 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
39192 goto exit;
39193 }
39194 self->private_impl.f_next_animation_seq_num += 1;
39195 {
39196 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39197 uint32_t t_1;
39198 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39199 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39200 iop_a_src += 4;
39201 } else {
39202 self->private_data.s_decode_fctl[0].scratch = 0;
39203 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39204 while (true) {
39205 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39206 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39207 goto suspend;
39208 }
39209 uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39210 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
39211 *scratch >>= 8;
39212 *scratch <<= 8;
39213 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
39214 if (num_bits_1 == 24) {
39215 t_1 = ((uint32_t)(*scratch >> 32));
39216 break;
39217 }
39218 num_bits_1 += 8;
39219 *scratch |= ((uint64_t)(num_bits_1));
39220 }
39221 }
39222 v_x1 = t_1;
39223 }
39224 {
39225 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39226 uint32_t t_2;
39227 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39228 t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39229 iop_a_src += 4;
39230 } else {
39231 self->private_data.s_decode_fctl[0].scratch = 0;
39232 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
39233 while (true) {
39234 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39235 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39236 goto suspend;
39237 }
39238 uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39239 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
39240 *scratch >>= 8;
39241 *scratch <<= 8;
39242 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
39243 if (num_bits_2 == 24) {
39244 t_2 = ((uint32_t)(*scratch >> 32));
39245 break;
39246 }
39247 num_bits_2 += 8;
39248 *scratch |= ((uint64_t)(num_bits_2));
39249 }
39250 }
39251 v_y1 = t_2;
39252 }
39253 {
39254 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
39255 uint32_t t_3;
39256 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39257 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39258 iop_a_src += 4;
39259 } else {
39260 self->private_data.s_decode_fctl[0].scratch = 0;
39261 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
39262 while (true) {
39263 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39264 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39265 goto suspend;
39266 }
39267 uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39268 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
39269 *scratch >>= 8;
39270 *scratch <<= 8;
39271 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
39272 if (num_bits_3 == 24) {
39273 t_3 = ((uint32_t)(*scratch >> 32));
39274 break;
39275 }
39276 num_bits_3 += 8;
39277 *scratch |= ((uint64_t)(num_bits_3));
39278 }
39279 }
39280 v_x0 = t_3;
39281 }
39282 {
39283 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
39284 uint32_t t_4;
39285 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39286 t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
39287 iop_a_src += 4;
39288 } else {
39289 self->private_data.s_decode_fctl[0].scratch = 0;
39290 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
39291 while (true) {
39292 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39293 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39294 goto suspend;
39295 }
39296 uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39297 uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFF));
39298 *scratch >>= 8;
39299 *scratch <<= 8;
39300 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
39301 if (num_bits_4 == 24) {
39302 t_4 = ((uint32_t)(*scratch >> 32));
39303 break;
39304 }
39305 num_bits_4 += 8;
39306 *scratch |= ((uint64_t)(num_bits_4));
39307 }
39308 }
39309 v_y0 = t_4;
39310 }
39311 v_x1 += v_x0;
39312 v_y1 += v_y0;
39313 if ((v_x0 >= v_x1) ||
39314 (v_x0 > self->private_impl.f_width) ||
39315 (v_x1 > self->private_impl.f_width) ||
39316 (v_y0 >= v_y1) ||
39317 (v_y0 > self->private_impl.f_height) ||
39318 (v_y1 > self->private_impl.f_height)) {
39319 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39320 goto exit;
39321 }
39322 self->private_impl.f_frame_rect_x0 = v_x0;
39323 self->private_impl.f_frame_rect_y0 = v_y0;
39324 self->private_impl.f_frame_rect_x1 = v_x1;
39325 self->private_impl.f_frame_rect_y1 = v_y1;
39326 {
39327 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
39328 uint32_t t_5;
39329 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39330 t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
39331 iop_a_src += 2;
39332 } else {
39333 self->private_data.s_decode_fctl[0].scratch = 0;
39334 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
39335 while (true) {
39336 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39337 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39338 goto suspend;
39339 }
39340 uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39341 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
39342 *scratch >>= 8;
39343 *scratch <<= 8;
39344 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
39345 if (num_bits_5 == 8) {
39346 t_5 = ((uint32_t)(*scratch >> 48));
39347 break;
39348 }
39349 num_bits_5 += 8;
39350 *scratch |= ((uint64_t)(num_bits_5));
39351 }
39352 }
39353 v_x0 = t_5;
39354 }
39355 {
39356 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
39357 uint32_t t_6;
39358 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39359 t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
39360 iop_a_src += 2;
39361 } else {
39362 self->private_data.s_decode_fctl[0].scratch = 0;
39363 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
39364 while (true) {
39365 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39366 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39367 goto suspend;
39368 }
39369 uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
39370 uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFF));
39371 *scratch >>= 8;
39372 *scratch <<= 8;
39373 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
39374 if (num_bits_6 == 8) {
39375 t_6 = ((uint32_t)(*scratch >> 48));
39376 break;
39377 }
39378 num_bits_6 += 8;
39379 *scratch |= ((uint64_t)(num_bits_6));
39380 }
39381 }
39382 v_x1 = t_6;
39383 }
39384 if (v_x1 <= 0) {
39385 self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000);
39386 } else {
39387 self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000) / ((uint64_t)(v_x1)));
39388 }
39389 {
39390 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
39391 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39392 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39393 goto suspend;
39394 }
39395 uint32_t t_7 = *iop_a_src++;
39396 v_x0 = t_7;
39397 }
39398 if (v_x0 == 0) {
39399 self->private_impl.f_frame_disposal = 0;
39400 } else if (v_x0 == 1) {
39401 self->private_impl.f_frame_disposal = 1;
39402 } else if (v_x0 == 2) {
39403 self->private_impl.f_frame_disposal = 2;
39404 } else {
39405 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39406 goto exit;
39407 }
39408 {
39409 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
39410 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39411 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39412 goto suspend;
39413 }
39414 uint32_t t_8 = *iop_a_src++;
39415 v_x0 = t_8;
39416 }
39417 if (v_x0 == 0) {
39418 self->private_impl.f_frame_overwrite_instead_of_blend = true;
39419 } else if (v_x0 == 1) {
39420 self->private_impl.f_frame_overwrite_instead_of_blend = false;
39421 } else {
39422 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39423 goto exit;
39424 }
39425 if (self->private_impl.f_num_decoded_frame_configs_value == 0) {
39426 self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0;
39427 self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0;
39428 self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1;
39429 self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1;
39430 self->private_impl.f_first_duration = self->private_impl.f_frame_duration;
39431 self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal;
39432 self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend;
39433 }
39434
39435 goto ok;
39436 ok:
39437 self->private_impl.p_decode_fctl[0] = 0;
39438 goto exit;
39439 }
39440
39441 goto suspend;
39442 suspend:
39443 self->private_impl.p_decode_fctl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39444 self->private_data.s_decode_fctl[0].v_x0 = v_x0;
39445 self->private_data.s_decode_fctl[0].v_x1 = v_x1;
39446 self->private_data.s_decode_fctl[0].v_y1 = v_y1;
39447
39448 goto exit;
39449 exit:
39450 if (a_src) {
39451 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39452 }
39453
39454 return status;
39455 }
39456
39457 // -------- func png.decoder.decode_gama
39458
39459 static wuffs_base__status
wuffs_png__decoder__decode_gama(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39460 wuffs_png__decoder__decode_gama(
39461 wuffs_png__decoder* self,
39462 wuffs_base__io_buffer* a_src) {
39463 wuffs_base__status status = wuffs_base__make_status(NULL);
39464
39465 const uint8_t* iop_a_src = NULL;
39466 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39467 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39468 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39469 if (a_src) {
39470 io0_a_src = a_src->data.ptr;
39471 io1_a_src = io0_a_src + a_src->meta.ri;
39472 iop_a_src = io1_a_src;
39473 io2_a_src = io0_a_src + a_src->meta.wi;
39474 }
39475
39476 uint32_t coro_susp_point = self->private_impl.p_decode_gama[0];
39477 switch (coro_susp_point) {
39478 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39479
39480 if (self->private_impl.f_chunk_length != 4) {
39481 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39482 goto exit;
39483 }
39484 self->private_impl.f_chunk_length = 0;
39485 self->private_impl.f_metadata_flavor = 5;
39486 self->private_impl.f_metadata_fourcc = 1195461953;
39487 {
39488 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39489 uint64_t t_0;
39490 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
39491 t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
39492 iop_a_src += 4;
39493 } else {
39494 self->private_data.s_decode_gama[0].scratch = 0;
39495 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39496 while (true) {
39497 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39498 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39499 goto suspend;
39500 }
39501 uint64_t* scratch = &self->private_data.s_decode_gama[0].scratch;
39502 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39503 *scratch >>= 8;
39504 *scratch <<= 8;
39505 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39506 if (num_bits_0 == 24) {
39507 t_0 = ((uint64_t)(*scratch >> 32));
39508 break;
39509 }
39510 num_bits_0 += 8;
39511 *scratch |= ((uint64_t)(num_bits_0));
39512 }
39513 }
39514 self->private_impl.f_metadata_x = t_0;
39515 }
39516 self->private_impl.f_metadata_y = 0;
39517 self->private_impl.f_metadata_z = 0;
39518
39519 goto ok;
39520 ok:
39521 self->private_impl.p_decode_gama[0] = 0;
39522 goto exit;
39523 }
39524
39525 goto suspend;
39526 suspend:
39527 self->private_impl.p_decode_gama[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39528
39529 goto exit;
39530 exit:
39531 if (a_src) {
39532 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39533 }
39534
39535 return status;
39536 }
39537
39538 // -------- func png.decoder.decode_iccp
39539
39540 static wuffs_base__status
wuffs_png__decoder__decode_iccp(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39541 wuffs_png__decoder__decode_iccp(
39542 wuffs_png__decoder* self,
39543 wuffs_base__io_buffer* a_src) {
39544 wuffs_base__status status = wuffs_base__make_status(NULL);
39545
39546 uint8_t v_c = 0;
39547
39548 const uint8_t* iop_a_src = NULL;
39549 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39550 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39551 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39552 if (a_src) {
39553 io0_a_src = a_src->data.ptr;
39554 io1_a_src = io0_a_src + a_src->meta.ri;
39555 iop_a_src = io1_a_src;
39556 io2_a_src = io0_a_src + a_src->meta.wi;
39557 }
39558
39559 uint32_t coro_susp_point = self->private_impl.p_decode_iccp[0];
39560 switch (coro_susp_point) {
39561 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39562
39563 while (true) {
39564 if (self->private_impl.f_chunk_length <= 0) {
39565 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39566 goto exit;
39567 }
39568 self->private_impl.f_chunk_length -= 1;
39569 {
39570 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39571 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39572 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39573 goto suspend;
39574 }
39575 uint8_t t_0 = *iop_a_src++;
39576 v_c = t_0;
39577 }
39578 if (v_c == 0) {
39579 goto label__0__break;
39580 }
39581 }
39582 label__0__break:;
39583 if (self->private_impl.f_chunk_length <= 0) {
39584 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39585 goto exit;
39586 }
39587 self->private_impl.f_chunk_length -= 1;
39588 {
39589 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39590 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39591 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39592 goto suspend;
39593 }
39594 uint8_t t_1 = *iop_a_src++;
39595 v_c = t_1;
39596 }
39597 if (v_c != 0) {
39598 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
39599 goto exit;
39600 }
39601 self->private_impl.f_metadata_is_zlib_compressed = true;
39602 self->private_impl.f_metadata_flavor = 4;
39603 self->private_impl.f_metadata_fourcc = 1229144912;
39604 self->private_impl.f_metadata_x = 0;
39605 self->private_impl.f_metadata_y = 0;
39606 self->private_impl.f_metadata_z = 0;
39607
39608 goto ok;
39609 ok:
39610 self->private_impl.p_decode_iccp[0] = 0;
39611 goto exit;
39612 }
39613
39614 goto suspend;
39615 suspend:
39616 self->private_impl.p_decode_iccp[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39617
39618 goto exit;
39619 exit:
39620 if (a_src) {
39621 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39622 }
39623
39624 return status;
39625 }
39626
39627 // -------- func png.decoder.decode_plte
39628
39629 static wuffs_base__status
wuffs_png__decoder__decode_plte(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39630 wuffs_png__decoder__decode_plte(
39631 wuffs_png__decoder* self,
39632 wuffs_base__io_buffer* a_src) {
39633 wuffs_base__status status = wuffs_base__make_status(NULL);
39634
39635 uint32_t v_num_entries = 0;
39636 uint32_t v_i = 0;
39637 uint32_t v_argb = 0;
39638
39639 const uint8_t* iop_a_src = NULL;
39640 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39641 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39642 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39643 if (a_src) {
39644 io0_a_src = a_src->data.ptr;
39645 io1_a_src = io0_a_src + a_src->meta.ri;
39646 iop_a_src = io1_a_src;
39647 io2_a_src = io0_a_src + a_src->meta.wi;
39648 }
39649
39650 uint32_t coro_susp_point = self->private_impl.p_decode_plte[0];
39651 if (coro_susp_point) {
39652 v_num_entries = self->private_data.s_decode_plte[0].v_num_entries;
39653 v_i = self->private_data.s_decode_plte[0].v_i;
39654 }
39655 switch (coro_susp_point) {
39656 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39657
39658 if ((self->private_impl.f_chunk_length > 768) || ((self->private_impl.f_chunk_length % 3) != 0)) {
39659 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39660 goto exit;
39661 }
39662 v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3);
39663 self->private_impl.f_chunk_length = 0;
39664 while (v_i < v_num_entries) {
39665 {
39666 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39667 uint32_t t_0;
39668 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
39669 t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
39670 iop_a_src += 3;
39671 } else {
39672 self->private_data.s_decode_plte[0].scratch = 0;
39673 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39674 while (true) {
39675 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39676 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39677 goto suspend;
39678 }
39679 uint64_t* scratch = &self->private_data.s_decode_plte[0].scratch;
39680 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39681 *scratch >>= 8;
39682 *scratch <<= 8;
39683 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39684 if (num_bits_0 == 16) {
39685 t_0 = ((uint32_t)(*scratch >> 40));
39686 break;
39687 }
39688 num_bits_0 += 8;
39689 *scratch |= ((uint64_t)(num_bits_0));
39690 }
39691 }
39692 v_argb = t_0;
39693 }
39694 v_argb |= 4278190080;
39695 self->private_data.f_src_palette[((4 * v_i) + 0)] = ((uint8_t)(((v_argb >> 0) & 255)));
39696 self->private_data.f_src_palette[((4 * v_i) + 1)] = ((uint8_t)(((v_argb >> 8) & 255)));
39697 self->private_data.f_src_palette[((4 * v_i) + 2)] = ((uint8_t)(((v_argb >> 16) & 255)));
39698 self->private_data.f_src_palette[((4 * v_i) + 3)] = ((uint8_t)(((v_argb >> 24) & 255)));
39699 v_i += 1;
39700 }
39701 while (v_i < 256) {
39702 self->private_data.f_src_palette[((4 * v_i) + 0)] = 0;
39703 self->private_data.f_src_palette[((4 * v_i) + 1)] = 0;
39704 self->private_data.f_src_palette[((4 * v_i) + 2)] = 0;
39705 self->private_data.f_src_palette[((4 * v_i) + 3)] = 255;
39706 v_i += 1;
39707 }
39708
39709 goto ok;
39710 ok:
39711 self->private_impl.p_decode_plte[0] = 0;
39712 goto exit;
39713 }
39714
39715 goto suspend;
39716 suspend:
39717 self->private_impl.p_decode_plte[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39718 self->private_data.s_decode_plte[0].v_num_entries = v_num_entries;
39719 self->private_data.s_decode_plte[0].v_i = v_i;
39720
39721 goto exit;
39722 exit:
39723 if (a_src) {
39724 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39725 }
39726
39727 return status;
39728 }
39729
39730 // -------- func png.decoder.decode_srgb
39731
39732 static wuffs_base__status
wuffs_png__decoder__decode_srgb(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39733 wuffs_png__decoder__decode_srgb(
39734 wuffs_png__decoder* self,
39735 wuffs_base__io_buffer* a_src) {
39736 wuffs_base__status status = wuffs_base__make_status(NULL);
39737
39738 const uint8_t* iop_a_src = NULL;
39739 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39740 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39741 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39742 if (a_src) {
39743 io0_a_src = a_src->data.ptr;
39744 io1_a_src = io0_a_src + a_src->meta.ri;
39745 iop_a_src = io1_a_src;
39746 io2_a_src = io0_a_src + a_src->meta.wi;
39747 }
39748
39749 uint32_t coro_susp_point = self->private_impl.p_decode_srgb[0];
39750 switch (coro_susp_point) {
39751 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39752
39753 if (self->private_impl.f_chunk_length != 1) {
39754 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39755 goto exit;
39756 }
39757 self->private_impl.f_chunk_length = 0;
39758 self->private_impl.f_metadata_flavor = 5;
39759 self->private_impl.f_metadata_fourcc = 1397901122;
39760 {
39761 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39762 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39763 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39764 goto suspend;
39765 }
39766 uint64_t t_0 = *iop_a_src++;
39767 self->private_impl.f_metadata_x = t_0;
39768 }
39769 self->private_impl.f_metadata_y = 0;
39770 self->private_impl.f_metadata_z = 0;
39771
39772 goto ok;
39773 ok:
39774 self->private_impl.p_decode_srgb[0] = 0;
39775 goto exit;
39776 }
39777
39778 goto suspend;
39779 suspend:
39780 self->private_impl.p_decode_srgb[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39781
39782 goto exit;
39783 exit:
39784 if (a_src) {
39785 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39786 }
39787
39788 return status;
39789 }
39790
39791 // -------- func png.decoder.decode_trns
39792
39793 static wuffs_base__status
wuffs_png__decoder__decode_trns(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)39794 wuffs_png__decoder__decode_trns(
39795 wuffs_png__decoder* self,
39796 wuffs_base__io_buffer* a_src) {
39797 wuffs_base__status status = wuffs_base__make_status(NULL);
39798
39799 uint32_t v_i = 0;
39800 uint32_t v_n = 0;
39801 uint64_t v_u = 0;
39802
39803 const uint8_t* iop_a_src = NULL;
39804 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39805 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39806 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
39807 if (a_src) {
39808 io0_a_src = a_src->data.ptr;
39809 io1_a_src = io0_a_src + a_src->meta.ri;
39810 iop_a_src = io1_a_src;
39811 io2_a_src = io0_a_src + a_src->meta.wi;
39812 }
39813
39814 uint32_t coro_susp_point = self->private_impl.p_decode_trns[0];
39815 if (coro_susp_point) {
39816 v_i = self->private_data.s_decode_trns[0].v_i;
39817 v_n = self->private_data.s_decode_trns[0].v_n;
39818 }
39819 switch (coro_susp_point) {
39820 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
39821
39822 if (self->private_impl.f_color_type == 0) {
39823 self->private_impl.choosy_filter_and_swizzle = (
39824 &wuffs_png__decoder__filter_and_swizzle_tricky);
39825 if (self->private_impl.f_depth <= 8) {
39826 self->private_impl.f_dst_pixfmt = 2164295816;
39827 self->private_impl.f_src_pixfmt = 2164295816;
39828 } else {
39829 self->private_impl.f_dst_pixfmt = 2164308923;
39830 self->private_impl.f_src_pixfmt = 2164308923;
39831 }
39832 if (self->private_impl.f_chunk_length != 2) {
39833 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39834 goto exit;
39835 }
39836 self->private_impl.f_chunk_length = 0;
39837 {
39838 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
39839 uint64_t t_0;
39840 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
39841 t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
39842 iop_a_src += 2;
39843 } else {
39844 self->private_data.s_decode_trns[0].scratch = 0;
39845 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
39846 while (true) {
39847 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39848 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39849 goto suspend;
39850 }
39851 uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
39852 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
39853 *scratch >>= 8;
39854 *scratch <<= 8;
39855 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
39856 if (num_bits_0 == 8) {
39857 t_0 = ((uint64_t)(*scratch >> 48));
39858 break;
39859 }
39860 num_bits_0 += 8;
39861 *scratch |= ((uint64_t)(num_bits_0));
39862 }
39863 }
39864 v_u = t_0;
39865 }
39866 if (self->private_impl.f_depth <= 1) {
39867 self->private_impl.f_remap_transparency = (((v_u & 1) * 16777215) | 4278190080);
39868 } else if (self->private_impl.f_depth <= 2) {
39869 self->private_impl.f_remap_transparency = (((v_u & 3) * 5592405) | 4278190080);
39870 } else if (self->private_impl.f_depth <= 4) {
39871 self->private_impl.f_remap_transparency = (((v_u & 15) * 1118481) | 4278190080);
39872 } else if (self->private_impl.f_depth <= 8) {
39873 self->private_impl.f_remap_transparency = (((v_u & 255) * 65793) | 4278190080);
39874 } else {
39875 self->private_impl.f_remap_transparency = ((v_u * 4295032833) | 18446462598732840960u);
39876 }
39877 } else if (self->private_impl.f_color_type == 2) {
39878 self->private_impl.choosy_filter_and_swizzle = (
39879 &wuffs_png__decoder__filter_and_swizzle_tricky);
39880 if (self->private_impl.f_depth <= 8) {
39881 self->private_impl.f_dst_pixfmt = 2164295816;
39882 self->private_impl.f_src_pixfmt = 2164295816;
39883 } else {
39884 self->private_impl.f_dst_pixfmt = 2164308923;
39885 self->private_impl.f_src_pixfmt = 2164308923;
39886 }
39887 if (self->private_impl.f_chunk_length != 6) {
39888 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39889 goto exit;
39890 }
39891 self->private_impl.f_chunk_length = 0;
39892 {
39893 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
39894 uint64_t t_1;
39895 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
39896 t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src)));
39897 iop_a_src += 6;
39898 } else {
39899 self->private_data.s_decode_trns[0].scratch = 0;
39900 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
39901 while (true) {
39902 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39903 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39904 goto suspend;
39905 }
39906 uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
39907 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
39908 *scratch >>= 8;
39909 *scratch <<= 8;
39910 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
39911 if (num_bits_1 == 40) {
39912 t_1 = ((uint64_t)(*scratch >> 16));
39913 break;
39914 }
39915 num_bits_1 += 8;
39916 *scratch |= ((uint64_t)(num_bits_1));
39917 }
39918 }
39919 v_u = t_1;
39920 }
39921 if (self->private_impl.f_depth <= 8) {
39922 self->private_impl.f_remap_transparency = ((255 & (v_u >> 0)) |
39923 (65280 & (v_u >> 8)) |
39924 (16711680 & (v_u >> 16)) |
39925 4278190080);
39926 } else {
39927 self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u);
39928 }
39929 } else if (self->private_impl.f_color_type == 3) {
39930 self->private_impl.f_dst_pixfmt = 2164523016;
39931 self->private_impl.f_src_pixfmt = 2164523016;
39932 if (self->private_impl.f_chunk_length > 256) {
39933 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39934 goto exit;
39935 }
39936 v_n = ((uint32_t)(self->private_impl.f_chunk_length));
39937 self->private_impl.f_chunk_length = 0;
39938 while (v_i < v_n) {
39939 {
39940 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
39941 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
39942 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
39943 goto suspend;
39944 }
39945 uint8_t t_2 = *iop_a_src++;
39946 self->private_data.f_src_palette[((4 * v_i) + 3)] = t_2;
39947 }
39948 v_i += 1;
39949 }
39950 } else {
39951 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
39952 goto exit;
39953 }
39954
39955 goto ok;
39956 ok:
39957 self->private_impl.p_decode_trns[0] = 0;
39958 goto exit;
39959 }
39960
39961 goto suspend;
39962 suspend:
39963 self->private_impl.p_decode_trns[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
39964 self->private_data.s_decode_trns[0].v_i = v_i;
39965 self->private_data.s_decode_trns[0].v_n = v_n;
39966
39967 goto exit;
39968 exit:
39969 if (a_src) {
39970 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
39971 }
39972
39973 return status;
39974 }
39975
39976 // -------- func png.decoder.decode_frame_config
39977
39978 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__decode_frame_config(wuffs_png__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)39979 wuffs_png__decoder__decode_frame_config(
39980 wuffs_png__decoder* self,
39981 wuffs_base__frame_config* a_dst,
39982 wuffs_base__io_buffer* a_src) {
39983 if (!self) {
39984 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
39985 }
39986 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
39987 return wuffs_base__make_status(
39988 (self->private_impl.magic == WUFFS_BASE__DISABLED)
39989 ? wuffs_base__error__disabled_by_previous_error
39990 : wuffs_base__error__initialize_not_called);
39991 }
39992 if (!a_src) {
39993 self->private_impl.magic = WUFFS_BASE__DISABLED;
39994 return wuffs_base__make_status(wuffs_base__error__bad_argument);
39995 }
39996 if ((self->private_impl.active_coroutine != 0) &&
39997 (self->private_impl.active_coroutine != 2)) {
39998 self->private_impl.magic = WUFFS_BASE__DISABLED;
39999 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
40000 }
40001 self->private_impl.active_coroutine = 0;
40002 wuffs_base__status status = wuffs_base__make_status(NULL);
40003
40004 const uint8_t* iop_a_src = NULL;
40005 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40006 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40007 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40008 if (a_src) {
40009 io0_a_src = a_src->data.ptr;
40010 io1_a_src = io0_a_src + a_src->meta.ri;
40011 iop_a_src = io1_a_src;
40012 io2_a_src = io0_a_src + a_src->meta.wi;
40013 }
40014
40015 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
40016 switch (coro_susp_point) {
40017 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40018
40019 if (self->private_impl.f_call_sequence == 255) {
40020 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
40021 goto ok;
40022 } else if (self->private_impl.f_call_sequence < 3) {
40023 if (a_src) {
40024 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40025 }
40026 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40027 status = wuffs_png__decoder__decode_image_config(self, NULL, a_src);
40028 if (a_src) {
40029 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40030 }
40031 if (status.repr) {
40032 goto suspend;
40033 }
40034 } else if (self->private_impl.f_call_sequence == 3) {
40035 if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
40036 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
40037 goto exit;
40038 }
40039 } else if (self->private_impl.f_call_sequence == 4) {
40040 if (a_src) {
40041 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40042 }
40043 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40044 status = wuffs_png__decoder__skip_frame(self, a_src);
40045 if (a_src) {
40046 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40047 }
40048 if (status.repr) {
40049 goto suspend;
40050 }
40051 if (self->private_impl.f_call_sequence == 255) {
40052 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
40053 goto ok;
40054 }
40055 }
40056 if (self->private_impl.f_num_decoded_frame_configs_value == 0) {
40057 self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0;
40058 self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0;
40059 self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1;
40060 self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1;
40061 self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position;
40062 self->private_impl.f_frame_duration = self->private_impl.f_first_duration;
40063 self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal;
40064 self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend;
40065 } else {
40066 while (true) {
40067 {
40068 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40069 uint32_t t_0;
40070 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40071 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40072 iop_a_src += 4;
40073 } else {
40074 self->private_data.s_decode_frame_config[0].scratch = 0;
40075 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40076 while (true) {
40077 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40078 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40079 goto suspend;
40080 }
40081 uint64_t* scratch = &self->private_data.s_decode_frame_config[0].scratch;
40082 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
40083 *scratch >>= 8;
40084 *scratch <<= 8;
40085 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
40086 if (num_bits_0 == 24) {
40087 t_0 = ((uint32_t)(*scratch >> 32));
40088 break;
40089 }
40090 num_bits_0 += 8;
40091 *scratch |= ((uint64_t)(num_bits_0));
40092 }
40093 }
40094 self->private_impl.f_chunk_length = t_0;
40095 }
40096 {
40097 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40098 uint32_t t_1;
40099 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40100 t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
40101 iop_a_src += 4;
40102 } else {
40103 self->private_data.s_decode_frame_config[0].scratch = 0;
40104 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40105 while (true) {
40106 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40107 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40108 goto suspend;
40109 }
40110 uint64_t* scratch = &self->private_data.s_decode_frame_config[0].scratch;
40111 uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
40112 *scratch <<= 8;
40113 *scratch >>= 8;
40114 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
40115 if (num_bits_1 == 24) {
40116 t_1 = ((uint32_t)(*scratch));
40117 break;
40118 }
40119 num_bits_1 += 8;
40120 *scratch |= ((uint64_t)(num_bits_1)) << 56;
40121 }
40122 }
40123 self->private_impl.f_chunk_type = t_1;
40124 }
40125 if (self->private_impl.f_chunk_type == 1413571686) {
40126 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40127 goto exit;
40128 } else if (self->private_impl.f_chunk_type == 1280598886) {
40129 self->private_impl.f_frame_config_io_position = ((uint64_t)(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) - 8));
40130 if (a_src) {
40131 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40132 }
40133 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
40134 status = wuffs_png__decoder__decode_fctl(self, a_src);
40135 if (a_src) {
40136 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40137 }
40138 if (status.repr) {
40139 goto suspend;
40140 }
40141 self->private_data.s_decode_frame_config[0].scratch = 4;
40142 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
40143 if (self->private_data.s_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40144 self->private_data.s_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40145 iop_a_src = io2_a_src;
40146 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40147 goto suspend;
40148 }
40149 iop_a_src += self->private_data.s_decode_frame_config[0].scratch;
40150 goto label__0__break;
40151 }
40152 self->private_data.s_decode_frame_config[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4);
40153 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
40154 if (self->private_data.s_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40155 self->private_data.s_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40156 iop_a_src = io2_a_src;
40157 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40158 goto suspend;
40159 }
40160 iop_a_src += self->private_data.s_decode_frame_config[0].scratch;
40161 self->private_impl.f_chunk_length = 0;
40162 }
40163 label__0__break:;
40164 }
40165 if (a_dst != NULL) {
40166 wuffs_base__frame_config__set(
40167 a_dst,
40168 wuffs_base__utility__make_rect_ie_u32(
40169 self->private_impl.f_frame_rect_x0,
40170 self->private_impl.f_frame_rect_y0,
40171 self->private_impl.f_frame_rect_x1,
40172 self->private_impl.f_frame_rect_y1),
40173 ((wuffs_base__flicks)(self->private_impl.f_frame_duration)),
40174 ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)),
40175 self->private_impl.f_frame_config_io_position,
40176 self->private_impl.f_frame_disposal,
40177 ((self->private_impl.f_color_type <= 3) && ! self->private_impl.f_seen_trns),
40178 self->private_impl.f_frame_overwrite_instead_of_blend,
40179 0);
40180 }
40181 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1);
40182 self->private_impl.f_call_sequence = 4;
40183
40184 ok:
40185 self->private_impl.p_decode_frame_config[0] = 0;
40186 goto exit;
40187 }
40188
40189 goto suspend;
40190 suspend:
40191 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40192 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
40193
40194 goto exit;
40195 exit:
40196 if (a_src) {
40197 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40198 }
40199
40200 if (wuffs_base__status__is_error(&status)) {
40201 self->private_impl.magic = WUFFS_BASE__DISABLED;
40202 }
40203 return status;
40204 }
40205
40206 // -------- func png.decoder.skip_frame
40207
40208 static wuffs_base__status
wuffs_png__decoder__skip_frame(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src)40209 wuffs_png__decoder__skip_frame(
40210 wuffs_png__decoder* self,
40211 wuffs_base__io_buffer* a_src) {
40212 wuffs_base__status status = wuffs_base__make_status(NULL);
40213
40214 uint32_t v_seq_num = 0;
40215
40216 const uint8_t* iop_a_src = NULL;
40217 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40218 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40219 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40220 if (a_src) {
40221 io0_a_src = a_src->data.ptr;
40222 io1_a_src = io0_a_src + a_src->meta.ri;
40223 iop_a_src = io1_a_src;
40224 io2_a_src = io0_a_src + a_src->meta.wi;
40225 }
40226
40227 uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
40228 switch (coro_susp_point) {
40229 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40230
40231 self->private_impl.f_chunk_type_array[0] = 0;
40232 self->private_impl.f_chunk_type_array[1] = 0;
40233 self->private_impl.f_chunk_type_array[2] = 0;
40234 self->private_impl.f_chunk_type_array[3] = 0;
40235 label__0__continue:;
40236 while (true) {
40237 while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
40238 if (a_src && a_src->meta.closed) {
40239 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40240 goto exit;
40241 }
40242 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40243 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
40244 }
40245 self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40246 self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
40247 if (self->private_impl.f_chunk_type == 1413563465) {
40248 if (self->private_impl.f_chunk_type_array[0] == 102) {
40249 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40250 goto exit;
40251 }
40252 self->private_impl.f_chunk_type_array[0] = 73;
40253 self->private_impl.f_chunk_type_array[1] = 68;
40254 self->private_impl.f_chunk_type_array[2] = 65;
40255 self->private_impl.f_chunk_type_array[3] = 84;
40256 } else if (self->private_impl.f_chunk_type == 1413571686) {
40257 if (self->private_impl.f_chunk_type_array[0] == 73) {
40258 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40259 goto exit;
40260 }
40261 self->private_impl.f_chunk_type_array[0] = 102;
40262 self->private_impl.f_chunk_type_array[1] = 100;
40263 self->private_impl.f_chunk_type_array[2] = 65;
40264 self->private_impl.f_chunk_type_array[3] = 84;
40265 if (self->private_impl.f_chunk_length < 4) {
40266 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40267 goto exit;
40268 }
40269 self->private_impl.f_chunk_length -= 4;
40270 iop_a_src += 8;
40271 {
40272 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40273 uint32_t t_0;
40274 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40275 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40276 iop_a_src += 4;
40277 } else {
40278 self->private_data.s_skip_frame[0].scratch = 0;
40279 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40280 while (true) {
40281 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40282 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40283 goto suspend;
40284 }
40285 uint64_t* scratch = &self->private_data.s_skip_frame[0].scratch;
40286 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
40287 *scratch >>= 8;
40288 *scratch <<= 8;
40289 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
40290 if (num_bits_0 == 24) {
40291 t_0 = ((uint32_t)(*scratch >> 32));
40292 break;
40293 }
40294 num_bits_0 += 8;
40295 *scratch |= ((uint64_t)(num_bits_0));
40296 }
40297 }
40298 v_seq_num = t_0;
40299 }
40300 if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
40301 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
40302 goto exit;
40303 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
40304 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
40305 goto exit;
40306 }
40307 self->private_impl.f_next_animation_seq_num += 1;
40308 self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4);
40309 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40310 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40311 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40312 iop_a_src = io2_a_src;
40313 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40314 goto suspend;
40315 }
40316 iop_a_src += self->private_data.s_skip_frame[0].scratch;
40317 self->private_impl.f_chunk_length = 0;
40318 goto label__0__continue;
40319 } else if (self->private_impl.f_chunk_type_array[0] != 0) {
40320 goto label__0__break;
40321 } else if (self->private_impl.f_chunk_type == 1280598886) {
40322 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40323 goto exit;
40324 }
40325 self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12);
40326 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40327 if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40328 self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40329 iop_a_src = io2_a_src;
40330 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40331 goto suspend;
40332 }
40333 iop_a_src += self->private_data.s_skip_frame[0].scratch;
40334 self->private_impl.f_chunk_length = 0;
40335 }
40336 label__0__break:;
40337 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
40338 if (self->private_impl.f_num_decoded_frames_value < self->private_impl.f_num_animation_frames_value) {
40339 self->private_impl.f_call_sequence = 5;
40340 } else {
40341 self->private_impl.f_call_sequence = 255;
40342 }
40343
40344 ok:
40345 self->private_impl.p_skip_frame[0] = 0;
40346 goto exit;
40347 }
40348
40349 goto suspend;
40350 suspend:
40351 self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40352
40353 goto exit;
40354 exit:
40355 if (a_src) {
40356 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40357 }
40358
40359 return status;
40360 }
40361
40362 // -------- func png.decoder.decode_frame
40363
40364 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__decode_frame(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)40365 wuffs_png__decoder__decode_frame(
40366 wuffs_png__decoder* self,
40367 wuffs_base__pixel_buffer* a_dst,
40368 wuffs_base__io_buffer* a_src,
40369 wuffs_base__pixel_blend a_blend,
40370 wuffs_base__slice_u8 a_workbuf,
40371 wuffs_base__decode_frame_options* a_opts) {
40372 if (!self) {
40373 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
40374 }
40375 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
40376 return wuffs_base__make_status(
40377 (self->private_impl.magic == WUFFS_BASE__DISABLED)
40378 ? wuffs_base__error__disabled_by_previous_error
40379 : wuffs_base__error__initialize_not_called);
40380 }
40381 if (!a_dst || !a_src) {
40382 self->private_impl.magic = WUFFS_BASE__DISABLED;
40383 return wuffs_base__make_status(wuffs_base__error__bad_argument);
40384 }
40385 if ((self->private_impl.active_coroutine != 0) &&
40386 (self->private_impl.active_coroutine != 3)) {
40387 self->private_impl.magic = WUFFS_BASE__DISABLED;
40388 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
40389 }
40390 self->private_impl.active_coroutine = 0;
40391 wuffs_base__status status = wuffs_base__make_status(NULL);
40392
40393 uint32_t v_seq_num = 0;
40394 wuffs_base__status v_status = wuffs_base__make_status(NULL);
40395 uint32_t v_pass_width = 0;
40396 uint32_t v_pass_height = 0;
40397
40398 const uint8_t* iop_a_src = NULL;
40399 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40400 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40401 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40402 if (a_src) {
40403 io0_a_src = a_src->data.ptr;
40404 io1_a_src = io0_a_src + a_src->meta.ri;
40405 iop_a_src = io1_a_src;
40406 io2_a_src = io0_a_src + a_src->meta.wi;
40407 }
40408
40409 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
40410 switch (coro_susp_point) {
40411 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40412
40413 if (self->private_impl.f_call_sequence == 255) {
40414 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
40415 goto ok;
40416 } else if (self->private_impl.f_call_sequence != 4) {
40417 if (a_src) {
40418 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40419 }
40420 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40421 status = wuffs_png__decoder__decode_frame_config(self, NULL, a_src);
40422 if (a_src) {
40423 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40424 }
40425 if (status.repr) {
40426 goto suspend;
40427 }
40428 }
40429 while (true) {
40430 while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
40431 if (a_src && a_src->meta.closed) {
40432 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40433 goto exit;
40434 }
40435 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40436 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
40437 }
40438 self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40439 self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
40440 if (self->private_impl.f_chunk_type == 1413563465) {
40441 self->private_impl.f_chunk_type_array[0] = 73;
40442 self->private_impl.f_chunk_type_array[1] = 68;
40443 self->private_impl.f_chunk_type_array[2] = 65;
40444 self->private_impl.f_chunk_type_array[3] = 84;
40445 iop_a_src += 8;
40446 if ( ! self->private_impl.f_ignore_checksum) {
40447 wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
40448 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40449 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
40450 }
40451 goto label__0__break;
40452 } else if (self->private_impl.f_chunk_type == 1413571686) {
40453 self->private_impl.f_chunk_type_array[0] = 102;
40454 self->private_impl.f_chunk_type_array[1] = 100;
40455 self->private_impl.f_chunk_type_array[2] = 65;
40456 self->private_impl.f_chunk_type_array[3] = 84;
40457 if (self->private_impl.f_chunk_length < 4) {
40458 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40459 goto exit;
40460 }
40461 self->private_impl.f_chunk_length -= 4;
40462 iop_a_src += 8;
40463 {
40464 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40465 uint32_t t_0;
40466 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40467 t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40468 iop_a_src += 4;
40469 } else {
40470 self->private_data.s_decode_frame[0].scratch = 0;
40471 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40472 while (true) {
40473 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40474 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40475 goto suspend;
40476 }
40477 uint64_t* scratch = &self->private_data.s_decode_frame[0].scratch;
40478 uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFF));
40479 *scratch >>= 8;
40480 *scratch <<= 8;
40481 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
40482 if (num_bits_0 == 24) {
40483 t_0 = ((uint32_t)(*scratch >> 32));
40484 break;
40485 }
40486 num_bits_0 += 8;
40487 *scratch |= ((uint64_t)(num_bits_0));
40488 }
40489 }
40490 v_seq_num = t_0;
40491 }
40492 if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
40493 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
40494 goto exit;
40495 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
40496 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
40497 goto exit;
40498 }
40499 self->private_impl.f_next_animation_seq_num += 1;
40500 goto label__0__break;
40501 } else if (self->private_impl.f_chunk_type == 1280598886) {
40502 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40503 goto exit;
40504 }
40505 self->private_data.s_decode_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12);
40506 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40507 if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
40508 self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
40509 iop_a_src = io2_a_src;
40510 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40511 goto suspend;
40512 }
40513 iop_a_src += self->private_data.s_decode_frame[0].scratch;
40514 self->private_impl.f_chunk_length = 0;
40515 }
40516 label__0__break:;
40517 if (self->private_impl.f_zlib_is_dirty) {
40518 wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
40519 sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40520 if (self->private_impl.f_ignore_checksum) {
40521 wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, 1, true);
40522 }
40523 }
40524 self->private_impl.f_zlib_is_dirty = true;
40525 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
40526 wuffs_base__pixel_buffer__pixel_format(a_dst),
40527 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
40528 wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
40529 wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
40530 a_blend);
40531 if ( ! wuffs_base__status__is_ok(&v_status)) {
40532 status = v_status;
40533 if (wuffs_base__status__is_error(&status)) {
40534 goto exit;
40535 } else if (wuffs_base__status__is_suspension(&status)) {
40536 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40537 goto exit;
40538 }
40539 goto ok;
40540 }
40541 self->private_impl.f_workbuf_hist_pos_base = 0;
40542 while (true) {
40543 if (self->private_impl.f_chunk_type_array[0] == 73) {
40544 v_pass_width = (16777215 & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][1])) + self->private_impl.f_width) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]));
40545 v_pass_height = (16777215 & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][4])) + self->private_impl.f_height) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3]));
40546 } else {
40547 v_pass_width = (16777215 & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0)));
40548 v_pass_height = (16777215 & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0)));
40549 }
40550 if ((v_pass_width > 0) && (v_pass_height > 0)) {
40551 self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width);
40552 self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1 + self->private_impl.f_pass_bytes_per_row));
40553 if (a_src) {
40554 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40555 }
40556 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40557 status = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf);
40558 if (a_src) {
40559 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40560 }
40561 if (status.repr) {
40562 goto suspend;
40563 }
40564 v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf);
40565 if ( ! wuffs_base__status__is_ok(&v_status)) {
40566 status = v_status;
40567 if (wuffs_base__status__is_error(&status)) {
40568 goto exit;
40569 } else if (wuffs_base__status__is_suspension(&status)) {
40570 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40571 goto exit;
40572 }
40573 goto ok;
40574 }
40575 self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length;
40576 }
40577 if ((self->private_impl.f_interlace_pass == 0) || (self->private_impl.f_interlace_pass >= 7)) {
40578 goto label__1__break;
40579 }
40580 #if defined(__GNUC__)
40581 #pragma GCC diagnostic push
40582 #pragma GCC diagnostic ignored "-Wconversion"
40583 #endif
40584 self->private_impl.f_interlace_pass += 1;
40585 #if defined(__GNUC__)
40586 #pragma GCC diagnostic pop
40587 #endif
40588 }
40589 label__1__break:;
40590 wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1);
40591 if (self->private_impl.f_num_decoded_frames_value < self->private_impl.f_num_animation_frames_value) {
40592 self->private_impl.f_call_sequence = 5;
40593 } else {
40594 self->private_impl.f_call_sequence = 255;
40595 }
40596
40597 ok:
40598 self->private_impl.p_decode_frame[0] = 0;
40599 goto exit;
40600 }
40601
40602 goto suspend;
40603 suspend:
40604 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40605 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
40606
40607 goto exit;
40608 exit:
40609 if (a_src) {
40610 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40611 }
40612
40613 if (wuffs_base__status__is_error(&status)) {
40614 self->private_impl.magic = WUFFS_BASE__DISABLED;
40615 }
40616 return status;
40617 }
40618
40619 // -------- func png.decoder.decode_pass
40620
40621 static wuffs_base__status
wuffs_png__decoder__decode_pass(wuffs_png__decoder * self,wuffs_base__io_buffer * a_src,wuffs_base__slice_u8 a_workbuf)40622 wuffs_png__decoder__decode_pass(
40623 wuffs_png__decoder* self,
40624 wuffs_base__io_buffer* a_src,
40625 wuffs_base__slice_u8 a_workbuf) {
40626 wuffs_base__status status = wuffs_base__make_status(NULL);
40627
40628 wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
40629 wuffs_base__io_buffer* v_w = &u_w;
40630 uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40631 uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40632 uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40633 uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40634 uint64_t v_w_mark = 0;
40635 uint64_t v_r_mark = 0;
40636 wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
40637 uint32_t v_checksum_have = 0;
40638 uint32_t v_checksum_want = 0;
40639 uint32_t v_seq_num = 0;
40640
40641 const uint8_t* iop_a_src = NULL;
40642 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40643 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40644 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
40645 if (a_src) {
40646 io0_a_src = a_src->data.ptr;
40647 io1_a_src = io0_a_src + a_src->meta.ri;
40648 iop_a_src = io1_a_src;
40649 io2_a_src = io0_a_src + a_src->meta.wi;
40650 }
40651
40652 uint32_t coro_susp_point = self->private_impl.p_decode_pass[0];
40653 switch (coro_susp_point) {
40654 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
40655
40656 self->private_impl.f_workbuf_wi = 0;
40657 label__0__continue:;
40658 while (true) {
40659 if ((self->private_impl.f_workbuf_wi > self->private_impl.f_pass_workbuf_length) || (self->private_impl.f_pass_workbuf_length > ((uint64_t)(a_workbuf.len)))) {
40660 status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
40661 goto exit;
40662 }
40663 {
40664 wuffs_base__io_buffer* o_0_v_w = v_w;
40665 uint8_t *o_0_iop_v_w = iop_v_w;
40666 uint8_t *o_0_io0_v_w = io0_v_w;
40667 uint8_t *o_0_io1_v_w = io1_v_w;
40668 uint8_t *o_0_io2_v_w = io2_v_w;
40669 v_w = wuffs_base__io_writer__set(
40670 &u_w,
40671 &iop_v_w,
40672 &io0_v_w,
40673 &io1_v_w,
40674 &io2_v_w,
40675 wuffs_base__slice_u8__subslice_ij(a_workbuf,
40676 self->private_impl.f_workbuf_wi,
40677 self->private_impl.f_pass_workbuf_length),
40678 ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi)));
40679 {
40680 const uint8_t *o_1_io2_a_src = io2_a_src;
40681 wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
40682 ((uint64_t)(self->private_impl.f_chunk_length)));
40683 if (a_src) {
40684 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40685 }
40686 v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
40687 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
40688 {
40689 u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
40690 if (a_src) {
40691 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40692 }
40693 wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8());
40694 v_zlib_status = t_0;
40695 iop_v_w = u_w.data.ptr + u_w.meta.wi;
40696 if (a_src) {
40697 iop_a_src = a_src->data.ptr + a_src->meta.ri;
40698 }
40699 }
40700 if ( ! self->private_impl.f_ignore_checksum) {
40701 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
40702 }
40703 wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)((wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))) & 4294967295))));
40704 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_workbuf_wi, wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w))));
40705 io2_a_src = o_1_io2_a_src;
40706 if (a_src) {
40707 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
40708 }
40709 }
40710 v_w = o_0_v_w;
40711 iop_v_w = o_0_iop_v_w;
40712 io0_v_w = o_0_io0_v_w;
40713 io1_v_w = o_0_io1_v_w;
40714 io2_v_w = o_0_io2_v_w;
40715 }
40716 if (wuffs_base__status__is_ok(&v_zlib_status)) {
40717 if (self->private_impl.f_chunk_length > 0) {
40718 status = wuffs_base__make_status(wuffs_base__error__too_much_data);
40719 goto exit;
40720 }
40721 {
40722 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
40723 uint32_t t_1;
40724 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40725 t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40726 iop_a_src += 4;
40727 } else {
40728 self->private_data.s_decode_pass[0].scratch = 0;
40729 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
40730 while (true) {
40731 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40732 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40733 goto suspend;
40734 }
40735 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40736 uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFF));
40737 *scratch >>= 8;
40738 *scratch <<= 8;
40739 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
40740 if (num_bits_1 == 24) {
40741 t_1 = ((uint32_t)(*scratch >> 32));
40742 break;
40743 }
40744 num_bits_1 += 8;
40745 *scratch |= ((uint64_t)(num_bits_1));
40746 }
40747 }
40748 v_checksum_want = t_1;
40749 }
40750 if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0] == 73)) {
40751 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
40752 if (v_checksum_have != v_checksum_want) {
40753 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
40754 goto exit;
40755 }
40756 }
40757 goto label__0__break;
40758 } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) {
40759 if ((1 <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6)) {
40760 goto label__0__break;
40761 }
40762 status = wuffs_base__make_status(wuffs_base__error__too_much_data);
40763 goto exit;
40764 } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) {
40765 status = v_zlib_status;
40766 if (wuffs_base__status__is_error(&status)) {
40767 goto exit;
40768 } else if (wuffs_base__status__is_suspension(&status)) {
40769 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
40770 goto exit;
40771 }
40772 goto ok;
40773 } else if (self->private_impl.f_chunk_length == 0) {
40774 {
40775 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
40776 uint32_t t_2;
40777 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40778 t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40779 iop_a_src += 4;
40780 } else {
40781 self->private_data.s_decode_pass[0].scratch = 0;
40782 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
40783 while (true) {
40784 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40785 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40786 goto suspend;
40787 }
40788 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40789 uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFF));
40790 *scratch >>= 8;
40791 *scratch <<= 8;
40792 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
40793 if (num_bits_2 == 24) {
40794 t_2 = ((uint32_t)(*scratch >> 32));
40795 break;
40796 }
40797 num_bits_2 += 8;
40798 *scratch |= ((uint64_t)(num_bits_2));
40799 }
40800 }
40801 v_checksum_want = t_2;
40802 }
40803 if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0] == 73)) {
40804 v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
40805 if (v_checksum_have != v_checksum_want) {
40806 status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
40807 goto exit;
40808 }
40809 }
40810 {
40811 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
40812 uint32_t t_3;
40813 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40814 t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40815 iop_a_src += 4;
40816 } else {
40817 self->private_data.s_decode_pass[0].scratch = 0;
40818 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
40819 while (true) {
40820 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40821 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40822 goto suspend;
40823 }
40824 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40825 uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFF));
40826 *scratch >>= 8;
40827 *scratch <<= 8;
40828 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
40829 if (num_bits_3 == 24) {
40830 t_3 = ((uint32_t)(*scratch >> 32));
40831 break;
40832 }
40833 num_bits_3 += 8;
40834 *scratch |= ((uint64_t)(num_bits_3));
40835 }
40836 }
40837 self->private_impl.f_chunk_length = t_3;
40838 }
40839 {
40840 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
40841 uint32_t t_4;
40842 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40843 t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
40844 iop_a_src += 4;
40845 } else {
40846 self->private_data.s_decode_pass[0].scratch = 0;
40847 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
40848 while (true) {
40849 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40850 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40851 goto suspend;
40852 }
40853 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40854 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
40855 *scratch <<= 8;
40856 *scratch >>= 8;
40857 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
40858 if (num_bits_4 == 24) {
40859 t_4 = ((uint32_t)(*scratch));
40860 break;
40861 }
40862 num_bits_4 += 8;
40863 *scratch |= ((uint64_t)(num_bits_4)) << 56;
40864 }
40865 }
40866 self->private_impl.f_chunk_type = t_4;
40867 }
40868 if (self->private_impl.f_chunk_type_array[0] == 73) {
40869 if (self->private_impl.f_chunk_type != 1413563465) {
40870 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40871 goto exit;
40872 }
40873 if ( ! self->private_impl.f_ignore_checksum) {
40874 wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
40875 sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
40876 wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
40877 }
40878 } else {
40879 if ((self->private_impl.f_chunk_type != 1413571686) || (self->private_impl.f_chunk_length < 4)) {
40880 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
40881 goto exit;
40882 }
40883 self->private_impl.f_chunk_length -= 4;
40884 {
40885 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
40886 uint32_t t_5;
40887 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
40888 t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
40889 iop_a_src += 4;
40890 } else {
40891 self->private_data.s_decode_pass[0].scratch = 0;
40892 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
40893 while (true) {
40894 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
40895 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40896 goto suspend;
40897 }
40898 uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
40899 uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFF));
40900 *scratch >>= 8;
40901 *scratch <<= 8;
40902 *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
40903 if (num_bits_5 == 24) {
40904 t_5 = ((uint32_t)(*scratch >> 32));
40905 break;
40906 }
40907 num_bits_5 += 8;
40908 *scratch |= ((uint64_t)(num_bits_5));
40909 }
40910 }
40911 v_seq_num = t_5;
40912 }
40913 if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
40914 status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
40915 goto exit;
40916 } else if (self->private_impl.f_next_animation_seq_num >= 4294967295) {
40917 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
40918 goto exit;
40919 }
40920 self->private_impl.f_next_animation_seq_num += 1;
40921 }
40922 goto label__0__continue;
40923 } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0) {
40924 status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input);
40925 goto exit;
40926 }
40927 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
40928 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
40929 }
40930 label__0__break:;
40931 if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) {
40932 status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
40933 goto exit;
40934 } else if (0 < ((uint64_t)(a_workbuf.len))) {
40935 if (a_workbuf.ptr[0] == 4) {
40936 a_workbuf.ptr[0] = 1;
40937 }
40938 }
40939
40940 ok:
40941 self->private_impl.p_decode_pass[0] = 0;
40942 goto exit;
40943 }
40944
40945 goto suspend;
40946 suspend:
40947 self->private_impl.p_decode_pass[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
40948
40949 goto exit;
40950 exit:
40951 if (a_src) {
40952 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
40953 }
40954
40955 return status;
40956 }
40957
40958 // -------- func png.decoder.frame_dirty_rect
40959
40960 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_png__decoder__frame_dirty_rect(const wuffs_png__decoder * self)40961 wuffs_png__decoder__frame_dirty_rect(
40962 const wuffs_png__decoder* self) {
40963 if (!self) {
40964 return wuffs_base__utility__empty_rect_ie_u32();
40965 }
40966 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40967 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40968 return wuffs_base__utility__empty_rect_ie_u32();
40969 }
40970
40971 return wuffs_base__utility__make_rect_ie_u32(
40972 self->private_impl.f_frame_rect_x0,
40973 self->private_impl.f_frame_rect_y0,
40974 self->private_impl.f_frame_rect_x1,
40975 self->private_impl.f_frame_rect_y1);
40976 }
40977
40978 // -------- func png.decoder.num_animation_loops
40979
40980 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_png__decoder__num_animation_loops(const wuffs_png__decoder * self)40981 wuffs_png__decoder__num_animation_loops(
40982 const wuffs_png__decoder* self) {
40983 if (!self) {
40984 return 0;
40985 }
40986 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
40987 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
40988 return 0;
40989 }
40990
40991 return self->private_impl.f_num_animation_loops_value;
40992 }
40993
40994 // -------- func png.decoder.num_decoded_frame_configs
40995
40996 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frame_configs(const wuffs_png__decoder * self)40997 wuffs_png__decoder__num_decoded_frame_configs(
40998 const wuffs_png__decoder* self) {
40999 if (!self) {
41000 return 0;
41001 }
41002 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41003 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41004 return 0;
41005 }
41006
41007 return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value));
41008 }
41009
41010 // -------- func png.decoder.num_decoded_frames
41011
41012 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_png__decoder__num_decoded_frames(const wuffs_png__decoder * self)41013 wuffs_png__decoder__num_decoded_frames(
41014 const wuffs_png__decoder* self) {
41015 if (!self) {
41016 return 0;
41017 }
41018 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41019 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41020 return 0;
41021 }
41022
41023 return ((uint64_t)(self->private_impl.f_num_decoded_frames_value));
41024 }
41025
41026 // -------- func png.decoder.restart_frame
41027
41028 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__restart_frame(wuffs_png__decoder * self,uint64_t a_index,uint64_t a_io_position)41029 wuffs_png__decoder__restart_frame(
41030 wuffs_png__decoder* self,
41031 uint64_t a_index,
41032 uint64_t a_io_position) {
41033 if (!self) {
41034 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41035 }
41036 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41037 return wuffs_base__make_status(
41038 (self->private_impl.magic == WUFFS_BASE__DISABLED)
41039 ? wuffs_base__error__disabled_by_previous_error
41040 : wuffs_base__error__initialize_not_called);
41041 }
41042
41043 if (self->private_impl.f_call_sequence < 3) {
41044 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41045 } else if ((a_index >= ((uint64_t)(self->private_impl.f_num_animation_frames_value))) || ((a_index == 0) && (a_io_position != self->private_impl.f_first_config_io_position))) {
41046 return wuffs_base__make_status(wuffs_base__error__bad_argument);
41047 }
41048 self->private_impl.f_call_sequence = 3;
41049 if (self->private_impl.f_interlace_pass >= 1) {
41050 self->private_impl.f_interlace_pass = 1;
41051 }
41052 self->private_impl.f_frame_config_io_position = a_io_position;
41053 self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)((a_index & 4294967295)));
41054 self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value;
41055 return wuffs_base__make_status(NULL);
41056 }
41057
41058 // -------- func png.decoder.set_report_metadata
41059
41060 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_png__decoder__set_report_metadata(wuffs_png__decoder * self,uint32_t a_fourcc,bool a_report)41061 wuffs_png__decoder__set_report_metadata(
41062 wuffs_png__decoder* self,
41063 uint32_t a_fourcc,
41064 bool a_report) {
41065 if (!self) {
41066 return wuffs_base__make_empty_struct();
41067 }
41068 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41069 return wuffs_base__make_empty_struct();
41070 }
41071
41072 if (a_fourcc == 1128813133) {
41073 self->private_impl.f_report_metadata_chrm = a_report;
41074 } else if (a_fourcc == 1163413830) {
41075 self->private_impl.f_report_metadata_exif = a_report;
41076 } else if (a_fourcc == 1195461953) {
41077 self->private_impl.f_report_metadata_gama = a_report;
41078 } else if (a_fourcc == 1229144912) {
41079 self->private_impl.f_report_metadata_iccp = a_report;
41080 } else if (a_fourcc == 1263947808) {
41081 self->private_impl.f_report_metadata_kvp = a_report;
41082 } else if (a_fourcc == 1397901122) {
41083 self->private_impl.f_report_metadata_srgb = a_report;
41084 }
41085 return wuffs_base__make_empty_struct();
41086 }
41087
41088 // -------- func png.decoder.tell_me_more
41089
41090 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_png__decoder__tell_me_more(wuffs_png__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)41091 wuffs_png__decoder__tell_me_more(
41092 wuffs_png__decoder* self,
41093 wuffs_base__io_buffer* a_dst,
41094 wuffs_base__more_information* a_minfo,
41095 wuffs_base__io_buffer* a_src) {
41096 if (!self) {
41097 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
41098 }
41099 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
41100 return wuffs_base__make_status(
41101 (self->private_impl.magic == WUFFS_BASE__DISABLED)
41102 ? wuffs_base__error__disabled_by_previous_error
41103 : wuffs_base__error__initialize_not_called);
41104 }
41105 if (!a_dst || !a_src) {
41106 self->private_impl.magic = WUFFS_BASE__DISABLED;
41107 return wuffs_base__make_status(wuffs_base__error__bad_argument);
41108 }
41109 if ((self->private_impl.active_coroutine != 0) &&
41110 (self->private_impl.active_coroutine != 4)) {
41111 self->private_impl.magic = WUFFS_BASE__DISABLED;
41112 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
41113 }
41114 self->private_impl.active_coroutine = 0;
41115 wuffs_base__status status = wuffs_base__make_status(NULL);
41116
41117 uint8_t v_c = 0;
41118 uint16_t v_c2 = 0;
41119 wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
41120 wuffs_base__io_buffer* v_w = &u_w;
41121 uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41122 uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41123 uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41124 uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41125 uint64_t v_num_written = 0;
41126 uint64_t v_w_mark = 0;
41127 uint64_t v_r_mark = 0;
41128 wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
41129
41130 uint8_t* iop_a_dst = NULL;
41131 uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41132 uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41133 uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41134 if (a_dst) {
41135 io0_a_dst = a_dst->data.ptr;
41136 io1_a_dst = io0_a_dst + a_dst->meta.wi;
41137 iop_a_dst = io1_a_dst;
41138 io2_a_dst = io0_a_dst + a_dst->data.len;
41139 if (a_dst->meta.closed) {
41140 io2_a_dst = iop_a_dst;
41141 }
41142 }
41143 const uint8_t* iop_a_src = NULL;
41144 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41145 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41146 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
41147 if (a_src) {
41148 io0_a_src = a_src->data.ptr;
41149 io1_a_src = io0_a_src + a_src->meta.ri;
41150 iop_a_src = io1_a_src;
41151 io2_a_src = io0_a_src + a_src->meta.wi;
41152 }
41153
41154 uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
41155 if (coro_susp_point) {
41156 v_zlib_status = self->private_data.s_tell_me_more[0].v_zlib_status;
41157 }
41158 switch (coro_susp_point) {
41159 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
41160
41161 if (self->private_impl.f_call_sequence != 1) {
41162 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
41163 goto exit;
41164 }
41165 if (self->private_impl.f_metadata_fourcc == 0) {
41166 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
41167 goto exit;
41168 }
41169 while (true) {
41170 if (self->private_impl.f_metadata_flavor == 3) {
41171 while (true) {
41172 if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_y) {
41173 status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
41174 goto exit;
41175 } else if (a_minfo != NULL) {
41176 wuffs_base__more_information__set(a_minfo,
41177 self->private_impl.f_metadata_flavor,
41178 self->private_impl.f_metadata_fourcc,
41179 self->private_impl.f_metadata_x,
41180 self->private_impl.f_metadata_y,
41181 self->private_impl.f_metadata_z);
41182 }
41183 if (self->private_impl.f_metadata_y >= self->private_impl.f_metadata_z) {
41184 goto label__goto_done__break;
41185 }
41186 self->private_impl.f_metadata_y = self->private_impl.f_metadata_z;
41187 status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
41188 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
41189 }
41190 }
41191 if (self->private_impl.f_metadata_is_zlib_compressed) {
41192 if (self->private_impl.f_zlib_is_dirty) {
41193 wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
41194 sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
41195 if (self->private_impl.f_ignore_checksum) {
41196 wuffs_zlib__decoder__set_quirk_enabled(&self->private_data.f_zlib, 1, true);
41197 }
41198 }
41199 self->private_impl.f_zlib_is_dirty = true;
41200 self->private_impl.f_ztxt_hist_pos = 0;
41201 }
41202 label__loop__continue:;
41203 while (true) {
41204 if (a_minfo != NULL) {
41205 wuffs_base__more_information__set(a_minfo,
41206 self->private_impl.f_metadata_flavor,
41207 self->private_impl.f_metadata_fourcc,
41208 self->private_impl.f_metadata_x,
41209 self->private_impl.f_metadata_y,
41210 self->private_impl.f_metadata_z);
41211 }
41212 if (self->private_impl.f_metadata_flavor != 4) {
41213 goto label__loop__break;
41214 }
41215 if (self->private_impl.f_metadata_is_zlib_compressed) {
41216 if (self->private_impl.f_chunk_type == 1346585449) {
41217 {
41218 const uint8_t *o_0_io2_a_src = io2_a_src;
41219 wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
41220 ((uint64_t)(self->private_impl.f_chunk_length)));
41221 if (a_src) {
41222 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41223 }
41224 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
41225 {
41226 if (a_dst) {
41227 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
41228 }
41229 if (a_src) {
41230 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41231 }
41232 wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8());
41233 v_zlib_status = t_0;
41234 if (a_dst) {
41235 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
41236 }
41237 if (a_src) {
41238 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41239 }
41240 }
41241 wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)((wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))) & 4294967295))));
41242 io2_a_src = o_0_io2_a_src;
41243 if (a_src) {
41244 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41245 }
41246 }
41247 if (wuffs_base__status__is_ok(&v_zlib_status)) {
41248 self->private_impl.f_metadata_is_zlib_compressed = false;
41249 goto label__loop__break;
41250 } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
41251 status = v_zlib_status;
41252 if (wuffs_base__status__is_error(&status)) {
41253 goto exit;
41254 } else if (wuffs_base__status__is_suspension(&status)) {
41255 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
41256 goto exit;
41257 }
41258 goto ok;
41259 }
41260 status = v_zlib_status;
41261 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
41262 } else if (self->private_impl.f_chunk_type == 1951945833) {
41263 {
41264 const uint8_t *o_1_io2_a_src = io2_a_src;
41265 wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
41266 ((uint64_t)(self->private_impl.f_chunk_length)));
41267 if (a_src) {
41268 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41269 }
41270 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
41271 {
41272 if (a_dst) {
41273 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
41274 }
41275 if (a_src) {
41276 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41277 }
41278 wuffs_base__status t_1 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8());
41279 v_zlib_status = t_1;
41280 if (a_dst) {
41281 iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
41282 }
41283 if (a_src) {
41284 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41285 }
41286 }
41287 wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)((wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))) & 4294967295))));
41288 io2_a_src = o_1_io2_a_src;
41289 if (a_src) {
41290 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41291 }
41292 }
41293 if (wuffs_base__status__is_ok(&v_zlib_status)) {
41294 self->private_impl.f_metadata_is_zlib_compressed = false;
41295 goto label__loop__break;
41296 } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
41297 status = v_zlib_status;
41298 if (wuffs_base__status__is_error(&status)) {
41299 goto exit;
41300 } else if (wuffs_base__status__is_suspension(&status)) {
41301 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
41302 goto exit;
41303 }
41304 goto ok;
41305 }
41306 status = v_zlib_status;
41307 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
41308 } else if (self->private_impl.f_chunk_type == 1951945850) {
41309 if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) {
41310 {
41311 wuffs_base__io_buffer* o_2_v_w = v_w;
41312 uint8_t *o_2_iop_v_w = iop_v_w;
41313 uint8_t *o_2_io0_v_w = io0_v_w;
41314 uint8_t *o_2_io1_v_w = io1_v_w;
41315 uint8_t *o_2_io2_v_w = io2_v_w;
41316 v_w = wuffs_base__io_writer__set(
41317 &u_w,
41318 &iop_v_w,
41319 &io0_v_w,
41320 &io1_v_w,
41321 &io2_v_w,
41322 wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024),
41323 self->private_impl.f_ztxt_hist_pos);
41324 {
41325 const uint8_t *o_3_io2_a_src = io2_a_src;
41326 wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
41327 ((uint64_t)(self->private_impl.f_chunk_length)));
41328 if (a_src) {
41329 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41330 }
41331 v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
41332 v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
41333 {
41334 u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
41335 if (a_src) {
41336 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41337 }
41338 wuffs_base__status t_2 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8());
41339 v_zlib_status = t_2;
41340 iop_v_w = u_w.data.ptr + u_w.meta.wi;
41341 if (a_src) {
41342 iop_a_src = a_src->data.ptr + a_src->meta.ri;
41343 }
41344 }
41345 wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)((wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))) & 4294967295))));
41346 v_num_written = wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)));
41347 io2_a_src = o_3_io2_a_src;
41348 if (a_src) {
41349 a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
41350 }
41351 }
41352 v_w = o_2_v_w;
41353 iop_v_w = o_2_iop_v_w;
41354 io0_v_w = o_2_io0_v_w;
41355 io1_v_w = o_2_io1_v_w;
41356 io2_v_w = o_2_io2_v_w;
41357 }
41358 if (v_num_written > 1024) {
41359 status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o);
41360 goto exit;
41361 }
41362 self->private_impl.f_ztxt_ri = 0;
41363 self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written));
41364 wuffs_base__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written);
41365 }
41366 while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) {
41367 v_c2 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]];
41368 if (v_c2 == 0) {
41369 status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
41370 goto exit;
41371 } else if (v_c2 <= 127) {
41372 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
41373 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41374 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
41375 v_c2 = 0;
41376 goto label__loop__continue;
41377 }
41378 self->private_impl.f_ztxt_ri += 1;
41379 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
41380 } else {
41381 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
41382 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41383 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
41384 v_c2 = 0;
41385 goto label__loop__continue;
41386 }
41387 self->private_impl.f_ztxt_ri += 1;
41388 (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
41389 }
41390 }
41391 if (wuffs_base__status__is_ok(&v_zlib_status)) {
41392 self->private_impl.f_metadata_is_zlib_compressed = false;
41393 goto label__loop__break;
41394 } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
41395 status = v_zlib_status;
41396 if (wuffs_base__status__is_error(&status)) {
41397 goto exit;
41398 } else if (wuffs_base__status__is_suspension(&status)) {
41399 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
41400 goto exit;
41401 }
41402 goto ok;
41403 } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) {
41404 status = v_zlib_status;
41405 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
41406 }
41407 } else {
41408 status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type);
41409 goto exit;
41410 }
41411 } else if ((self->private_impl.f_chunk_type == 1951945833) && (self->private_impl.f_metadata_fourcc == 1263947862)) {
41412 while (true) {
41413 if (self->private_impl.f_chunk_length <= 0) {
41414 goto label__loop__break;
41415 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
41416 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41417 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
41418 goto label__loop__continue;
41419 } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
41420 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41421 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
41422 goto label__loop__continue;
41423 }
41424 self->private_impl.f_chunk_length -= 1;
41425 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
41426 iop_a_src += 1;
41427 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c), iop_a_dst += 1);
41428 }
41429 } else {
41430 while (true) {
41431 if (self->private_impl.f_chunk_length <= 0) {
41432 if (self->private_impl.f_metadata_fourcc == 1263947851) {
41433 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41434 goto exit;
41435 }
41436 goto label__loop__break;
41437 } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
41438 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41439 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
41440 goto label__loop__continue;
41441 }
41442 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
41443 if (v_c == 0) {
41444 self->private_impl.f_chunk_length -= 1;
41445 iop_a_src += 1;
41446 goto label__loop__break;
41447 }
41448 v_c2 = WUFFS_PNG__LATIN_1[v_c];
41449 if (v_c2 == 0) {
41450 status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
41451 goto exit;
41452 } else if (v_c2 <= 127) {
41453 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0) {
41454 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41455 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
41456 v_c2 = 0;
41457 goto label__loop__continue;
41458 }
41459 self->private_impl.f_chunk_length -= 1;
41460 iop_a_src += 1;
41461 (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
41462 } else {
41463 if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1) {
41464 status = wuffs_base__make_status(wuffs_base__suspension__short_write);
41465 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
41466 v_c2 = 0;
41467 goto label__loop__continue;
41468 }
41469 self->private_impl.f_chunk_length -= 1;
41470 iop_a_src += 1;
41471 (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
41472 }
41473 }
41474 }
41475 }
41476 label__loop__break:;
41477 if (self->private_impl.f_metadata_fourcc == 1263947851) {
41478 self->private_impl.f_metadata_fourcc = 1263947862;
41479 if (self->private_impl.f_chunk_type == 1951945833) {
41480 if (self->private_impl.f_chunk_length <= 1) {
41481 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41482 goto exit;
41483 }
41484 self->private_impl.f_chunk_length -= 2;
41485 {
41486 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
41487 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41488 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41489 goto suspend;
41490 }
41491 uint8_t t_3 = *iop_a_src++;
41492 v_c = t_3;
41493 }
41494 if (v_c == 0) {
41495 self->private_impl.f_metadata_is_zlib_compressed = false;
41496 } else if (v_c == 1) {
41497 self->private_impl.f_metadata_is_zlib_compressed = true;
41498 } else {
41499 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41500 goto exit;
41501 }
41502 {
41503 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
41504 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41505 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41506 goto suspend;
41507 }
41508 uint8_t t_4 = *iop_a_src++;
41509 v_c = t_4;
41510 }
41511 if ((v_c != 0) && self->private_impl.f_metadata_is_zlib_compressed) {
41512 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
41513 goto exit;
41514 }
41515 self->private_impl.f_metadata_fourcc -= 2;
41516 while (self->private_impl.f_metadata_fourcc != 1263947862) {
41517 self->private_impl.f_metadata_fourcc += 1;
41518 while (true) {
41519 if (self->private_impl.f_chunk_length <= 0) {
41520 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41521 goto exit;
41522 }
41523 self->private_impl.f_chunk_length -= 1;
41524 {
41525 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
41526 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41527 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41528 goto suspend;
41529 }
41530 uint8_t t_5 = *iop_a_src++;
41531 v_c = t_5;
41532 }
41533 if (v_c == 0) {
41534 goto label__0__break;
41535 }
41536 }
41537 label__0__break:;
41538 }
41539 } else if (self->private_impl.f_chunk_type == 1951945850) {
41540 if (self->private_impl.f_chunk_length <= 0) {
41541 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41542 goto exit;
41543 }
41544 self->private_impl.f_chunk_length -= 1;
41545 {
41546 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
41547 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
41548 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41549 goto suspend;
41550 }
41551 uint8_t t_6 = *iop_a_src++;
41552 v_c = t_6;
41553 }
41554 if (v_c != 0) {
41555 status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
41556 goto exit;
41557 }
41558 self->private_impl.f_metadata_is_zlib_compressed = true;
41559 }
41560 self->private_impl.f_call_sequence = 2;
41561 status = wuffs_base__make_status(NULL);
41562 goto ok;
41563 }
41564 goto label__goto_done__break;
41565 }
41566 label__goto_done__break:;
41567 if (self->private_impl.f_chunk_length != 0) {
41568 status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
41569 goto exit;
41570 }
41571 self->private_data.s_tell_me_more[0].scratch = 4;
41572 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
41573 if (self->private_data.s_tell_me_more[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
41574 self->private_data.s_tell_me_more[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
41575 iop_a_src = io2_a_src;
41576 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
41577 goto suspend;
41578 }
41579 iop_a_src += self->private_data.s_tell_me_more[0].scratch;
41580 self->private_impl.f_metadata_flavor = 0;
41581 self->private_impl.f_metadata_fourcc = 0;
41582 self->private_impl.f_metadata_x = 0;
41583 self->private_impl.f_metadata_y = 0;
41584 self->private_impl.f_metadata_z = 0;
41585 self->private_impl.f_call_sequence = 2;
41586 status = wuffs_base__make_status(NULL);
41587 goto ok;
41588
41589 ok:
41590 self->private_impl.p_tell_me_more[0] = 0;
41591 goto exit;
41592 }
41593
41594 goto suspend;
41595 suspend:
41596 self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
41597 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
41598 self->private_data.s_tell_me_more[0].v_zlib_status = v_zlib_status;
41599
41600 goto exit;
41601 exit:
41602 if (a_dst) {
41603 a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
41604 }
41605 if (a_src) {
41606 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
41607 }
41608
41609 if (wuffs_base__status__is_error(&status)) {
41610 self->private_impl.magic = WUFFS_BASE__DISABLED;
41611 }
41612 return status;
41613 }
41614
41615 // -------- func png.decoder.workbuf_len
41616
41617 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_png__decoder__workbuf_len(const wuffs_png__decoder * self)41618 wuffs_png__decoder__workbuf_len(
41619 const wuffs_png__decoder* self) {
41620 if (!self) {
41621 return wuffs_base__utility__empty_range_ii_u64();
41622 }
41623 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
41624 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
41625 return wuffs_base__utility__empty_range_ii_u64();
41626 }
41627
41628 return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length);
41629 }
41630
41631 // -------- func png.decoder.filter_and_swizzle
41632
41633 static wuffs_base__status
wuffs_png__decoder__filter_and_swizzle(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)41634 wuffs_png__decoder__filter_and_swizzle(
41635 wuffs_png__decoder* self,
41636 wuffs_base__pixel_buffer* a_dst,
41637 wuffs_base__slice_u8 a_workbuf) {
41638 return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf);
41639 }
41640
41641 static wuffs_base__status
wuffs_png__decoder__filter_and_swizzle__choosy_default(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)41642 wuffs_png__decoder__filter_and_swizzle__choosy_default(
41643 wuffs_png__decoder* self,
41644 wuffs_base__pixel_buffer* a_dst,
41645 wuffs_base__slice_u8 a_workbuf) {
41646 wuffs_base__pixel_format v_dst_pixfmt = {0};
41647 uint32_t v_dst_bits_per_pixel = 0;
41648 uint64_t v_dst_bytes_per_pixel = 0;
41649 uint64_t v_dst_bytes_per_row0 = 0;
41650 uint64_t v_dst_bytes_per_row1 = 0;
41651 wuffs_base__slice_u8 v_dst_palette = {0};
41652 wuffs_base__table_u8 v_tab = {0};
41653 uint32_t v_y = 0;
41654 wuffs_base__slice_u8 v_dst = {0};
41655 uint8_t v_filter = 0;
41656 wuffs_base__slice_u8 v_curr_row = {0};
41657 wuffs_base__slice_u8 v_prev_row = {0};
41658
41659 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
41660 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
41661 if ((v_dst_bits_per_pixel & 7) != 0) {
41662 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
41663 }
41664 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
41665 v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel);
41666 v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
41667 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
41668 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41669 if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) {
41670 v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41671 0,
41672 0,
41673 v_dst_bytes_per_row1,
41674 ((uint64_t)(v_tab.height)));
41675 }
41676 if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) {
41677 v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41678 v_dst_bytes_per_row0,
41679 0,
41680 ((uint64_t)(v_tab.width)),
41681 ((uint64_t)(v_tab.height)));
41682 } else {
41683 v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
41684 0,
41685 0,
41686 0,
41687 0);
41688 }
41689 v_y = self->private_impl.f_frame_rect_y0;
41690 while (v_y < self->private_impl.f_frame_rect_y1) {
41691 v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
41692 if (1 > ((uint64_t)(a_workbuf.len))) {
41693 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41694 }
41695 v_filter = a_workbuf.ptr[0];
41696 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1);
41697 if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
41698 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41699 }
41700 v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41701 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41702 if (v_filter == 0) {
41703 } else if (v_filter == 1) {
41704 wuffs_png__decoder__filter_1(self, v_curr_row);
41705 } else if (v_filter == 2) {
41706 wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
41707 } else if (v_filter == 3) {
41708 wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
41709 } else if (v_filter == 4) {
41710 wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
41711 } else {
41712 return wuffs_base__make_status(wuffs_png__error__bad_filter);
41713 }
41714 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row);
41715 v_prev_row = v_curr_row;
41716 v_y += 1;
41717 }
41718 return wuffs_base__make_status(NULL);
41719 }
41720
41721 // -------- func png.decoder.filter_and_swizzle_tricky
41722
41723 static wuffs_base__status
wuffs_png__decoder__filter_and_swizzle_tricky(wuffs_png__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__slice_u8 a_workbuf)41724 wuffs_png__decoder__filter_and_swizzle_tricky(
41725 wuffs_png__decoder* self,
41726 wuffs_base__pixel_buffer* a_dst,
41727 wuffs_base__slice_u8 a_workbuf) {
41728 wuffs_base__pixel_format v_dst_pixfmt = {0};
41729 uint32_t v_dst_bits_per_pixel = 0;
41730 uint64_t v_dst_bytes_per_pixel = 0;
41731 uint64_t v_dst_bytes_per_row1 = 0;
41732 wuffs_base__slice_u8 v_dst_palette = {0};
41733 wuffs_base__table_u8 v_tab = {0};
41734 uint64_t v_src_bytes_per_pixel = 0;
41735 uint32_t v_x = 0;
41736 uint32_t v_y = 0;
41737 uint64_t v_i = 0;
41738 wuffs_base__slice_u8 v_dst = {0};
41739 uint8_t v_filter = 0;
41740 wuffs_base__slice_u8 v_s = {0};
41741 wuffs_base__slice_u8 v_curr_row = {0};
41742 wuffs_base__slice_u8 v_prev_row = {0};
41743 uint8_t v_bits_unpacked[8] = {0};
41744 uint8_t v_bits_packed = 0;
41745 uint8_t v_packs_remaining = 0;
41746 uint8_t v_multiplier = 0;
41747 uint8_t v_shift = 0;
41748
41749 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
41750 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
41751 if ((v_dst_bits_per_pixel & 7) != 0) {
41752 return wuffs_base__make_status(wuffs_base__error__unsupported_option);
41753 }
41754 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
41755 v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
41756 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
41757 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
41758 v_src_bytes_per_pixel = 1;
41759 if (self->private_impl.f_depth >= 8) {
41760 v_src_bytes_per_pixel = (((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])) * ((uint64_t)((self->private_impl.f_depth >> 3))));
41761 }
41762 if (self->private_impl.f_chunk_type_array[0] == 73) {
41763 v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5]));
41764 } else {
41765 v_y = self->private_impl.f_frame_rect_y0;
41766 }
41767 while (v_y < self->private_impl.f_frame_rect_y1) {
41768 v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
41769 if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) {
41770 v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1);
41771 }
41772 if (1 > ((uint64_t)(a_workbuf.len))) {
41773 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41774 }
41775 v_filter = a_workbuf.ptr[0];
41776 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1);
41777 if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
41778 return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
41779 }
41780 v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41781 a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
41782 if (v_filter == 0) {
41783 } else if (v_filter == 1) {
41784 wuffs_png__decoder__filter_1(self, v_curr_row);
41785 } else if (v_filter == 2) {
41786 wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
41787 } else if (v_filter == 3) {
41788 wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
41789 } else if (v_filter == 4) {
41790 wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
41791 } else {
41792 return wuffs_base__make_status(wuffs_png__error__bad_filter);
41793 }
41794 v_s = v_curr_row;
41795 if (self->private_impl.f_chunk_type_array[0] == 73) {
41796 v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2]));
41797 } else {
41798 v_x = self->private_impl.f_frame_rect_x0;
41799 }
41800 if (self->private_impl.f_depth == 8) {
41801 while (v_x < self->private_impl.f_frame_rect_x1) {
41802 v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41803 if (v_i <= ((uint64_t)(v_dst.len))) {
41804 if (self->private_impl.f_color_type == 4) {
41805 if (2 <= ((uint64_t)(v_s.len))) {
41806 v_bits_unpacked[0] = v_s.ptr[0];
41807 v_bits_unpacked[1] = v_s.ptr[0];
41808 v_bits_unpacked[2] = v_s.ptr[0];
41809 v_bits_unpacked[3] = v_s.ptr[1];
41810 v_s = wuffs_base__slice_u8__subslice_i(v_s, 2);
41811 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
41812 }
41813 } else if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) != 0) {
41814 if (self->private_impl.f_color_type == 0) {
41815 if (1 <= ((uint64_t)(v_s.len))) {
41816 v_bits_unpacked[0] = v_s.ptr[0];
41817 v_bits_unpacked[1] = v_s.ptr[0];
41818 v_bits_unpacked[2] = v_s.ptr[0];
41819 v_bits_unpacked[3] = 255;
41820 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1);
41821 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41822 (((uint32_t)(v_bits_unpacked[1])) << 8) |
41823 (((uint32_t)(v_bits_unpacked[2])) << 16) |
41824 (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41825 v_bits_unpacked[0] = 0;
41826 v_bits_unpacked[1] = 0;
41827 v_bits_unpacked[2] = 0;
41828 v_bits_unpacked[3] = 0;
41829 }
41830 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
41831 }
41832 } else {
41833 if (3 <= ((uint64_t)(v_s.len))) {
41834 v_bits_unpacked[0] = v_s.ptr[2];
41835 v_bits_unpacked[1] = v_s.ptr[1];
41836 v_bits_unpacked[2] = v_s.ptr[0];
41837 v_bits_unpacked[3] = 255;
41838 v_s = wuffs_base__slice_u8__subslice_i(v_s, 3);
41839 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41840 (((uint32_t)(v_bits_unpacked[1])) << 8) |
41841 (((uint32_t)(v_bits_unpacked[2])) << 16) |
41842 (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41843 v_bits_unpacked[0] = 0;
41844 v_bits_unpacked[1] = 0;
41845 v_bits_unpacked[2] = 0;
41846 v_bits_unpacked[3] = 0;
41847 }
41848 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
41849 }
41850 }
41851 } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) {
41852 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__slice_u8__subslice_j(v_s, v_src_bytes_per_pixel));
41853 v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel);
41854 }
41855 }
41856 v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41857 }
41858 } else if (self->private_impl.f_depth < 8) {
41859 v_multiplier = 1;
41860 if (self->private_impl.f_color_type == 0) {
41861 v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth];
41862 }
41863 v_shift = ((8 - self->private_impl.f_depth) & 7);
41864 v_packs_remaining = 0;
41865 while (v_x < self->private_impl.f_frame_rect_x1) {
41866 v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41867 if (v_i <= ((uint64_t)(v_dst.len))) {
41868 if ((v_packs_remaining == 0) && (1 <= ((uint64_t)(v_s.len)))) {
41869 v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth];
41870 v_bits_packed = v_s.ptr[0];
41871 v_s = wuffs_base__slice_u8__subslice_i(v_s, 1);
41872 }
41873 v_bits_unpacked[0] = ((uint8_t)((v_bits_packed >> v_shift) * v_multiplier));
41874 v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth));
41875 v_packs_remaining = ((uint8_t)(v_packs_remaining - 1));
41876 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) != 0) {
41877 v_bits_unpacked[1] = v_bits_unpacked[0];
41878 v_bits_unpacked[2] = v_bits_unpacked[0];
41879 v_bits_unpacked[3] = 255;
41880 if (((uint32_t)((self->private_impl.f_remap_transparency & 4294967295))) == ((((uint32_t)(v_bits_unpacked[0])) << 0) |
41881 (((uint32_t)(v_bits_unpacked[1])) << 8) |
41882 (((uint32_t)(v_bits_unpacked[2])) << 16) |
41883 (((uint32_t)(v_bits_unpacked[3])) << 24))) {
41884 v_bits_unpacked[0] = 0;
41885 v_bits_unpacked[1] = 0;
41886 v_bits_unpacked[2] = 0;
41887 v_bits_unpacked[3] = 0;
41888 }
41889 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
41890 } else {
41891 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 1));
41892 }
41893 }
41894 v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41895 }
41896 } else {
41897 while (v_x < self->private_impl.f_frame_rect_x1) {
41898 v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
41899 if (v_i <= ((uint64_t)(v_dst.len))) {
41900 if (self->private_impl.f_color_type == 0) {
41901 if (2 <= ((uint64_t)(v_s.len))) {
41902 v_bits_unpacked[0] = v_s.ptr[1];
41903 v_bits_unpacked[1] = v_s.ptr[0];
41904 v_bits_unpacked[2] = v_s.ptr[1];
41905 v_bits_unpacked[3] = v_s.ptr[0];
41906 v_bits_unpacked[4] = v_s.ptr[1];
41907 v_bits_unpacked[5] = v_s.ptr[0];
41908 v_bits_unpacked[6] = 255;
41909 v_bits_unpacked[7] = 255;
41910 v_s = wuffs_base__slice_u8__subslice_i(v_s, 2);
41911 if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0])) << 0) |
41912 (((uint64_t)(v_bits_unpacked[1])) << 8) |
41913 (((uint64_t)(v_bits_unpacked[2])) << 16) |
41914 (((uint64_t)(v_bits_unpacked[3])) << 24) |
41915 (((uint64_t)(v_bits_unpacked[4])) << 32) |
41916 (((uint64_t)(v_bits_unpacked[5])) << 40) |
41917 (((uint64_t)(v_bits_unpacked[6])) << 48) |
41918 (((uint64_t)(v_bits_unpacked[7])) << 56))) {
41919 v_bits_unpacked[0] = 0;
41920 v_bits_unpacked[1] = 0;
41921 v_bits_unpacked[2] = 0;
41922 v_bits_unpacked[3] = 0;
41923 v_bits_unpacked[4] = 0;
41924 v_bits_unpacked[5] = 0;
41925 v_bits_unpacked[6] = 0;
41926 v_bits_unpacked[7] = 0;
41927 }
41928 }
41929 } else if (self->private_impl.f_color_type == 2) {
41930 if (6 <= ((uint64_t)(v_s.len))) {
41931 v_bits_unpacked[0] = v_s.ptr[5];
41932 v_bits_unpacked[1] = v_s.ptr[4];
41933 v_bits_unpacked[2] = v_s.ptr[3];
41934 v_bits_unpacked[3] = v_s.ptr[2];
41935 v_bits_unpacked[4] = v_s.ptr[1];
41936 v_bits_unpacked[5] = v_s.ptr[0];
41937 v_bits_unpacked[6] = 255;
41938 v_bits_unpacked[7] = 255;
41939 v_s = wuffs_base__slice_u8__subslice_i(v_s, 6);
41940 if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0])) << 0) |
41941 (((uint64_t)(v_bits_unpacked[1])) << 8) |
41942 (((uint64_t)(v_bits_unpacked[2])) << 16) |
41943 (((uint64_t)(v_bits_unpacked[3])) << 24) |
41944 (((uint64_t)(v_bits_unpacked[4])) << 32) |
41945 (((uint64_t)(v_bits_unpacked[5])) << 40) |
41946 (((uint64_t)(v_bits_unpacked[6])) << 48) |
41947 (((uint64_t)(v_bits_unpacked[7])) << 56))) {
41948 v_bits_unpacked[0] = 0;
41949 v_bits_unpacked[1] = 0;
41950 v_bits_unpacked[2] = 0;
41951 v_bits_unpacked[3] = 0;
41952 v_bits_unpacked[4] = 0;
41953 v_bits_unpacked[5] = 0;
41954 v_bits_unpacked[6] = 0;
41955 v_bits_unpacked[7] = 0;
41956 }
41957 }
41958 } else if (self->private_impl.f_color_type == 4) {
41959 if (4 <= ((uint64_t)(v_s.len))) {
41960 v_bits_unpacked[0] = v_s.ptr[1];
41961 v_bits_unpacked[1] = v_s.ptr[0];
41962 v_bits_unpacked[2] = v_s.ptr[1];
41963 v_bits_unpacked[3] = v_s.ptr[0];
41964 v_bits_unpacked[4] = v_s.ptr[1];
41965 v_bits_unpacked[5] = v_s.ptr[0];
41966 v_bits_unpacked[6] = v_s.ptr[3];
41967 v_bits_unpacked[7] = v_s.ptr[2];
41968 v_s = wuffs_base__slice_u8__subslice_i(v_s, 4);
41969 }
41970 } else {
41971 if (8 <= ((uint64_t)(v_s.len))) {
41972 v_bits_unpacked[0] = v_s.ptr[5];
41973 v_bits_unpacked[1] = v_s.ptr[4];
41974 v_bits_unpacked[2] = v_s.ptr[3];
41975 v_bits_unpacked[3] = v_s.ptr[2];
41976 v_bits_unpacked[4] = v_s.ptr[1];
41977 v_bits_unpacked[5] = v_s.ptr[0];
41978 v_bits_unpacked[6] = v_s.ptr[7];
41979 v_bits_unpacked[7] = v_s.ptr[6];
41980 v_s = wuffs_base__slice_u8__subslice_i(v_s, 8);
41981 }
41982 }
41983 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 8));
41984 }
41985 v_x += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0]);
41986 }
41987 }
41988 v_prev_row = v_curr_row;
41989 v_y += (((uint32_t)(1)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3]);
41990 }
41991 return wuffs_base__make_status(NULL);
41992 }
41993
41994 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
41995
41996 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
41997
41998 // ---------------- Status Codes Implementations
41999
42000 const char wuffs_tga__error__bad_header[] = "#tga: bad header";
42001 const char wuffs_tga__error__bad_run_length_encoding[] = "#tga: bad run length encoding";
42002 const char wuffs_tga__error__unsupported_tga_file[] = "#tga: unsupported TGA file";
42003
42004 // ---------------- Private Consts
42005
42006 // ---------------- Private Initializer Prototypes
42007
42008 // ---------------- Private Function Prototypes
42009
42010 // ---------------- VTables
42011
42012 const wuffs_base__image_decoder__func_ptrs
42013 wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder = {
42014 (wuffs_base__status(*)(void*,
42015 wuffs_base__pixel_buffer*,
42016 wuffs_base__io_buffer*,
42017 wuffs_base__pixel_blend,
42018 wuffs_base__slice_u8,
42019 wuffs_base__decode_frame_options*))(&wuffs_tga__decoder__decode_frame),
42020 (wuffs_base__status(*)(void*,
42021 wuffs_base__frame_config*,
42022 wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_frame_config),
42023 (wuffs_base__status(*)(void*,
42024 wuffs_base__image_config*,
42025 wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_image_config),
42026 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_tga__decoder__frame_dirty_rect),
42027 (uint32_t(*)(const void*))(&wuffs_tga__decoder__num_animation_loops),
42028 (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frame_configs),
42029 (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frames),
42030 (wuffs_base__status(*)(void*,
42031 uint64_t,
42032 uint64_t))(&wuffs_tga__decoder__restart_frame),
42033 (wuffs_base__empty_struct(*)(void*,
42034 uint32_t,
42035 bool))(&wuffs_tga__decoder__set_quirk_enabled),
42036 (wuffs_base__empty_struct(*)(void*,
42037 uint32_t,
42038 bool))(&wuffs_tga__decoder__set_report_metadata),
42039 (wuffs_base__status(*)(void*,
42040 wuffs_base__io_buffer*,
42041 wuffs_base__more_information*,
42042 wuffs_base__io_buffer*))(&wuffs_tga__decoder__tell_me_more),
42043 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_tga__decoder__workbuf_len),
42044 };
42045
42046 // ---------------- Initializer Implementations
42047
42048 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_tga__decoder__initialize(wuffs_tga__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)42049 wuffs_tga__decoder__initialize(
42050 wuffs_tga__decoder* self,
42051 size_t sizeof_star_self,
42052 uint64_t wuffs_version,
42053 uint32_t options){
42054 if (!self) {
42055 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42056 }
42057 if (sizeof(*self) != sizeof_star_self) {
42058 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
42059 }
42060 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
42061 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
42062 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
42063 }
42064
42065 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
42066 // The whole point of this if-check is to detect an uninitialized *self.
42067 // We disable the warning on GCC. Clang-5.0 does not have this warning.
42068 #if !defined(__clang__) && defined(__GNUC__)
42069 #pragma GCC diagnostic push
42070 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
42071 #endif
42072 if (self->private_impl.magic != 0) {
42073 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
42074 }
42075 #if !defined(__clang__) && defined(__GNUC__)
42076 #pragma GCC diagnostic pop
42077 #endif
42078 } else {
42079 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
42080 memset(self, 0, sizeof(*self));
42081 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
42082 } else {
42083 memset(&(self->private_impl), 0, sizeof(self->private_impl));
42084 }
42085 }
42086
42087 self->private_impl.magic = WUFFS_BASE__MAGIC;
42088 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
42089 wuffs_base__image_decoder__vtable_name;
42090 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
42091 (const void*)(&wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder);
42092 return wuffs_base__make_status(NULL);
42093 }
42094
42095 wuffs_tga__decoder*
wuffs_tga__decoder__alloc()42096 wuffs_tga__decoder__alloc() {
42097 wuffs_tga__decoder* x =
42098 (wuffs_tga__decoder*)(calloc(sizeof(wuffs_tga__decoder), 1));
42099 if (!x) {
42100 return NULL;
42101 }
42102 if (wuffs_tga__decoder__initialize(
42103 x, sizeof(wuffs_tga__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
42104 free(x);
42105 return NULL;
42106 }
42107 return x;
42108 }
42109
42110 size_t
sizeof__wuffs_tga__decoder()42111 sizeof__wuffs_tga__decoder() {
42112 return sizeof(wuffs_tga__decoder);
42113 }
42114
42115 // ---------------- Function Implementations
42116
42117 // -------- func tga.decoder.set_quirk_enabled
42118
42119 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_tga__decoder__set_quirk_enabled(wuffs_tga__decoder * self,uint32_t a_quirk,bool a_enabled)42120 wuffs_tga__decoder__set_quirk_enabled(
42121 wuffs_tga__decoder* self,
42122 uint32_t a_quirk,
42123 bool a_enabled) {
42124 return wuffs_base__make_empty_struct();
42125 }
42126
42127 // -------- func tga.decoder.decode_image_config
42128
42129 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_image_config(wuffs_tga__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)42130 wuffs_tga__decoder__decode_image_config(
42131 wuffs_tga__decoder* self,
42132 wuffs_base__image_config* a_dst,
42133 wuffs_base__io_buffer* a_src) {
42134 if (!self) {
42135 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42136 }
42137 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42138 return wuffs_base__make_status(
42139 (self->private_impl.magic == WUFFS_BASE__DISABLED)
42140 ? wuffs_base__error__disabled_by_previous_error
42141 : wuffs_base__error__initialize_not_called);
42142 }
42143 if (!a_src) {
42144 self->private_impl.magic = WUFFS_BASE__DISABLED;
42145 return wuffs_base__make_status(wuffs_base__error__bad_argument);
42146 }
42147 if ((self->private_impl.active_coroutine != 0) &&
42148 (self->private_impl.active_coroutine != 1)) {
42149 self->private_impl.magic = WUFFS_BASE__DISABLED;
42150 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42151 }
42152 self->private_impl.active_coroutine = 0;
42153 wuffs_base__status status = wuffs_base__make_status(NULL);
42154
42155 uint32_t v_c = 0;
42156 uint32_t v_c5 = 0;
42157 uint32_t v_i = 0;
42158
42159 const uint8_t* iop_a_src = NULL;
42160 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42161 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42162 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42163 if (a_src) {
42164 io0_a_src = a_src->data.ptr;
42165 io1_a_src = io0_a_src + a_src->meta.ri;
42166 iop_a_src = io1_a_src;
42167 io2_a_src = io0_a_src + a_src->meta.wi;
42168 }
42169
42170 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
42171 if (coro_susp_point) {
42172 v_i = self->private_data.s_decode_image_config[0].v_i;
42173 }
42174 switch (coro_susp_point) {
42175 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42176
42177 if (self->private_impl.f_call_sequence != 0) {
42178 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
42179 goto exit;
42180 }
42181 {
42182 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42183 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42184 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42185 goto suspend;
42186 }
42187 uint8_t t_0 = *iop_a_src++;
42188 self->private_impl.f_header_id_length = t_0;
42189 }
42190 {
42191 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42192 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42193 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42194 goto suspend;
42195 }
42196 uint8_t t_1 = *iop_a_src++;
42197 self->private_impl.f_header_color_map_type = t_1;
42198 }
42199 if (self->private_impl.f_header_color_map_type > 1) {
42200 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42201 goto exit;
42202 }
42203 {
42204 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
42205 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42206 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42207 goto suspend;
42208 }
42209 uint8_t t_2 = *iop_a_src++;
42210 self->private_impl.f_header_image_type = t_2;
42211 }
42212 if ((self->private_impl.f_header_image_type == 1) ||
42213 (self->private_impl.f_header_image_type == 2) ||
42214 (self->private_impl.f_header_image_type == 3) ||
42215 (self->private_impl.f_header_image_type == 9) ||
42216 (self->private_impl.f_header_image_type == 10) ||
42217 (self->private_impl.f_header_image_type == 11)) {
42218 } else {
42219 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42220 goto exit;
42221 }
42222 {
42223 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
42224 uint16_t t_3;
42225 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42226 t_3 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
42227 iop_a_src += 2;
42228 } else {
42229 self->private_data.s_decode_image_config[0].scratch = 0;
42230 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
42231 while (true) {
42232 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42233 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42234 goto suspend;
42235 }
42236 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42237 uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
42238 *scratch <<= 8;
42239 *scratch >>= 8;
42240 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
42241 if (num_bits_3 == 8) {
42242 t_3 = ((uint16_t)(*scratch));
42243 break;
42244 }
42245 num_bits_3 += 8;
42246 *scratch |= ((uint64_t)(num_bits_3)) << 56;
42247 }
42248 }
42249 self->private_impl.f_header_color_map_first_entry_index = t_3;
42250 }
42251 {
42252 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
42253 uint16_t t_4;
42254 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42255 t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
42256 iop_a_src += 2;
42257 } else {
42258 self->private_data.s_decode_image_config[0].scratch = 0;
42259 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
42260 while (true) {
42261 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42262 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42263 goto suspend;
42264 }
42265 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42266 uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
42267 *scratch <<= 8;
42268 *scratch >>= 8;
42269 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
42270 if (num_bits_4 == 8) {
42271 t_4 = ((uint16_t)(*scratch));
42272 break;
42273 }
42274 num_bits_4 += 8;
42275 *scratch |= ((uint64_t)(num_bits_4)) << 56;
42276 }
42277 }
42278 self->private_impl.f_header_color_map_length = t_4;
42279 }
42280 {
42281 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
42282 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42283 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42284 goto suspend;
42285 }
42286 uint8_t t_5 = *iop_a_src++;
42287 self->private_impl.f_header_color_map_entry_size = t_5;
42288 }
42289 if (self->private_impl.f_header_color_map_type != 0) {
42290 if ((self->private_impl.f_header_color_map_first_entry_index != 0) || (self->private_impl.f_header_color_map_length > 256)) {
42291 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42292 goto exit;
42293 } else if ((self->private_impl.f_header_color_map_entry_size != 15) &&
42294 (self->private_impl.f_header_color_map_entry_size != 16) &&
42295 (self->private_impl.f_header_color_map_entry_size != 24) &&
42296 (self->private_impl.f_header_color_map_entry_size != 32)) {
42297 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42298 goto exit;
42299 }
42300 } else {
42301 if ((self->private_impl.f_header_color_map_first_entry_index != 0) || (self->private_impl.f_header_color_map_length != 0) || (self->private_impl.f_header_color_map_entry_size != 0)) {
42302 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42303 goto exit;
42304 }
42305 }
42306 self->private_data.s_decode_image_config[0].scratch = 4;
42307 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
42308 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42309 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42310 iop_a_src = io2_a_src;
42311 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42312 goto suspend;
42313 }
42314 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
42315 {
42316 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
42317 uint32_t t_6;
42318 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42319 t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42320 iop_a_src += 2;
42321 } else {
42322 self->private_data.s_decode_image_config[0].scratch = 0;
42323 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
42324 while (true) {
42325 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42326 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42327 goto suspend;
42328 }
42329 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42330 uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
42331 *scratch <<= 8;
42332 *scratch >>= 8;
42333 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
42334 if (num_bits_6 == 8) {
42335 t_6 = ((uint32_t)(*scratch));
42336 break;
42337 }
42338 num_bits_6 += 8;
42339 *scratch |= ((uint64_t)(num_bits_6)) << 56;
42340 }
42341 }
42342 self->private_impl.f_width = t_6;
42343 }
42344 {
42345 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
42346 uint32_t t_7;
42347 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42348 t_7 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42349 iop_a_src += 2;
42350 } else {
42351 self->private_data.s_decode_image_config[0].scratch = 0;
42352 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
42353 while (true) {
42354 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42355 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42356 goto suspend;
42357 }
42358 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42359 uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
42360 *scratch <<= 8;
42361 *scratch >>= 8;
42362 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
42363 if (num_bits_7 == 8) {
42364 t_7 = ((uint32_t)(*scratch));
42365 break;
42366 }
42367 num_bits_7 += 8;
42368 *scratch |= ((uint64_t)(num_bits_7)) << 56;
42369 }
42370 }
42371 self->private_impl.f_height = t_7;
42372 }
42373 {
42374 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
42375 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42376 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42377 goto suspend;
42378 }
42379 uint8_t t_8 = *iop_a_src++;
42380 self->private_impl.f_header_pixel_depth = t_8;
42381 }
42382 if ((self->private_impl.f_header_pixel_depth != 1) &&
42383 (self->private_impl.f_header_pixel_depth != 8) &&
42384 (self->private_impl.f_header_pixel_depth != 15) &&
42385 (self->private_impl.f_header_pixel_depth != 16) &&
42386 (self->private_impl.f_header_pixel_depth != 24) &&
42387 (self->private_impl.f_header_pixel_depth != 32)) {
42388 status = wuffs_base__make_status(wuffs_tga__error__bad_header);
42389 goto exit;
42390 }
42391 if ((self->private_impl.f_header_image_type | 8) == 9) {
42392 self->private_impl.f_scratch_bytes_per_pixel = 1;
42393 self->private_impl.f_src_bytes_per_pixel = 1;
42394 self->private_impl.f_src_pixfmt = 2164523016;
42395 self->private_impl.f_opaque = ((self->private_impl.f_header_color_map_entry_size == 15) || (self->private_impl.f_header_color_map_entry_size == 24));
42396 } else if ((self->private_impl.f_header_image_type | 8) == 10) {
42397 if ((self->private_impl.f_header_pixel_depth == 15) || (self->private_impl.f_header_pixel_depth == 16)) {
42398 self->private_impl.f_scratch_bytes_per_pixel = 4;
42399 self->private_impl.f_src_bytes_per_pixel = 0;
42400 self->private_impl.f_src_pixfmt = 2164295816;
42401 } else if (self->private_impl.f_header_pixel_depth == 24) {
42402 self->private_impl.f_scratch_bytes_per_pixel = 3;
42403 self->private_impl.f_src_bytes_per_pixel = 3;
42404 self->private_impl.f_src_pixfmt = 2147485832;
42405 self->private_impl.f_opaque = true;
42406 } else if (self->private_impl.f_header_pixel_depth == 32) {
42407 self->private_impl.f_scratch_bytes_per_pixel = 4;
42408 self->private_impl.f_src_bytes_per_pixel = 4;
42409 self->private_impl.f_src_pixfmt = 2164295816;
42410 } else {
42411 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42412 goto exit;
42413 }
42414 } else {
42415 if (self->private_impl.f_header_pixel_depth == 8) {
42416 self->private_impl.f_scratch_bytes_per_pixel = 1;
42417 self->private_impl.f_src_bytes_per_pixel = 1;
42418 self->private_impl.f_src_pixfmt = 536870920;
42419 self->private_impl.f_opaque = true;
42420 } else {
42421 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42422 goto exit;
42423 }
42424 }
42425 {
42426 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
42427 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42428 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42429 goto suspend;
42430 }
42431 uint8_t t_9 = *iop_a_src++;
42432 self->private_impl.f_header_image_descriptor = t_9;
42433 }
42434 if ((self->private_impl.f_header_image_descriptor & 16) != 0) {
42435 status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
42436 goto exit;
42437 }
42438 self->private_data.s_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_header_id_length));
42439 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
42440 if (self->private_data.s_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42441 self->private_data.s_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42442 iop_a_src = io2_a_src;
42443 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42444 goto suspend;
42445 }
42446 iop_a_src += self->private_data.s_decode_image_config[0].scratch;
42447 if (self->private_impl.f_header_color_map_type != 0) {
42448 while (v_i < ((uint32_t)(self->private_impl.f_header_color_map_length))) {
42449 if (self->private_impl.f_header_color_map_entry_size == 24) {
42450 {
42451 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
42452 uint32_t t_10;
42453 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
42454 t_10 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
42455 iop_a_src += 3;
42456 } else {
42457 self->private_data.s_decode_image_config[0].scratch = 0;
42458 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
42459 while (true) {
42460 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42461 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42462 goto suspend;
42463 }
42464 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42465 uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
42466 *scratch <<= 8;
42467 *scratch >>= 8;
42468 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
42469 if (num_bits_10 == 16) {
42470 t_10 = ((uint32_t)(*scratch));
42471 break;
42472 }
42473 num_bits_10 += 8;
42474 *scratch |= ((uint64_t)(num_bits_10)) << 56;
42475 }
42476 }
42477 v_c = t_10;
42478 }
42479 self->private_data.f_src_palette[(((v_i & 255) * 4) + 0)] = ((uint8_t)(((v_c >> 0) & 255)));
42480 self->private_data.f_src_palette[(((v_i & 255) * 4) + 1)] = ((uint8_t)(((v_c >> 8) & 255)));
42481 self->private_data.f_src_palette[(((v_i & 255) * 4) + 2)] = ((uint8_t)(((v_c >> 16) & 255)));
42482 self->private_data.f_src_palette[(((v_i & 255) * 4) + 3)] = 255;
42483 } else if (self->private_impl.f_header_color_map_entry_size == 32) {
42484 {
42485 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
42486 uint32_t t_11;
42487 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
42488 t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
42489 iop_a_src += 4;
42490 } else {
42491 self->private_data.s_decode_image_config[0].scratch = 0;
42492 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
42493 while (true) {
42494 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42495 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42496 goto suspend;
42497 }
42498 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42499 uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
42500 *scratch <<= 8;
42501 *scratch >>= 8;
42502 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
42503 if (num_bits_11 == 24) {
42504 t_11 = ((uint32_t)(*scratch));
42505 break;
42506 }
42507 num_bits_11 += 8;
42508 *scratch |= ((uint64_t)(num_bits_11)) << 56;
42509 }
42510 }
42511 v_c = t_11;
42512 }
42513 self->private_data.f_src_palette[(((v_i & 255) * 4) + 0)] = ((uint8_t)(((v_c >> 0) & 255)));
42514 self->private_data.f_src_palette[(((v_i & 255) * 4) + 1)] = ((uint8_t)(((v_c >> 8) & 255)));
42515 self->private_data.f_src_palette[(((v_i & 255) * 4) + 2)] = ((uint8_t)(((v_c >> 16) & 255)));
42516 self->private_data.f_src_palette[(((v_i & 255) * 4) + 3)] = ((uint8_t)(((v_c >> 24) & 255)));
42517 } else {
42518 {
42519 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
42520 uint32_t t_12;
42521 if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
42522 t_12 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42523 iop_a_src += 2;
42524 } else {
42525 self->private_data.s_decode_image_config[0].scratch = 0;
42526 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
42527 while (true) {
42528 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
42529 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42530 goto suspend;
42531 }
42532 uint64_t* scratch = &self->private_data.s_decode_image_config[0].scratch;
42533 uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
42534 *scratch <<= 8;
42535 *scratch >>= 8;
42536 *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
42537 if (num_bits_12 == 8) {
42538 t_12 = ((uint32_t)(*scratch));
42539 break;
42540 }
42541 num_bits_12 += 8;
42542 *scratch |= ((uint64_t)(num_bits_12)) << 56;
42543 }
42544 }
42545 v_c = t_12;
42546 }
42547 v_c5 = (31 & (v_c >> 0));
42548 self->private_data.f_src_palette[(((v_i & 255) * 4) + 0)] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42549 v_c5 = (31 & (v_c >> 5));
42550 self->private_data.f_src_palette[(((v_i & 255) * 4) + 1)] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42551 v_c5 = (31 & (v_c >> 10));
42552 self->private_data.f_src_palette[(((v_i & 255) * 4) + 2)] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42553 self->private_data.f_src_palette[(((v_i & 255) * 4) + 3)] = 255;
42554 }
42555 v_i += 1;
42556 }
42557 while (v_i < 256) {
42558 self->private_data.f_src_palette[((v_i * 4) + 0)] = 0;
42559 self->private_data.f_src_palette[((v_i * 4) + 1)] = 0;
42560 self->private_data.f_src_palette[((v_i * 4) + 2)] = 0;
42561 self->private_data.f_src_palette[((v_i * 4) + 3)] = 255;
42562 v_i += 1;
42563 }
42564 }
42565 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
42566 if (a_dst != NULL) {
42567 wuffs_base__image_config__set(
42568 a_dst,
42569 self->private_impl.f_src_pixfmt,
42570 0,
42571 self->private_impl.f_width,
42572 self->private_impl.f_height,
42573 self->private_impl.f_frame_config_io_position,
42574 self->private_impl.f_opaque);
42575 }
42576 self->private_impl.f_call_sequence = 3;
42577
42578 goto ok;
42579 ok:
42580 self->private_impl.p_decode_image_config[0] = 0;
42581 goto exit;
42582 }
42583
42584 goto suspend;
42585 suspend:
42586 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42587 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
42588 self->private_data.s_decode_image_config[0].v_i = v_i;
42589
42590 goto exit;
42591 exit:
42592 if (a_src) {
42593 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42594 }
42595
42596 if (wuffs_base__status__is_error(&status)) {
42597 self->private_impl.magic = WUFFS_BASE__DISABLED;
42598 }
42599 return status;
42600 }
42601
42602 // -------- func tga.decoder.decode_frame_config
42603
42604 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_frame_config(wuffs_tga__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)42605 wuffs_tga__decoder__decode_frame_config(
42606 wuffs_tga__decoder* self,
42607 wuffs_base__frame_config* a_dst,
42608 wuffs_base__io_buffer* a_src) {
42609 if (!self) {
42610 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42611 }
42612 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42613 return wuffs_base__make_status(
42614 (self->private_impl.magic == WUFFS_BASE__DISABLED)
42615 ? wuffs_base__error__disabled_by_previous_error
42616 : wuffs_base__error__initialize_not_called);
42617 }
42618 if (!a_src) {
42619 self->private_impl.magic = WUFFS_BASE__DISABLED;
42620 return wuffs_base__make_status(wuffs_base__error__bad_argument);
42621 }
42622 if ((self->private_impl.active_coroutine != 0) &&
42623 (self->private_impl.active_coroutine != 2)) {
42624 self->private_impl.magic = WUFFS_BASE__DISABLED;
42625 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42626 }
42627 self->private_impl.active_coroutine = 0;
42628 wuffs_base__status status = wuffs_base__make_status(NULL);
42629
42630 const uint8_t* iop_a_src = NULL;
42631 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42632 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42633 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42634 if (a_src) {
42635 io0_a_src = a_src->data.ptr;
42636 io1_a_src = io0_a_src + a_src->meta.ri;
42637 iop_a_src = io1_a_src;
42638 io2_a_src = io0_a_src + a_src->meta.wi;
42639 }
42640
42641 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
42642 switch (coro_susp_point) {
42643 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42644
42645 if (self->private_impl.f_call_sequence < 3) {
42646 if (a_src) {
42647 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42648 }
42649 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42650 status = wuffs_tga__decoder__decode_image_config(self, NULL, a_src);
42651 if (a_src) {
42652 iop_a_src = a_src->data.ptr + a_src->meta.ri;
42653 }
42654 if (status.repr) {
42655 goto suspend;
42656 }
42657 } else if (self->private_impl.f_call_sequence == 3) {
42658 if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
42659 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
42660 goto exit;
42661 }
42662 } else if (self->private_impl.f_call_sequence == 4) {
42663 self->private_impl.f_call_sequence = 255;
42664 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
42665 goto ok;
42666 } else {
42667 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
42668 goto ok;
42669 }
42670 if (a_dst != NULL) {
42671 wuffs_base__frame_config__set(
42672 a_dst,
42673 wuffs_base__utility__make_rect_ie_u32(
42674 0,
42675 0,
42676 self->private_impl.f_width,
42677 self->private_impl.f_height),
42678 ((wuffs_base__flicks)(0)),
42679 0,
42680 self->private_impl.f_frame_config_io_position,
42681 0,
42682 self->private_impl.f_opaque,
42683 false,
42684 4278190080);
42685 }
42686 self->private_impl.f_call_sequence = 4;
42687
42688 ok:
42689 self->private_impl.p_decode_frame_config[0] = 0;
42690 goto exit;
42691 }
42692
42693 goto suspend;
42694 suspend:
42695 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
42696 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
42697
42698 goto exit;
42699 exit:
42700 if (a_src) {
42701 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42702 }
42703
42704 if (wuffs_base__status__is_error(&status)) {
42705 self->private_impl.magic = WUFFS_BASE__DISABLED;
42706 }
42707 return status;
42708 }
42709
42710 // -------- func tga.decoder.decode_frame
42711
42712 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__decode_frame(wuffs_tga__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)42713 wuffs_tga__decoder__decode_frame(
42714 wuffs_tga__decoder* self,
42715 wuffs_base__pixel_buffer* a_dst,
42716 wuffs_base__io_buffer* a_src,
42717 wuffs_base__pixel_blend a_blend,
42718 wuffs_base__slice_u8 a_workbuf,
42719 wuffs_base__decode_frame_options* a_opts) {
42720 if (!self) {
42721 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
42722 }
42723 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
42724 return wuffs_base__make_status(
42725 (self->private_impl.magic == WUFFS_BASE__DISABLED)
42726 ? wuffs_base__error__disabled_by_previous_error
42727 : wuffs_base__error__initialize_not_called);
42728 }
42729 if (!a_dst || !a_src) {
42730 self->private_impl.magic = WUFFS_BASE__DISABLED;
42731 return wuffs_base__make_status(wuffs_base__error__bad_argument);
42732 }
42733 if ((self->private_impl.active_coroutine != 0) &&
42734 (self->private_impl.active_coroutine != 3)) {
42735 self->private_impl.magic = WUFFS_BASE__DISABLED;
42736 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
42737 }
42738 self->private_impl.active_coroutine = 0;
42739 wuffs_base__status status = wuffs_base__make_status(NULL);
42740
42741 wuffs_base__status v_status = wuffs_base__make_status(NULL);
42742 wuffs_base__pixel_format v_dst_pixfmt = {0};
42743 uint32_t v_dst_bits_per_pixel = 0;
42744 uint64_t v_dst_bytes_per_pixel = 0;
42745 uint32_t v_dst_x = 0;
42746 uint32_t v_dst_y = 0;
42747 wuffs_base__table_u8 v_tab = {0};
42748 wuffs_base__slice_u8 v_dst_palette = {0};
42749 wuffs_base__slice_u8 v_dst = {0};
42750 uint64_t v_dst_start = 0;
42751 wuffs_base__slice_u8 v_src_palette = {0};
42752 uint64_t v_mark = 0;
42753 uint64_t v_num_pixels64 = 0;
42754 uint32_t v_num_pixels32 = 0;
42755 uint32_t v_lit_length = 0;
42756 uint32_t v_run_length = 0;
42757 uint64_t v_num_dst_bytes = 0;
42758 uint32_t v_num_src_bytes = 0;
42759 uint32_t v_c = 0;
42760 uint32_t v_c5 = 0;
42761
42762 const uint8_t* iop_a_src = NULL;
42763 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42764 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42765 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
42766 if (a_src) {
42767 io0_a_src = a_src->data.ptr;
42768 io1_a_src = io0_a_src + a_src->meta.ri;
42769 iop_a_src = io1_a_src;
42770 io2_a_src = io0_a_src + a_src->meta.wi;
42771 }
42772
42773 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
42774 if (coro_susp_point) {
42775 v_dst_bytes_per_pixel = self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel;
42776 v_dst_x = self->private_data.s_decode_frame[0].v_dst_x;
42777 v_dst_y = self->private_data.s_decode_frame[0].v_dst_y;
42778 v_mark = self->private_data.s_decode_frame[0].v_mark;
42779 v_num_pixels32 = self->private_data.s_decode_frame[0].v_num_pixels32;
42780 v_lit_length = self->private_data.s_decode_frame[0].v_lit_length;
42781 v_run_length = self->private_data.s_decode_frame[0].v_run_length;
42782 v_num_dst_bytes = self->private_data.s_decode_frame[0].v_num_dst_bytes;
42783 }
42784 switch (coro_susp_point) {
42785 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
42786
42787 if (self->private_impl.f_call_sequence < 4) {
42788 if (a_src) {
42789 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
42790 }
42791 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
42792 status = wuffs_tga__decoder__decode_frame_config(self, NULL, a_src);
42793 if (a_src) {
42794 iop_a_src = a_src->data.ptr + a_src->meta.ri;
42795 }
42796 if (status.repr) {
42797 goto suspend;
42798 }
42799 } else if (self->private_impl.f_call_sequence == 4) {
42800 } else {
42801 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
42802 goto ok;
42803 }
42804 if (self->private_impl.f_header_color_map_type != 0) {
42805 v_src_palette = wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024);
42806 }
42807 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
42808 wuffs_base__pixel_buffer__pixel_format(a_dst),
42809 wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
42810 wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
42811 v_src_palette,
42812 a_blend);
42813 if ( ! wuffs_base__status__is_ok(&v_status)) {
42814 status = v_status;
42815 if (wuffs_base__status__is_error(&status)) {
42816 goto exit;
42817 } else if (wuffs_base__status__is_suspension(&status)) {
42818 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
42819 goto exit;
42820 }
42821 goto ok;
42822 }
42823 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
42824 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
42825 if ((v_dst_bits_per_pixel & 7) != 0) {
42826 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
42827 goto exit;
42828 }
42829 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
42830 if ((self->private_impl.f_header_image_descriptor & 32) == 0) {
42831 v_dst_y = ((uint32_t)(self->private_impl.f_height - 1));
42832 }
42833 if ((self->private_impl.f_header_image_type & 8) == 0) {
42834 v_lit_length = self->private_impl.f_width;
42835 }
42836 label__resume__continue:;
42837 while (true) {
42838 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
42839 v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
42840 while (v_dst_y < self->private_impl.f_height) {
42841 v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
42842 v_dst_start = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
42843 if (v_dst_start <= ((uint64_t)(v_dst.len))) {
42844 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_start);
42845 } else {
42846 v_dst = wuffs_base__utility__empty_slice_u8();
42847 }
42848 while (v_dst_x < self->private_impl.f_width) {
42849 if (self->private_impl.f_src_bytes_per_pixel > 0) {
42850 if (v_lit_length > 0) {
42851 v_mark = ((uint64_t)(iop_a_src - io0_a_src));
42852 v_num_pixels64 = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(self->private_impl.f_src_bytes_per_pixel)));
42853 v_num_pixels32 = ((uint32_t)(wuffs_base__u64__min(v_num_pixels64, ((uint64_t)(v_lit_length)))));
42854 v_num_dst_bytes = (((uint64_t)(v_num_pixels32)) * v_dst_bytes_per_pixel);
42855 v_num_src_bytes = (v_num_pixels32 * self->private_impl.f_src_bytes_per_pixel);
42856 self->private_data.s_decode_frame[0].scratch = v_num_src_bytes;
42857 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
42858 if (self->private_data.s_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
42859 self->private_data.s_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
42860 iop_a_src = io2_a_src;
42861 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42862 goto suspend;
42863 }
42864 iop_a_src += self->private_data.s_decode_frame[0].scratch;
42865 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
42866 if (v_num_dst_bytes <= ((uint64_t)(v_dst.len))) {
42867 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_num_dst_bytes);
42868 } else {
42869 v_dst = wuffs_base__utility__empty_slice_u8();
42870 }
42871 v_dst_x += v_num_pixels32;
42872 v_lit_length = (((uint32_t)(v_lit_length - v_num_pixels32)) & 65535);
42873 if (v_lit_length > 0) {
42874 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42875 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
42876 goto label__resume__continue;
42877 }
42878 } else if (v_run_length > 0) {
42879 v_run_length -= 1;
42880 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 4), self->private_impl.f_scratch_bytes_per_pixel));
42881 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
42882 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
42883 }
42884 v_dst_x += 1;
42885 } else {
42886 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
42887 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42888 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
42889 goto label__resume__continue;
42890 }
42891 if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128) {
42892 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1);
42893 iop_a_src += 1;
42894 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
42895 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
42896 goto exit;
42897 }
42898 } else {
42899 if (self->private_impl.f_src_bytes_per_pixel == 1) {
42900 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
42901 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42902 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
42903 goto label__resume__continue;
42904 }
42905 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42906 iop_a_src += 1;
42907 self->private_data.f_scratch[0] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42908 iop_a_src += 1;
42909 } else if (self->private_impl.f_src_bytes_per_pixel == 3) {
42910 if (((uint64_t)(io2_a_src - iop_a_src)) < 4) {
42911 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42912 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
42913 goto label__resume__continue;
42914 }
42915 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42916 iop_a_src += 1;
42917 self->private_data.f_scratch[0] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42918 iop_a_src += 1;
42919 self->private_data.f_scratch[1] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42920 iop_a_src += 1;
42921 self->private_data.f_scratch[2] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42922 iop_a_src += 1;
42923 } else {
42924 if (((uint64_t)(io2_a_src - iop_a_src)) < 5) {
42925 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42926 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
42927 goto label__resume__continue;
42928 }
42929 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42930 iop_a_src += 1;
42931 self->private_data.f_scratch[0] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42932 iop_a_src += 1;
42933 self->private_data.f_scratch[1] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42934 iop_a_src += 1;
42935 self->private_data.f_scratch[2] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42936 iop_a_src += 1;
42937 self->private_data.f_scratch[3] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
42938 iop_a_src += 1;
42939 }
42940 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
42941 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
42942 goto exit;
42943 }
42944 }
42945 }
42946 } else {
42947 if (v_lit_length > 0) {
42948 if (((uint64_t)(io2_a_src - iop_a_src)) < 2) {
42949 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42950 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
42951 goto label__resume__continue;
42952 }
42953 v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42954 iop_a_src += 2;
42955 v_c5 = (31 & (v_c >> 0));
42956 self->private_data.f_scratch[0] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42957 v_c5 = (31 & (v_c >> 5));
42958 self->private_data.f_scratch[1] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42959 v_c5 = (31 & (v_c >> 10));
42960 self->private_data.f_scratch[2] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
42961 self->private_data.f_scratch[3] = 255;
42962 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, 4));
42963 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
42964 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
42965 }
42966 v_dst_x += 1;
42967 v_lit_length -= 1;
42968 } else if (v_run_length > 0) {
42969 v_run_length -= 1;
42970 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(wuffs_base__make_slice_u8(self->private_data.f_scratch, 4), self->private_impl.f_scratch_bytes_per_pixel));
42971 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
42972 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
42973 }
42974 v_dst_x += 1;
42975 } else {
42976 if (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
42977 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42978 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
42979 goto label__resume__continue;
42980 }
42981 if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128) {
42982 v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1);
42983 iop_a_src += 1;
42984 if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
42985 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
42986 goto exit;
42987 }
42988 } else {
42989 if (((uint64_t)(io2_a_src - iop_a_src)) < 3) {
42990 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
42991 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
42992 goto label__resume__continue;
42993 }
42994 v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127) + 1);
42995 iop_a_src += 1;
42996 v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
42997 iop_a_src += 2;
42998 v_c5 = (31 & (v_c >> 0));
42999 self->private_data.f_scratch[0] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
43000 v_c5 = (31 & (v_c >> 5));
43001 self->private_data.f_scratch[1] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
43002 v_c5 = (31 & (v_c >> 10));
43003 self->private_data.f_scratch[2] = ((uint8_t)(((v_c5 << 3) | (v_c5 >> 2))));
43004 self->private_data.f_scratch[3] = 255;
43005 if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
43006 status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
43007 goto exit;
43008 }
43009 }
43010 }
43011 }
43012 }
43013 v_dst_x = 0;
43014 if ((self->private_impl.f_header_image_descriptor & 32) == 0) {
43015 v_dst_y -= 1;
43016 } else {
43017 v_dst_y += 1;
43018 }
43019 if ((self->private_impl.f_header_image_type & 8) == 0) {
43020 v_lit_length = self->private_impl.f_width;
43021 }
43022 }
43023 goto label__resume__break;
43024 }
43025 label__resume__break:;
43026 self->private_impl.f_call_sequence = 255;
43027
43028 ok:
43029 self->private_impl.p_decode_frame[0] = 0;
43030 goto exit;
43031 }
43032
43033 goto suspend;
43034 suspend:
43035 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43036 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
43037 self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
43038 self->private_data.s_decode_frame[0].v_dst_x = v_dst_x;
43039 self->private_data.s_decode_frame[0].v_dst_y = v_dst_y;
43040 self->private_data.s_decode_frame[0].v_mark = v_mark;
43041 self->private_data.s_decode_frame[0].v_num_pixels32 = v_num_pixels32;
43042 self->private_data.s_decode_frame[0].v_lit_length = v_lit_length;
43043 self->private_data.s_decode_frame[0].v_run_length = v_run_length;
43044 self->private_data.s_decode_frame[0].v_num_dst_bytes = v_num_dst_bytes;
43045
43046 goto exit;
43047 exit:
43048 if (a_src) {
43049 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43050 }
43051
43052 if (wuffs_base__status__is_error(&status)) {
43053 self->private_impl.magic = WUFFS_BASE__DISABLED;
43054 }
43055 return status;
43056 }
43057
43058 // -------- func tga.decoder.frame_dirty_rect
43059
43060 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_tga__decoder__frame_dirty_rect(const wuffs_tga__decoder * self)43061 wuffs_tga__decoder__frame_dirty_rect(
43062 const wuffs_tga__decoder* self) {
43063 if (!self) {
43064 return wuffs_base__utility__empty_rect_ie_u32();
43065 }
43066 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43067 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43068 return wuffs_base__utility__empty_rect_ie_u32();
43069 }
43070
43071 return wuffs_base__utility__make_rect_ie_u32(
43072 0,
43073 0,
43074 self->private_impl.f_width,
43075 self->private_impl.f_height);
43076 }
43077
43078 // -------- func tga.decoder.num_animation_loops
43079
43080 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_tga__decoder__num_animation_loops(const wuffs_tga__decoder * self)43081 wuffs_tga__decoder__num_animation_loops(
43082 const wuffs_tga__decoder* self) {
43083 if (!self) {
43084 return 0;
43085 }
43086 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43087 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43088 return 0;
43089 }
43090
43091 return 0;
43092 }
43093
43094 // -------- func tga.decoder.num_decoded_frame_configs
43095
43096 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__num_decoded_frame_configs(const wuffs_tga__decoder * self)43097 wuffs_tga__decoder__num_decoded_frame_configs(
43098 const wuffs_tga__decoder* self) {
43099 if (!self) {
43100 return 0;
43101 }
43102 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43103 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43104 return 0;
43105 }
43106
43107 if (self->private_impl.f_call_sequence > 3) {
43108 return 1;
43109 }
43110 return 0;
43111 }
43112
43113 // -------- func tga.decoder.num_decoded_frames
43114
43115 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_tga__decoder__num_decoded_frames(const wuffs_tga__decoder * self)43116 wuffs_tga__decoder__num_decoded_frames(
43117 const wuffs_tga__decoder* self) {
43118 if (!self) {
43119 return 0;
43120 }
43121 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43122 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43123 return 0;
43124 }
43125
43126 if (self->private_impl.f_call_sequence > 4) {
43127 return 1;
43128 }
43129 return 0;
43130 }
43131
43132 // -------- func tga.decoder.restart_frame
43133
43134 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__restart_frame(wuffs_tga__decoder * self,uint64_t a_index,uint64_t a_io_position)43135 wuffs_tga__decoder__restart_frame(
43136 wuffs_tga__decoder* self,
43137 uint64_t a_index,
43138 uint64_t a_io_position) {
43139 if (!self) {
43140 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43141 }
43142 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43143 return wuffs_base__make_status(
43144 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43145 ? wuffs_base__error__disabled_by_previous_error
43146 : wuffs_base__error__initialize_not_called);
43147 }
43148
43149 if (self->private_impl.f_call_sequence < 3) {
43150 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
43151 }
43152 if (a_index != 0) {
43153 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43154 }
43155 self->private_impl.f_call_sequence = 3;
43156 self->private_impl.f_frame_config_io_position = a_io_position;
43157 return wuffs_base__make_status(NULL);
43158 }
43159
43160 // -------- func tga.decoder.set_report_metadata
43161
43162 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_tga__decoder__set_report_metadata(wuffs_tga__decoder * self,uint32_t a_fourcc,bool a_report)43163 wuffs_tga__decoder__set_report_metadata(
43164 wuffs_tga__decoder* self,
43165 uint32_t a_fourcc,
43166 bool a_report) {
43167 return wuffs_base__make_empty_struct();
43168 }
43169
43170 // -------- func tga.decoder.tell_me_more
43171
43172 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_tga__decoder__tell_me_more(wuffs_tga__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)43173 wuffs_tga__decoder__tell_me_more(
43174 wuffs_tga__decoder* self,
43175 wuffs_base__io_buffer* a_dst,
43176 wuffs_base__more_information* a_minfo,
43177 wuffs_base__io_buffer* a_src) {
43178 if (!self) {
43179 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43180 }
43181 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43182 return wuffs_base__make_status(
43183 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43184 ? wuffs_base__error__disabled_by_previous_error
43185 : wuffs_base__error__initialize_not_called);
43186 }
43187 if (!a_dst || !a_src) {
43188 self->private_impl.magic = WUFFS_BASE__DISABLED;
43189 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43190 }
43191 if ((self->private_impl.active_coroutine != 0) &&
43192 (self->private_impl.active_coroutine != 4)) {
43193 self->private_impl.magic = WUFFS_BASE__DISABLED;
43194 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43195 }
43196 self->private_impl.active_coroutine = 0;
43197 wuffs_base__status status = wuffs_base__make_status(NULL);
43198
43199 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
43200 goto exit;
43201
43202 goto ok;
43203 ok:
43204 goto exit;
43205 exit:
43206 if (wuffs_base__status__is_error(&status)) {
43207 self->private_impl.magic = WUFFS_BASE__DISABLED;
43208 }
43209 return status;
43210 }
43211
43212 // -------- func tga.decoder.workbuf_len
43213
43214 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_tga__decoder__workbuf_len(const wuffs_tga__decoder * self)43215 wuffs_tga__decoder__workbuf_len(
43216 const wuffs_tga__decoder* self) {
43217 if (!self) {
43218 return wuffs_base__utility__empty_range_ii_u64();
43219 }
43220 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43221 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43222 return wuffs_base__utility__empty_range_ii_u64();
43223 }
43224
43225 return wuffs_base__utility__make_range_ii_u64(0, 0);
43226 }
43227
43228 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
43229
43230 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
43231
43232 // ---------------- Status Codes Implementations
43233
43234 const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header";
43235
43236 // ---------------- Private Consts
43237
43238 // ---------------- Private Initializer Prototypes
43239
43240 // ---------------- Private Function Prototypes
43241
43242 // ---------------- VTables
43243
43244 const wuffs_base__image_decoder__func_ptrs
43245 wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
43246 (wuffs_base__status(*)(void*,
43247 wuffs_base__pixel_buffer*,
43248 wuffs_base__io_buffer*,
43249 wuffs_base__pixel_blend,
43250 wuffs_base__slice_u8,
43251 wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame),
43252 (wuffs_base__status(*)(void*,
43253 wuffs_base__frame_config*,
43254 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config),
43255 (wuffs_base__status(*)(void*,
43256 wuffs_base__image_config*,
43257 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config),
43258 (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect),
43259 (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops),
43260 (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs),
43261 (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames),
43262 (wuffs_base__status(*)(void*,
43263 uint64_t,
43264 uint64_t))(&wuffs_wbmp__decoder__restart_frame),
43265 (wuffs_base__empty_struct(*)(void*,
43266 uint32_t,
43267 bool))(&wuffs_wbmp__decoder__set_quirk_enabled),
43268 (wuffs_base__empty_struct(*)(void*,
43269 uint32_t,
43270 bool))(&wuffs_wbmp__decoder__set_report_metadata),
43271 (wuffs_base__status(*)(void*,
43272 wuffs_base__io_buffer*,
43273 wuffs_base__more_information*,
43274 wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more),
43275 (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len),
43276 };
43277
43278 // ---------------- Initializer Implementations
43279
43280 wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
wuffs_wbmp__decoder__initialize(wuffs_wbmp__decoder * self,size_t sizeof_star_self,uint64_t wuffs_version,uint32_t options)43281 wuffs_wbmp__decoder__initialize(
43282 wuffs_wbmp__decoder* self,
43283 size_t sizeof_star_self,
43284 uint64_t wuffs_version,
43285 uint32_t options){
43286 if (!self) {
43287 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43288 }
43289 if (sizeof(*self) != sizeof_star_self) {
43290 return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
43291 }
43292 if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
43293 (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
43294 return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
43295 }
43296
43297 if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
43298 // The whole point of this if-check is to detect an uninitialized *self.
43299 // We disable the warning on GCC. Clang-5.0 does not have this warning.
43300 #if !defined(__clang__) && defined(__GNUC__)
43301 #pragma GCC diagnostic push
43302 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
43303 #endif
43304 if (self->private_impl.magic != 0) {
43305 return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
43306 }
43307 #if !defined(__clang__) && defined(__GNUC__)
43308 #pragma GCC diagnostic pop
43309 #endif
43310 } else {
43311 if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
43312 memset(self, 0, sizeof(*self));
43313 options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
43314 } else {
43315 memset(&(self->private_impl), 0, sizeof(self->private_impl));
43316 }
43317 }
43318
43319 self->private_impl.magic = WUFFS_BASE__MAGIC;
43320 self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
43321 wuffs_base__image_decoder__vtable_name;
43322 self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
43323 (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
43324 return wuffs_base__make_status(NULL);
43325 }
43326
43327 wuffs_wbmp__decoder*
wuffs_wbmp__decoder__alloc()43328 wuffs_wbmp__decoder__alloc() {
43329 wuffs_wbmp__decoder* x =
43330 (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
43331 if (!x) {
43332 return NULL;
43333 }
43334 if (wuffs_wbmp__decoder__initialize(
43335 x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
43336 free(x);
43337 return NULL;
43338 }
43339 return x;
43340 }
43341
43342 size_t
sizeof__wuffs_wbmp__decoder()43343 sizeof__wuffs_wbmp__decoder() {
43344 return sizeof(wuffs_wbmp__decoder);
43345 }
43346
43347 // ---------------- Function Implementations
43348
43349 // -------- func wbmp.decoder.set_quirk_enabled
43350
43351 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_wbmp__decoder__set_quirk_enabled(wuffs_wbmp__decoder * self,uint32_t a_quirk,bool a_enabled)43352 wuffs_wbmp__decoder__set_quirk_enabled(
43353 wuffs_wbmp__decoder* self,
43354 uint32_t a_quirk,
43355 bool a_enabled) {
43356 return wuffs_base__make_empty_struct();
43357 }
43358
43359 // -------- func wbmp.decoder.decode_image_config
43360
43361 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__decode_image_config(wuffs_wbmp__decoder * self,wuffs_base__image_config * a_dst,wuffs_base__io_buffer * a_src)43362 wuffs_wbmp__decoder__decode_image_config(
43363 wuffs_wbmp__decoder* self,
43364 wuffs_base__image_config* a_dst,
43365 wuffs_base__io_buffer* a_src) {
43366 if (!self) {
43367 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43368 }
43369 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43370 return wuffs_base__make_status(
43371 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43372 ? wuffs_base__error__disabled_by_previous_error
43373 : wuffs_base__error__initialize_not_called);
43374 }
43375 if (!a_src) {
43376 self->private_impl.magic = WUFFS_BASE__DISABLED;
43377 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43378 }
43379 if ((self->private_impl.active_coroutine != 0) &&
43380 (self->private_impl.active_coroutine != 1)) {
43381 self->private_impl.magic = WUFFS_BASE__DISABLED;
43382 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43383 }
43384 self->private_impl.active_coroutine = 0;
43385 wuffs_base__status status = wuffs_base__make_status(NULL);
43386
43387 uint8_t v_c = 0;
43388 uint32_t v_i = 0;
43389 uint32_t v_x32 = 0;
43390 uint64_t v_x64 = 0;
43391
43392 const uint8_t* iop_a_src = NULL;
43393 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43394 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43395 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43396 if (a_src) {
43397 io0_a_src = a_src->data.ptr;
43398 io1_a_src = io0_a_src + a_src->meta.ri;
43399 iop_a_src = io1_a_src;
43400 io2_a_src = io0_a_src + a_src->meta.wi;
43401 }
43402
43403 uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
43404 if (coro_susp_point) {
43405 v_i = self->private_data.s_decode_image_config[0].v_i;
43406 v_x32 = self->private_data.s_decode_image_config[0].v_x32;
43407 }
43408 switch (coro_susp_point) {
43409 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43410
43411 if (self->private_impl.f_call_sequence != 0) {
43412 status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
43413 goto exit;
43414 }
43415 v_i = 0;
43416 while (v_i < 2) {
43417 {
43418 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43419 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43420 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43421 goto suspend;
43422 }
43423 uint8_t t_0 = *iop_a_src++;
43424 v_c = t_0;
43425 }
43426 if (v_c != 0) {
43427 status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
43428 goto exit;
43429 }
43430 v_i += 1;
43431 }
43432 v_i = 0;
43433 while (v_i < 2) {
43434 v_x32 = 0;
43435 while (true) {
43436 {
43437 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
43438 if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
43439 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43440 goto suspend;
43441 }
43442 uint8_t t_1 = *iop_a_src++;
43443 v_c = t_1;
43444 }
43445 v_x32 |= ((uint32_t)((v_c & 127)));
43446 if ((v_c >> 7) == 0) {
43447 goto label__0__break;
43448 }
43449 v_x64 = (((uint64_t)(v_x32)) << 7);
43450 if (v_x64 > 4294967295) {
43451 status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
43452 goto exit;
43453 }
43454 v_x32 = ((uint32_t)(v_x64));
43455 }
43456 label__0__break:;
43457 if (v_i == 0) {
43458 self->private_impl.f_width = v_x32;
43459 } else {
43460 self->private_impl.f_height = v_x32;
43461 }
43462 v_i += 1;
43463 }
43464 self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
43465 if (a_dst != NULL) {
43466 wuffs_base__image_config__set(
43467 a_dst,
43468 2198077448,
43469 0,
43470 self->private_impl.f_width,
43471 self->private_impl.f_height,
43472 self->private_impl.f_frame_config_io_position,
43473 true);
43474 }
43475 self->private_impl.f_call_sequence = 3;
43476
43477 goto ok;
43478 ok:
43479 self->private_impl.p_decode_image_config[0] = 0;
43480 goto exit;
43481 }
43482
43483 goto suspend;
43484 suspend:
43485 self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43486 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
43487 self->private_data.s_decode_image_config[0].v_i = v_i;
43488 self->private_data.s_decode_image_config[0].v_x32 = v_x32;
43489
43490 goto exit;
43491 exit:
43492 if (a_src) {
43493 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43494 }
43495
43496 if (wuffs_base__status__is_error(&status)) {
43497 self->private_impl.magic = WUFFS_BASE__DISABLED;
43498 }
43499 return status;
43500 }
43501
43502 // -------- func wbmp.decoder.decode_frame_config
43503
43504 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__decode_frame_config(wuffs_wbmp__decoder * self,wuffs_base__frame_config * a_dst,wuffs_base__io_buffer * a_src)43505 wuffs_wbmp__decoder__decode_frame_config(
43506 wuffs_wbmp__decoder* self,
43507 wuffs_base__frame_config* a_dst,
43508 wuffs_base__io_buffer* a_src) {
43509 if (!self) {
43510 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43511 }
43512 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43513 return wuffs_base__make_status(
43514 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43515 ? wuffs_base__error__disabled_by_previous_error
43516 : wuffs_base__error__initialize_not_called);
43517 }
43518 if (!a_src) {
43519 self->private_impl.magic = WUFFS_BASE__DISABLED;
43520 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43521 }
43522 if ((self->private_impl.active_coroutine != 0) &&
43523 (self->private_impl.active_coroutine != 2)) {
43524 self->private_impl.magic = WUFFS_BASE__DISABLED;
43525 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43526 }
43527 self->private_impl.active_coroutine = 0;
43528 wuffs_base__status status = wuffs_base__make_status(NULL);
43529
43530 const uint8_t* iop_a_src = NULL;
43531 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43532 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43533 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43534 if (a_src) {
43535 io0_a_src = a_src->data.ptr;
43536 io1_a_src = io0_a_src + a_src->meta.ri;
43537 iop_a_src = io1_a_src;
43538 io2_a_src = io0_a_src + a_src->meta.wi;
43539 }
43540
43541 uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
43542 switch (coro_susp_point) {
43543 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43544
43545 if (self->private_impl.f_call_sequence < 3) {
43546 if (a_src) {
43547 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43548 }
43549 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43550 status = wuffs_wbmp__decoder__decode_image_config(self, NULL, a_src);
43551 if (a_src) {
43552 iop_a_src = a_src->data.ptr + a_src->meta.ri;
43553 }
43554 if (status.repr) {
43555 goto suspend;
43556 }
43557 } else if (self->private_impl.f_call_sequence == 3) {
43558 if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
43559 status = wuffs_base__make_status(wuffs_base__error__bad_restart);
43560 goto exit;
43561 }
43562 } else if (self->private_impl.f_call_sequence == 4) {
43563 self->private_impl.f_call_sequence = 255;
43564 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43565 goto ok;
43566 } else {
43567 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43568 goto ok;
43569 }
43570 if (a_dst != NULL) {
43571 wuffs_base__frame_config__set(
43572 a_dst,
43573 wuffs_base__utility__make_rect_ie_u32(
43574 0,
43575 0,
43576 self->private_impl.f_width,
43577 self->private_impl.f_height),
43578 ((wuffs_base__flicks)(0)),
43579 0,
43580 self->private_impl.f_frame_config_io_position,
43581 0,
43582 true,
43583 false,
43584 4278190080);
43585 }
43586 self->private_impl.f_call_sequence = 4;
43587
43588 ok:
43589 self->private_impl.p_decode_frame_config[0] = 0;
43590 goto exit;
43591 }
43592
43593 goto suspend;
43594 suspend:
43595 self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43596 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
43597
43598 goto exit;
43599 exit:
43600 if (a_src) {
43601 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43602 }
43603
43604 if (wuffs_base__status__is_error(&status)) {
43605 self->private_impl.magic = WUFFS_BASE__DISABLED;
43606 }
43607 return status;
43608 }
43609
43610 // -------- func wbmp.decoder.decode_frame
43611
43612 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__decode_frame(wuffs_wbmp__decoder * self,wuffs_base__pixel_buffer * a_dst,wuffs_base__io_buffer * a_src,wuffs_base__pixel_blend a_blend,wuffs_base__slice_u8 a_workbuf,wuffs_base__decode_frame_options * a_opts)43613 wuffs_wbmp__decoder__decode_frame(
43614 wuffs_wbmp__decoder* self,
43615 wuffs_base__pixel_buffer* a_dst,
43616 wuffs_base__io_buffer* a_src,
43617 wuffs_base__pixel_blend a_blend,
43618 wuffs_base__slice_u8 a_workbuf,
43619 wuffs_base__decode_frame_options* a_opts) {
43620 if (!self) {
43621 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43622 }
43623 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43624 return wuffs_base__make_status(
43625 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43626 ? wuffs_base__error__disabled_by_previous_error
43627 : wuffs_base__error__initialize_not_called);
43628 }
43629 if (!a_dst || !a_src) {
43630 self->private_impl.magic = WUFFS_BASE__DISABLED;
43631 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43632 }
43633 if ((self->private_impl.active_coroutine != 0) &&
43634 (self->private_impl.active_coroutine != 3)) {
43635 self->private_impl.magic = WUFFS_BASE__DISABLED;
43636 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43637 }
43638 self->private_impl.active_coroutine = 0;
43639 wuffs_base__status status = wuffs_base__make_status(NULL);
43640
43641 wuffs_base__status v_status = wuffs_base__make_status(NULL);
43642 wuffs_base__pixel_format v_dst_pixfmt = {0};
43643 uint32_t v_dst_bits_per_pixel = 0;
43644 uint64_t v_dst_bytes_per_pixel = 0;
43645 uint64_t v_dst_x_in_bytes = 0;
43646 uint32_t v_dst_x = 0;
43647 uint32_t v_dst_y = 0;
43648 wuffs_base__table_u8 v_tab = {0};
43649 wuffs_base__slice_u8 v_dst = {0};
43650 uint8_t v_src[1] = {0};
43651 uint8_t v_c = 0;
43652
43653 const uint8_t* iop_a_src = NULL;
43654 const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43655 const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43656 const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
43657 if (a_src) {
43658 io0_a_src = a_src->data.ptr;
43659 io1_a_src = io0_a_src + a_src->meta.ri;
43660 iop_a_src = io1_a_src;
43661 io2_a_src = io0_a_src + a_src->meta.wi;
43662 }
43663
43664 uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
43665 if (coro_susp_point) {
43666 v_dst_bytes_per_pixel = self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel;
43667 v_dst_x = self->private_data.s_decode_frame[0].v_dst_x;
43668 v_dst_y = self->private_data.s_decode_frame[0].v_dst_y;
43669 memcpy(v_src, self->private_data.s_decode_frame[0].v_src, sizeof(v_src));
43670 v_c = self->private_data.s_decode_frame[0].v_c;
43671 }
43672 switch (coro_susp_point) {
43673 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
43674
43675 if (self->private_impl.f_call_sequence < 4) {
43676 if (a_src) {
43677 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43678 }
43679 WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
43680 status = wuffs_wbmp__decoder__decode_frame_config(self, NULL, a_src);
43681 if (a_src) {
43682 iop_a_src = a_src->data.ptr + a_src->meta.ri;
43683 }
43684 if (status.repr) {
43685 goto suspend;
43686 }
43687 } else if (self->private_impl.f_call_sequence == 4) {
43688 } else {
43689 status = wuffs_base__make_status(wuffs_base__note__end_of_data);
43690 goto ok;
43691 }
43692 v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
43693 wuffs_base__pixel_buffer__pixel_format(a_dst),
43694 wuffs_base__pixel_buffer__palette(a_dst),
43695 wuffs_base__utility__make_pixel_format(536870920),
43696 wuffs_base__utility__empty_slice_u8(),
43697 a_blend);
43698 if ( ! wuffs_base__status__is_ok(&v_status)) {
43699 status = v_status;
43700 if (wuffs_base__status__is_error(&status)) {
43701 goto exit;
43702 } else if (wuffs_base__status__is_suspension(&status)) {
43703 status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
43704 goto exit;
43705 }
43706 goto ok;
43707 }
43708 v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
43709 v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
43710 if ((v_dst_bits_per_pixel & 7) != 0) {
43711 status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
43712 goto exit;
43713 }
43714 v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8)));
43715 if (self->private_impl.f_width > 0) {
43716 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
43717 while (v_dst_y < self->private_impl.f_height) {
43718 v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
43719 v_dst_x = 0;
43720 while (v_dst_x < self->private_impl.f_width) {
43721 if ((v_dst_x & 7) == 0) {
43722 while (((uint64_t)(io2_a_src - iop_a_src)) <= 0) {
43723 status = wuffs_base__make_status(wuffs_base__suspension__short_read);
43724 WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
43725 v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0);
43726 v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
43727 v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
43728 if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) {
43729 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes);
43730 }
43731 }
43732 v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
43733 iop_a_src += 1;
43734 }
43735 if ((v_c & 128) == 0) {
43736 v_src[0] = 0;
43737 } else {
43738 v_src[0] = 255;
43739 }
43740 v_c = ((uint8_t)(((((uint32_t)(v_c)) << 1) & 255)));
43741 wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__utility__empty_slice_u8(), wuffs_base__make_slice_u8(v_src, 1));
43742 if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
43743 v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
43744 }
43745 v_dst_x += 1;
43746 }
43747 v_dst_y += 1;
43748 }
43749 }
43750 self->private_impl.f_call_sequence = 255;
43751
43752 ok:
43753 self->private_impl.p_decode_frame[0] = 0;
43754 goto exit;
43755 }
43756
43757 goto suspend;
43758 suspend:
43759 self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
43760 self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
43761 self->private_data.s_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
43762 self->private_data.s_decode_frame[0].v_dst_x = v_dst_x;
43763 self->private_data.s_decode_frame[0].v_dst_y = v_dst_y;
43764 memcpy(self->private_data.s_decode_frame[0].v_src, v_src, sizeof(v_src));
43765 self->private_data.s_decode_frame[0].v_c = v_c;
43766
43767 goto exit;
43768 exit:
43769 if (a_src) {
43770 a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
43771 }
43772
43773 if (wuffs_base__status__is_error(&status)) {
43774 self->private_impl.magic = WUFFS_BASE__DISABLED;
43775 }
43776 return status;
43777 }
43778
43779 // -------- func wbmp.decoder.frame_dirty_rect
43780
43781 WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
wuffs_wbmp__decoder__frame_dirty_rect(const wuffs_wbmp__decoder * self)43782 wuffs_wbmp__decoder__frame_dirty_rect(
43783 const wuffs_wbmp__decoder* self) {
43784 if (!self) {
43785 return wuffs_base__utility__empty_rect_ie_u32();
43786 }
43787 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43788 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43789 return wuffs_base__utility__empty_rect_ie_u32();
43790 }
43791
43792 return wuffs_base__utility__make_rect_ie_u32(
43793 0,
43794 0,
43795 self->private_impl.f_width,
43796 self->private_impl.f_height);
43797 }
43798
43799 // -------- func wbmp.decoder.num_animation_loops
43800
43801 WUFFS_BASE__MAYBE_STATIC uint32_t
wuffs_wbmp__decoder__num_animation_loops(const wuffs_wbmp__decoder * self)43802 wuffs_wbmp__decoder__num_animation_loops(
43803 const wuffs_wbmp__decoder* self) {
43804 if (!self) {
43805 return 0;
43806 }
43807 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43808 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43809 return 0;
43810 }
43811
43812 return 0;
43813 }
43814
43815 // -------- func wbmp.decoder.num_decoded_frame_configs
43816
43817 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frame_configs(const wuffs_wbmp__decoder * self)43818 wuffs_wbmp__decoder__num_decoded_frame_configs(
43819 const wuffs_wbmp__decoder* self) {
43820 if (!self) {
43821 return 0;
43822 }
43823 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43824 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43825 return 0;
43826 }
43827
43828 if (self->private_impl.f_call_sequence > 3) {
43829 return 1;
43830 }
43831 return 0;
43832 }
43833
43834 // -------- func wbmp.decoder.num_decoded_frames
43835
43836 WUFFS_BASE__MAYBE_STATIC uint64_t
wuffs_wbmp__decoder__num_decoded_frames(const wuffs_wbmp__decoder * self)43837 wuffs_wbmp__decoder__num_decoded_frames(
43838 const wuffs_wbmp__decoder* self) {
43839 if (!self) {
43840 return 0;
43841 }
43842 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43843 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43844 return 0;
43845 }
43846
43847 if (self->private_impl.f_call_sequence > 4) {
43848 return 1;
43849 }
43850 return 0;
43851 }
43852
43853 // -------- func wbmp.decoder.restart_frame
43854
43855 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__restart_frame(wuffs_wbmp__decoder * self,uint64_t a_index,uint64_t a_io_position)43856 wuffs_wbmp__decoder__restart_frame(
43857 wuffs_wbmp__decoder* self,
43858 uint64_t a_index,
43859 uint64_t a_io_position) {
43860 if (!self) {
43861 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43862 }
43863 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43864 return wuffs_base__make_status(
43865 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43866 ? wuffs_base__error__disabled_by_previous_error
43867 : wuffs_base__error__initialize_not_called);
43868 }
43869
43870 if (self->private_impl.f_call_sequence < 3) {
43871 return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
43872 }
43873 if (a_index != 0) {
43874 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43875 }
43876 self->private_impl.f_call_sequence = 3;
43877 self->private_impl.f_frame_config_io_position = a_io_position;
43878 return wuffs_base__make_status(NULL);
43879 }
43880
43881 // -------- func wbmp.decoder.set_report_metadata
43882
43883 WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
wuffs_wbmp__decoder__set_report_metadata(wuffs_wbmp__decoder * self,uint32_t a_fourcc,bool a_report)43884 wuffs_wbmp__decoder__set_report_metadata(
43885 wuffs_wbmp__decoder* self,
43886 uint32_t a_fourcc,
43887 bool a_report) {
43888 return wuffs_base__make_empty_struct();
43889 }
43890
43891 // -------- func wbmp.decoder.tell_me_more
43892
43893 WUFFS_BASE__MAYBE_STATIC wuffs_base__status
wuffs_wbmp__decoder__tell_me_more(wuffs_wbmp__decoder * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)43894 wuffs_wbmp__decoder__tell_me_more(
43895 wuffs_wbmp__decoder* self,
43896 wuffs_base__io_buffer* a_dst,
43897 wuffs_base__more_information* a_minfo,
43898 wuffs_base__io_buffer* a_src) {
43899 if (!self) {
43900 return wuffs_base__make_status(wuffs_base__error__bad_receiver);
43901 }
43902 if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
43903 return wuffs_base__make_status(
43904 (self->private_impl.magic == WUFFS_BASE__DISABLED)
43905 ? wuffs_base__error__disabled_by_previous_error
43906 : wuffs_base__error__initialize_not_called);
43907 }
43908 if (!a_dst || !a_src) {
43909 self->private_impl.magic = WUFFS_BASE__DISABLED;
43910 return wuffs_base__make_status(wuffs_base__error__bad_argument);
43911 }
43912 if ((self->private_impl.active_coroutine != 0) &&
43913 (self->private_impl.active_coroutine != 4)) {
43914 self->private_impl.magic = WUFFS_BASE__DISABLED;
43915 return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
43916 }
43917 self->private_impl.active_coroutine = 0;
43918 wuffs_base__status status = wuffs_base__make_status(NULL);
43919
43920 status = wuffs_base__make_status(wuffs_base__error__no_more_information);
43921 goto exit;
43922
43923 goto ok;
43924 ok:
43925 goto exit;
43926 exit:
43927 if (wuffs_base__status__is_error(&status)) {
43928 self->private_impl.magic = WUFFS_BASE__DISABLED;
43929 }
43930 return status;
43931 }
43932
43933 // -------- func wbmp.decoder.workbuf_len
43934
43935 WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
wuffs_wbmp__decoder__workbuf_len(const wuffs_wbmp__decoder * self)43936 wuffs_wbmp__decoder__workbuf_len(
43937 const wuffs_wbmp__decoder* self) {
43938 if (!self) {
43939 return wuffs_base__utility__empty_range_ii_u64();
43940 }
43941 if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
43942 (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
43943 return wuffs_base__utility__empty_range_ii_u64();
43944 }
43945
43946 return wuffs_base__utility__make_range_ii_u64(0, 0);
43947 }
43948
43949 #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
43950
43951 #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
43952
43953 // ---------------- Auxiliary - Base
43954
43955 // Auxiliary code is discussed at
43956 // https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
43957
43958 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__BASE)
43959
43960 namespace wuffs_aux {
43961
43962 namespace sync_io {
43963
43964 // --------
43965
DynIOBuffer(uint64_t max_incl)43966 DynIOBuffer::DynIOBuffer(uint64_t max_incl)
43967 : m_buf(wuffs_base__empty_io_buffer()), m_max_incl(max_incl) {}
43968
~DynIOBuffer()43969 DynIOBuffer::~DynIOBuffer() {
43970 if (m_buf.data.ptr) {
43971 free(m_buf.data.ptr);
43972 }
43973 }
43974
43975 void //
drop()43976 DynIOBuffer::drop() {
43977 if (m_buf.data.ptr) {
43978 free(m_buf.data.ptr);
43979 }
43980 m_buf = wuffs_base__empty_io_buffer();
43981 }
43982
43983 DynIOBuffer::GrowResult //
grow(uint64_t min_incl)43984 DynIOBuffer::grow(uint64_t min_incl) {
43985 uint64_t n = round_up(min_incl, m_max_incl);
43986 if (n == 0) {
43987 return ((min_incl == 0) && (m_max_incl == 0))
43988 ? DynIOBuffer::GrowResult::OK
43989 : DynIOBuffer::GrowResult::FailedMaxInclExceeded;
43990 } else if (n > m_buf.data.len) {
43991 uint8_t* ptr = static_cast<uint8_t*>(realloc(m_buf.data.ptr, n));
43992 if (!ptr) {
43993 return DynIOBuffer::GrowResult::FailedOutOfMemory;
43994 }
43995 m_buf.data.ptr = ptr;
43996 m_buf.data.len = n;
43997 }
43998 return DynIOBuffer::GrowResult::OK;
43999 }
44000
44001 // round_up rounds min_incl up, returning the smallest value x satisfying
44002 // (min_incl <= x) and (x <= max_incl) and some other constraints. It returns 0
44003 // if there is no such x.
44004 //
44005 // When max_incl <= 4096, the other constraints are:
44006 // - (x == max_incl)
44007 //
44008 // When max_incl > 4096, the other constraints are:
44009 // - (x == max_incl) or (x is a power of 2)
44010 // - (x >= 4096)
44011 uint64_t //
round_up(uint64_t min_incl,uint64_t max_incl)44012 DynIOBuffer::round_up(uint64_t min_incl, uint64_t max_incl) {
44013 if (min_incl > max_incl) {
44014 return 0;
44015 }
44016 uint64_t n = 4096;
44017 if (n >= max_incl) {
44018 return max_incl;
44019 }
44020 while (n < min_incl) {
44021 if (n >= (max_incl / 2)) {
44022 return max_incl;
44023 }
44024 n *= 2;
44025 }
44026 return n;
44027 }
44028
44029 // --------
44030
~Input()44031 Input::~Input() {}
44032
44033 IOBuffer* //
BringsItsOwnIOBuffer()44034 Input::BringsItsOwnIOBuffer() {
44035 return nullptr;
44036 }
44037
44038 // --------
44039
FileInput(FILE * f)44040 FileInput::FileInput(FILE* f) : m_f(f) {}
44041
44042 std::string //
CopyIn(IOBuffer * dst)44043 FileInput::CopyIn(IOBuffer* dst) {
44044 if (!m_f) {
44045 return "wuffs_aux::sync_io::FileInput: nullptr file";
44046 } else if (!dst) {
44047 return "wuffs_aux::sync_io::FileInput: nullptr IOBuffer";
44048 } else if (dst->meta.closed) {
44049 return "wuffs_aux::sync_io::FileInput: end of file";
44050 } else {
44051 dst->compact();
44052 size_t n = fread(dst->writer_pointer(), 1, dst->writer_length(), m_f);
44053 dst->meta.wi += n;
44054 dst->meta.closed = feof(m_f);
44055 if (ferror(m_f)) {
44056 return "wuffs_aux::sync_io::FileInput: error reading file";
44057 }
44058 }
44059 return "";
44060 }
44061
44062 // --------
44063
MemoryInput(const char * ptr,size_t len)44064 MemoryInput::MemoryInput(const char* ptr, size_t len)
44065 : m_io(wuffs_base__ptr_u8__reader(
44066 static_cast<uint8_t*>(static_cast<void*>(const_cast<char*>(ptr))),
44067 len,
44068 true)) {}
44069
MemoryInput(const uint8_t * ptr,size_t len)44070 MemoryInput::MemoryInput(const uint8_t* ptr, size_t len)
44071 : m_io(wuffs_base__ptr_u8__reader(const_cast<uint8_t*>(ptr), len, true)) {}
44072
44073 IOBuffer* //
BringsItsOwnIOBuffer()44074 MemoryInput::BringsItsOwnIOBuffer() {
44075 return &m_io;
44076 }
44077
44078 std::string //
CopyIn(IOBuffer * dst)44079 MemoryInput::CopyIn(IOBuffer* dst) {
44080 if (!dst) {
44081 return "wuffs_aux::sync_io::MemoryInput: nullptr IOBuffer";
44082 } else if (dst->meta.closed) {
44083 return "wuffs_aux::sync_io::MemoryInput: end of file";
44084 } else if (wuffs_base__slice_u8__overlaps(dst->data, m_io.data)) {
44085 // Treat m_io's data as immutable, so don't compact dst or otherwise write
44086 // to it.
44087 return "wuffs_aux::sync_io::MemoryInput: overlapping buffers";
44088 } else {
44089 dst->compact();
44090 size_t nd = dst->writer_length();
44091 size_t ns = m_io.reader_length();
44092 size_t n = (nd < ns) ? nd : ns;
44093 memcpy(dst->writer_pointer(), m_io.reader_pointer(), n);
44094 m_io.meta.ri += n;
44095 dst->meta.wi += n;
44096 dst->meta.closed = m_io.reader_length() == 0;
44097 }
44098 return "";
44099 }
44100
44101 // --------
44102
44103 } // namespace sync_io
44104
44105 namespace private_impl {
44106
44107 struct ErrorMessages {
44108 const char* max_incl_metadata_length_exceeded;
44109 const char* out_of_memory;
44110 const char* unexpected_end_of_file;
44111 const char* unsupported_metadata;
44112 const char* unsupported_negative_advance;
44113
44114 // If adding new "const char*" typed fields to this struct, either add them
44115 // after existing fields or, if re-ordering fields, make sure that you update
44116 // all of the "const private_impl::ErrorMessages FooBarErrorMessages" values
44117 // in all of the sibling *.cc files.
44118
resolveErrorMessages44119 static inline const char* resolve(const char* s) {
44120 return s ? s : "wuffs_aux::private_impl: unknown error";
44121 };
44122 };
44123
44124 std::string //
AdvanceIOBufferTo(const ErrorMessages & error_messages,sync_io::Input & input,IOBuffer & io_buf,uint64_t absolute_position)44125 AdvanceIOBufferTo(const ErrorMessages& error_messages,
44126 sync_io::Input& input,
44127 IOBuffer& io_buf,
44128 uint64_t absolute_position) {
44129 if (absolute_position < io_buf.reader_position()) {
44130 return error_messages.resolve(error_messages.unsupported_negative_advance);
44131 }
44132 while (true) {
44133 uint64_t relative_position = absolute_position - io_buf.reader_position();
44134 if (relative_position <= io_buf.reader_length()) {
44135 io_buf.meta.ri += (size_t)relative_position;
44136 break;
44137 } else if (io_buf.meta.closed) {
44138 return error_messages.resolve(error_messages.unexpected_end_of_file);
44139 }
44140 io_buf.meta.ri = io_buf.meta.wi;
44141 if (!input.BringsItsOwnIOBuffer()) {
44142 io_buf.compact();
44143 }
44144 std::string error_message = input.CopyIn(&io_buf);
44145 if (!error_message.empty()) {
44146 return error_message;
44147 }
44148 }
44149 return "";
44150 }
44151
44152 std::string //
HandleMetadata(const ErrorMessages & error_messages,sync_io::Input & input,wuffs_base__io_buffer & io_buf,sync_io::DynIOBuffer & raw,wuffs_base__status (* tell_me_more_func)(void *,wuffs_base__io_buffer *,wuffs_base__more_information *,wuffs_base__io_buffer *),void * tell_me_more_receiver,std::string (* handle_metadata_func)(void *,const wuffs_base__more_information *,wuffs_base__slice_u8),void * handle_metadata_receiver)44153 HandleMetadata(
44154 const ErrorMessages& error_messages,
44155 sync_io::Input& input,
44156 wuffs_base__io_buffer& io_buf,
44157 sync_io::DynIOBuffer& raw,
44158 wuffs_base__status (*tell_me_more_func)(void*,
44159 wuffs_base__io_buffer*,
44160 wuffs_base__more_information*,
44161 wuffs_base__io_buffer*),
44162 void* tell_me_more_receiver,
44163 std::string (*handle_metadata_func)(void*,
44164 const wuffs_base__more_information*,
44165 wuffs_base__slice_u8),
44166 void* handle_metadata_receiver) {
44167 wuffs_base__more_information minfo = wuffs_base__empty_more_information();
44168 // Reset raw but keep its backing array (the raw.m_buf.data slice).
44169 raw.m_buf.meta = wuffs_base__empty_io_buffer_meta();
44170
44171 while (true) {
44172 minfo = wuffs_base__empty_more_information();
44173 wuffs_base__status status = (*tell_me_more_func)(
44174 tell_me_more_receiver, &raw.m_buf, &minfo, &io_buf);
44175 switch (minfo.flavor) {
44176 case 0:
44177 case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM:
44178 case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED:
44179 break;
44180
44181 case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH: {
44182 wuffs_base__range_ie_u64 r = minfo.metadata_raw_passthrough__range();
44183 if (r.is_empty()) {
44184 break;
44185 }
44186 uint64_t num_to_copy = r.length();
44187 if (num_to_copy > (raw.m_max_incl - raw.m_buf.meta.wi)) {
44188 return error_messages.resolve(
44189 error_messages.max_incl_metadata_length_exceeded);
44190 } else if (num_to_copy > (raw.m_buf.data.len - raw.m_buf.meta.wi)) {
44191 switch (raw.grow(num_to_copy + raw.m_buf.meta.wi)) {
44192 case sync_io::DynIOBuffer::GrowResult::OK:
44193 break;
44194 case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
44195 return error_messages.resolve(
44196 error_messages.max_incl_metadata_length_exceeded);
44197 case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
44198 return error_messages.resolve(error_messages.out_of_memory);
44199 }
44200 }
44201
44202 if (io_buf.reader_position() > r.min_incl) {
44203 return error_messages.resolve(error_messages.unsupported_metadata);
44204 } else {
44205 std::string error_message =
44206 AdvanceIOBufferTo(error_messages, input, io_buf, r.min_incl);
44207 if (!error_message.empty()) {
44208 return error_message;
44209 }
44210 }
44211
44212 while (true) {
44213 uint64_t n =
44214 wuffs_base__u64__min(num_to_copy, io_buf.reader_length());
44215 memcpy(raw.m_buf.writer_pointer(), io_buf.reader_pointer(), n);
44216 raw.m_buf.meta.wi += n;
44217 io_buf.meta.ri += n;
44218 num_to_copy -= n;
44219 if (num_to_copy == 0) {
44220 break;
44221 } else if (io_buf.meta.closed) {
44222 return error_messages.resolve(
44223 error_messages.unexpected_end_of_file);
44224 } else if (!input.BringsItsOwnIOBuffer()) {
44225 io_buf.compact();
44226 }
44227 std::string error_message = input.CopyIn(&io_buf);
44228 if (!error_message.empty()) {
44229 return error_message;
44230 }
44231 }
44232 break;
44233 }
44234
44235 default:
44236 return error_messages.resolve(error_messages.unsupported_metadata);
44237 }
44238
44239 if (status.repr == nullptr) {
44240 break;
44241 } else if (status.repr != wuffs_base__suspension__even_more_information) {
44242 if (status.repr != wuffs_base__suspension__short_write) {
44243 return status.message();
44244 }
44245 switch (raw.grow(wuffs_base__u64__sat_add(raw.m_buf.data.len, 1))) {
44246 case sync_io::DynIOBuffer::GrowResult::OK:
44247 break;
44248 case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
44249 return error_messages.resolve(
44250 error_messages.max_incl_metadata_length_exceeded);
44251 case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
44252 return error_messages.resolve(error_messages.out_of_memory);
44253 }
44254 }
44255 }
44256
44257 return (*handle_metadata_func)(handle_metadata_receiver, &minfo,
44258 raw.m_buf.reader_slice());
44259 }
44260
44261 } // namespace private_impl
44262
44263 } // namespace wuffs_aux
44264
44265 #endif // !defined(WUFFS_CONFIG__MODULES) ||
44266 // defined(WUFFS_CONFIG__MODULE__AUX__BASE)
44267
44268 // ---------------- Auxiliary - CBOR
44269
44270 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
44271
44272 #include <utility>
44273
44274 namespace wuffs_aux {
44275
DecodeCborResult(std::string && error_message0,uint64_t cursor_position0)44276 DecodeCborResult::DecodeCborResult(std::string&& error_message0,
44277 uint64_t cursor_position0)
44278 : error_message(std::move(error_message0)),
44279 cursor_position(cursor_position0) {}
44280
~DecodeCborCallbacks()44281 DecodeCborCallbacks::~DecodeCborCallbacks() {}
44282
44283 void //
Done(DecodeCborResult & result,sync_io::Input & input,IOBuffer & buffer)44284 DecodeCborCallbacks::Done(DecodeCborResult& result,
44285 sync_io::Input& input,
44286 IOBuffer& buffer) {}
44287
DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)44288 DecodeCborArgQuirks::DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)
44289 : repr(repr0) {}
44290
DecodeCborArgQuirks(uint32_t * ptr0,size_t len0)44291 DecodeCborArgQuirks::DecodeCborArgQuirks(uint32_t* ptr0, size_t len0)
44292 : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
44293
44294 DecodeCborArgQuirks //
DefaultValue()44295 DecodeCborArgQuirks::DefaultValue() {
44296 return DecodeCborArgQuirks(wuffs_base__empty_slice_u32());
44297 }
44298
44299 DecodeCborResult //
DecodeCbor(DecodeCborCallbacks & callbacks,sync_io::Input & input,DecodeCborArgQuirks quirks)44300 DecodeCbor(DecodeCborCallbacks& callbacks,
44301 sync_io::Input& input,
44302 DecodeCborArgQuirks quirks) {
44303 // Prepare the wuffs_base__io_buffer and the resultant error_message.
44304 wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
44305 wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
44306 std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
44307 if (!io_buf) {
44308 fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
44309 fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
44310 io_buf = &fallback_io_buf;
44311 }
44312 // cursor_index is discussed at
44313 // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
44314 size_t cursor_index = 0;
44315 std::string ret_error_message;
44316 std::string io_error_message;
44317
44318 do {
44319 // Prepare the low-level CBOR decoder.
44320 wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
44321 if (!dec) {
44322 ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
44323 goto done;
44324 }
44325 for (size_t i = 0; i < quirks.repr.len; i++) {
44326 dec->set_quirk_enabled(quirks.repr.ptr[i], true);
44327 }
44328
44329 // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
44330 wuffs_base__token tok_array[256];
44331 wuffs_base__token_buffer tok_buf =
44332 wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
44333 &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
44334 wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
44335
44336 // Prepare other state.
44337 int32_t depth = 0;
44338 std::string str;
44339 int64_t extension_category = 0;
44340 uint64_t extension_detail = 0;
44341
44342 // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens
44343 // from outside of the base package, such as the CBOR package.
44344 constexpr int64_t EXT_CAT__CBOR_TAG = 16;
44345
44346 // Loop, doing these two things:
44347 // 1. Get the next token.
44348 // 2. Process that token.
44349 while (true) {
44350 // 1. Get the next token.
44351
44352 while (tok_buf.meta.ri >= tok_buf.meta.wi) {
44353 if (tok_status.repr == nullptr) {
44354 // No-op.
44355 } else if (tok_status.repr == wuffs_base__suspension__short_write) {
44356 tok_buf.compact();
44357 } else if (tok_status.repr == wuffs_base__suspension__short_read) {
44358 // Read from input to io_buf.
44359 if (!io_error_message.empty()) {
44360 ret_error_message = std::move(io_error_message);
44361 goto done;
44362 } else if (cursor_index != io_buf->meta.ri) {
44363 ret_error_message =
44364 "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
44365 goto done;
44366 } else if (io_buf->meta.closed) {
44367 ret_error_message =
44368 "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
44369 goto done;
44370 }
44371 io_buf->compact();
44372 if (io_buf->meta.wi >= io_buf->data.len) {
44373 ret_error_message =
44374 "wuffs_aux::DecodeCbor: internal error: io_buf is full";
44375 goto done;
44376 }
44377 cursor_index = io_buf->meta.ri;
44378 io_error_message = input.CopyIn(io_buf);
44379 } else {
44380 ret_error_message = tok_status.message();
44381 goto done;
44382 }
44383
44384 if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
44385 ret_error_message =
44386 "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
44387 goto done;
44388 }
44389 wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
44390 tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
44391 if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
44392 (tok_buf.meta.wi > tok_buf.data.len) ||
44393 (io_buf->meta.ri > io_buf->meta.wi) ||
44394 (io_buf->meta.wi > io_buf->data.len)) {
44395 ret_error_message =
44396 "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
44397 goto done;
44398 }
44399 }
44400
44401 wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
44402 uint64_t token_len = token.length();
44403 if ((io_buf->meta.ri < cursor_index) ||
44404 ((io_buf->meta.ri - cursor_index) < token_len)) {
44405 ret_error_message =
44406 "wuffs_aux::DecodeCbor: internal error: bad token indexes";
44407 goto done;
44408 }
44409 uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
44410 cursor_index += static_cast<size_t>(token_len);
44411
44412 // 2. Process that token.
44413
44414 uint64_t vbd = token.value_base_detail();
44415
44416 if (extension_category != 0) {
44417 int64_t ext = token.value_extension();
44418 if ((ext >= 0) && !token.continued()) {
44419 extension_detail = (extension_detail
44420 << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |
44421 static_cast<uint64_t>(ext);
44422 switch (extension_category) {
44423 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED:
44424 extension_category = 0;
44425 ret_error_message =
44426 callbacks.AppendI64(static_cast<int64_t>(extension_detail));
44427 goto parsed_a_value;
44428 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:
44429 extension_category = 0;
44430 ret_error_message = callbacks.AppendU64(extension_detail);
44431 goto parsed_a_value;
44432 case EXT_CAT__CBOR_TAG:
44433 extension_category = 0;
44434 ret_error_message = callbacks.AppendCborTag(extension_detail);
44435 if (!ret_error_message.empty()) {
44436 goto done;
44437 }
44438 continue;
44439 }
44440 }
44441 ret_error_message =
44442 "wuffs_aux::DecodeCbor: internal error: bad extended token";
44443 goto done;
44444 }
44445
44446 switch (token.value_base_category()) {
44447 case WUFFS_BASE__TOKEN__VBC__FILLER:
44448 continue;
44449
44450 case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
44451 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
44452 ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
44453 if (!ret_error_message.empty()) {
44454 goto done;
44455 }
44456 depth++;
44457 if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
44458 ret_error_message =
44459 "wuffs_aux::DecodeCbor: internal error: bad depth";
44460 goto done;
44461 }
44462 continue;
44463 }
44464 ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
44465 depth--;
44466 if (depth < 0) {
44467 ret_error_message =
44468 "wuffs_aux::DecodeCbor: internal error: bad depth";
44469 goto done;
44470 }
44471 goto parsed_a_value;
44472 }
44473
44474 case WUFFS_BASE__TOKEN__VBC__STRING: {
44475 if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
44476 // No-op.
44477 } else if (vbd &
44478 WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
44479 const char* ptr = // Convert from (uint8_t*).
44480 static_cast<const char*>(static_cast<void*>(token_ptr));
44481 str.append(ptr, static_cast<size_t>(token_len));
44482 } else {
44483 goto fail;
44484 }
44485 if (token.continued()) {
44486 continue;
44487 }
44488 ret_error_message =
44489 (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)
44490 ? callbacks.AppendTextString(std::move(str))
44491 : callbacks.AppendByteString(std::move(str));
44492 str.clear();
44493 goto parsed_a_value;
44494 }
44495
44496 case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
44497 uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
44498 size_t n = wuffs_base__utf_8__encode(
44499 wuffs_base__make_slice_u8(
44500 &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
44501 static_cast<uint32_t>(vbd));
44502 const char* ptr = // Convert from (uint8_t*).
44503 static_cast<const char*>(static_cast<void*>(&u[0]));
44504 str.append(ptr, n);
44505 if (token.continued()) {
44506 continue;
44507 }
44508 goto fail;
44509 }
44510
44511 case WUFFS_BASE__TOKEN__VBC__LITERAL: {
44512 if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {
44513 ret_error_message = callbacks.AppendNull();
44514 } else if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED) {
44515 ret_error_message = callbacks.AppendUndefined();
44516 } else {
44517 ret_error_message = callbacks.AppendBool(
44518 vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
44519 }
44520 goto parsed_a_value;
44521 }
44522
44523 case WUFFS_BASE__TOKEN__VBC__NUMBER: {
44524 const uint64_t cfp_fbbe_fifb =
44525 WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |
44526 WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |
44527 WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;
44528 if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {
44529 double f;
44530 switch (token_len) {
44531 case 3:
44532 f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(
44533 wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));
44534 break;
44535 case 5:
44536 f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(
44537 wuffs_base__peek_u32be__no_bounds_check(token_ptr + 1));
44538 break;
44539 case 9:
44540 f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
44541 wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
44542 break;
44543 default:
44544 goto fail;
44545 }
44546 ret_error_message = callbacks.AppendF64(f);
44547 goto parsed_a_value;
44548 }
44549 goto fail;
44550 }
44551
44552 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {
44553 if (token.continued()) {
44554 extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;
44555 extension_detail =
44556 static_cast<uint64_t>(token.value_base_detail__sign_extended());
44557 continue;
44558 }
44559 ret_error_message =
44560 callbacks.AppendI64(token.value_base_detail__sign_extended());
44561 goto parsed_a_value;
44562 }
44563
44564 case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {
44565 if (token.continued()) {
44566 extension_category =
44567 WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;
44568 extension_detail = vbd;
44569 continue;
44570 }
44571 ret_error_message = callbacks.AppendU64(vbd);
44572 goto parsed_a_value;
44573 }
44574 }
44575
44576 if (token.value_major() == WUFFS_CBOR__TOKEN_VALUE_MAJOR) {
44577 uint64_t value_minor = token.value_minor();
44578 if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {
44579 if (token_len == 9) {
44580 ret_error_message = callbacks.AppendMinus1MinusX(
44581 wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
44582 goto parsed_a_value;
44583 }
44584 } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {
44585 ret_error_message =
44586 callbacks.AppendCborSimpleValue(static_cast<uint8_t>(
44587 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));
44588 goto parsed_a_value;
44589 } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG) {
44590 if (token.continued()) {
44591 extension_category = EXT_CAT__CBOR_TAG;
44592 extension_detail =
44593 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;
44594 continue;
44595 }
44596 ret_error_message = callbacks.AppendCborTag(
44597 value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);
44598 if (!ret_error_message.empty()) {
44599 goto done;
44600 }
44601 continue;
44602 }
44603 }
44604
44605 fail:
44606 ret_error_message =
44607 "wuffs_aux::DecodeCbor: internal error: unexpected token";
44608 goto done;
44609
44610 parsed_a_value:
44611 if (!ret_error_message.empty() || (depth == 0)) {
44612 goto done;
44613 }
44614 }
44615 } while (false);
44616
44617 done:
44618 DecodeCborResult result(
44619 std::move(ret_error_message),
44620 wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
44621 callbacks.Done(result, input, *io_buf);
44622 return result;
44623 }
44624
44625 } // namespace wuffs_aux
44626
44627 #endif // !defined(WUFFS_CONFIG__MODULES) ||
44628 // defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
44629
44630 // ---------------- Auxiliary - Image
44631
44632 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
44633
44634 #include <utility>
44635
44636 namespace wuffs_aux {
44637
DecodeImageResult(MemOwner && pixbuf_mem_owner0,wuffs_base__pixel_buffer pixbuf0,std::string && error_message0)44638 DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
44639 wuffs_base__pixel_buffer pixbuf0,
44640 std::string&& error_message0)
44641 : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
44642 pixbuf(pixbuf0),
44643 error_message(std::move(error_message0)) {}
44644
DecodeImageResult(std::string && error_message0)44645 DecodeImageResult::DecodeImageResult(std::string&& error_message0)
44646 : pixbuf_mem_owner(nullptr, &free),
44647 pixbuf(wuffs_base__null_pixel_buffer()),
44648 error_message(std::move(error_message0)) {}
44649
~DecodeImageCallbacks()44650 DecodeImageCallbacks::~DecodeImageCallbacks() {}
44651
AllocPixbufResult(MemOwner && mem_owner0,wuffs_base__pixel_buffer pixbuf0)44652 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
44653 MemOwner&& mem_owner0,
44654 wuffs_base__pixel_buffer pixbuf0)
44655 : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
44656
AllocPixbufResult(std::string && error_message0)44657 DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
44658 std::string&& error_message0)
44659 : mem_owner(nullptr, &free),
44660 pixbuf(wuffs_base__null_pixel_buffer()),
44661 error_message(std::move(error_message0)) {}
44662
AllocWorkbufResult(MemOwner && mem_owner0,wuffs_base__slice_u8 workbuf0)44663 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
44664 MemOwner&& mem_owner0,
44665 wuffs_base__slice_u8 workbuf0)
44666 : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
44667
AllocWorkbufResult(std::string && error_message0)44668 DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
44669 std::string&& error_message0)
44670 : mem_owner(nullptr, &free),
44671 workbuf(wuffs_base__empty_slice_u8()),
44672 error_message(std::move(error_message0)) {}
44673
44674 wuffs_base__image_decoder::unique_ptr //
SelectDecoder(uint32_t fourcc,wuffs_base__slice_u8 prefix_data,bool prefix_closed)44675 DecodeImageCallbacks::SelectDecoder(uint32_t fourcc,
44676 wuffs_base__slice_u8 prefix_data,
44677 bool prefix_closed) {
44678 switch (fourcc) {
44679 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
44680 case WUFFS_BASE__FOURCC__BMP:
44681 return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
44682 #endif
44683
44684 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
44685 case WUFFS_BASE__FOURCC__GIF:
44686 return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
44687 #endif
44688
44689 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
44690 case WUFFS_BASE__FOURCC__NIE:
44691 return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
44692 #endif
44693
44694 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
44695 case WUFFS_BASE__FOURCC__PNG: {
44696 auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
44697 // Favor faster decodes over rejecting invalid checksums.
44698 dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
44699 return dec;
44700 }
44701 #endif
44702
44703 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
44704 case WUFFS_BASE__FOURCC__TGA:
44705 return wuffs_tga__decoder::alloc_as__wuffs_base__image_decoder();
44706 #endif
44707
44708 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
44709 case WUFFS_BASE__FOURCC__WBMP:
44710 return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
44711 #endif
44712 }
44713
44714 return wuffs_base__image_decoder::unique_ptr(nullptr, &free);
44715 }
44716
44717 std::string //
HandleMetadata(const wuffs_base__more_information & minfo,wuffs_base__slice_u8 raw)44718 DecodeImageCallbacks::HandleMetadata(const wuffs_base__more_information& minfo,
44719 wuffs_base__slice_u8 raw) {
44720 return "";
44721 }
44722
44723 wuffs_base__pixel_format //
SelectPixfmt(const wuffs_base__image_config & image_config)44724 DecodeImageCallbacks::SelectPixfmt(
44725 const wuffs_base__image_config& image_config) {
44726 return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
44727 }
44728
44729 DecodeImageCallbacks::AllocPixbufResult //
AllocPixbuf(const wuffs_base__image_config & image_config,bool allow_uninitialized_memory)44730 DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
44731 bool allow_uninitialized_memory) {
44732 uint32_t w = image_config.pixcfg.width();
44733 uint32_t h = image_config.pixcfg.height();
44734 if ((w == 0) || (h == 0)) {
44735 return AllocPixbufResult("");
44736 }
44737 uint64_t len = image_config.pixcfg.pixbuf_len();
44738 if ((len == 0) || (SIZE_MAX < len)) {
44739 return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
44740 }
44741 void* ptr =
44742 allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
44743 if (!ptr) {
44744 return AllocPixbufResult(DecodeImage_OutOfMemory);
44745 }
44746 wuffs_base__pixel_buffer pixbuf;
44747 wuffs_base__status status = pixbuf.set_from_slice(
44748 &image_config.pixcfg,
44749 wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
44750 if (!status.is_ok()) {
44751 free(ptr);
44752 return AllocPixbufResult(status.message());
44753 }
44754 return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
44755 }
44756
44757 DecodeImageCallbacks::AllocWorkbufResult //
AllocWorkbuf(wuffs_base__range_ii_u64 len_range,bool allow_uninitialized_memory)44758 DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
44759 bool allow_uninitialized_memory) {
44760 uint64_t len = len_range.max_incl;
44761 if (len == 0) {
44762 return AllocWorkbufResult("");
44763 } else if (SIZE_MAX < len) {
44764 return AllocWorkbufResult(DecodeImage_OutOfMemory);
44765 }
44766 void* ptr =
44767 allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
44768 if (!ptr) {
44769 return AllocWorkbufResult(DecodeImage_OutOfMemory);
44770 }
44771 return AllocWorkbufResult(
44772 MemOwner(ptr, &free),
44773 wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
44774 }
44775
44776 void //
Done(DecodeImageResult & result,sync_io::Input & input,IOBuffer & buffer,wuffs_base__image_decoder::unique_ptr image_decoder)44777 DecodeImageCallbacks::Done(
44778 DecodeImageResult& result,
44779 sync_io::Input& input,
44780 IOBuffer& buffer,
44781 wuffs_base__image_decoder::unique_ptr image_decoder) {}
44782
44783 const char DecodeImage_BufferIsTooShort[] = //
44784 "wuffs_aux::DecodeImage: buffer is too short";
44785 const char DecodeImage_MaxInclDimensionExceeded[] = //
44786 "wuffs_aux::DecodeImage: max_incl_dimension exceeded";
44787 const char DecodeImage_MaxInclMetadataLengthExceeded[] = //
44788 "wuffs_aux::DecodeImage: max_incl_metadata_length exceeded";
44789 const char DecodeImage_OutOfMemory[] = //
44790 "wuffs_aux::DecodeImage: out of memory";
44791 const char DecodeImage_UnexpectedEndOfFile[] = //
44792 "wuffs_aux::DecodeImage: unexpected end of file";
44793 const char DecodeImage_UnsupportedImageFormat[] = //
44794 "wuffs_aux::DecodeImage: unsupported image format";
44795 const char DecodeImage_UnsupportedMetadata[] = //
44796 "wuffs_aux::DecodeImage: unsupported metadata";
44797 const char DecodeImage_UnsupportedPixelBlend[] = //
44798 "wuffs_aux::DecodeImage: unsupported pixel blend";
44799 const char DecodeImage_UnsupportedPixelConfiguration[] = //
44800 "wuffs_aux::DecodeImage: unsupported pixel configuration";
44801 const char DecodeImage_UnsupportedPixelFormat[] = //
44802 "wuffs_aux::DecodeImage: unsupported pixel format";
44803
DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)44804 DecodeImageArgQuirks::DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)
44805 : repr(repr0) {}
44806
DecodeImageArgQuirks(uint32_t * ptr0,size_t len0)44807 DecodeImageArgQuirks::DecodeImageArgQuirks(uint32_t* ptr0, size_t len0)
44808 : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
44809
44810 DecodeImageArgQuirks //
DefaultValue()44811 DecodeImageArgQuirks::DefaultValue() {
44812 return DecodeImageArgQuirks(wuffs_base__empty_slice_u32());
44813 }
44814
DecodeImageArgFlags(uint64_t repr0)44815 DecodeImageArgFlags::DecodeImageArgFlags(uint64_t repr0) : repr(repr0) {}
44816
44817 DecodeImageArgFlags //
DefaultValue()44818 DecodeImageArgFlags::DefaultValue() {
44819 return DecodeImageArgFlags(0);
44820 }
44821
DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0)44822 DecodeImageArgPixelBlend::DecodeImageArgPixelBlend(
44823 wuffs_base__pixel_blend repr0)
44824 : repr(repr0) {}
44825
44826 DecodeImageArgPixelBlend //
DefaultValue()44827 DecodeImageArgPixelBlend::DefaultValue() {
44828 return DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC);
44829 }
44830
DecodeImageArgBackgroundColor(wuffs_base__color_u32_argb_premul repr0)44831 DecodeImageArgBackgroundColor::DecodeImageArgBackgroundColor(
44832 wuffs_base__color_u32_argb_premul repr0)
44833 : repr(repr0) {}
44834
44835 DecodeImageArgBackgroundColor //
DefaultValue()44836 DecodeImageArgBackgroundColor::DefaultValue() {
44837 return DecodeImageArgBackgroundColor(1);
44838 }
44839
DecodeImageArgMaxInclDimension(uint32_t repr0)44840 DecodeImageArgMaxInclDimension::DecodeImageArgMaxInclDimension(uint32_t repr0)
44841 : repr(repr0) {}
44842
44843 DecodeImageArgMaxInclDimension //
DefaultValue()44844 DecodeImageArgMaxInclDimension::DefaultValue() {
44845 return DecodeImageArgMaxInclDimension(1048575);
44846 }
44847
DecodeImageArgMaxInclMetadataLength(uint64_t repr0)44848 DecodeImageArgMaxInclMetadataLength::DecodeImageArgMaxInclMetadataLength(
44849 uint64_t repr0)
44850 : repr(repr0) {}
44851
44852 DecodeImageArgMaxInclMetadataLength //
DefaultValue()44853 DecodeImageArgMaxInclMetadataLength::DefaultValue() {
44854 return DecodeImageArgMaxInclMetadataLength(16777215);
44855 }
44856
44857 // --------
44858
44859 namespace {
44860
44861 const private_impl::ErrorMessages DecodeImageErrorMessages = {
44862 DecodeImage_MaxInclMetadataLengthExceeded, //
44863 DecodeImage_OutOfMemory, //
44864 DecodeImage_UnexpectedEndOfFile, //
44865 DecodeImage_UnsupportedMetadata, //
44866 DecodeImage_UnsupportedImageFormat, //
44867 };
44868
44869 std::string //
DecodeImageAdvanceIOBufferTo(sync_io::Input & input,wuffs_base__io_buffer & io_buf,uint64_t absolute_position)44870 DecodeImageAdvanceIOBufferTo(sync_io::Input& input,
44871 wuffs_base__io_buffer& io_buf,
44872 uint64_t absolute_position) {
44873 return private_impl::AdvanceIOBufferTo(DecodeImageErrorMessages, input,
44874 io_buf, absolute_position);
44875 }
44876
44877 wuffs_base__status //
DIHM0(void * self,wuffs_base__io_buffer * a_dst,wuffs_base__more_information * a_minfo,wuffs_base__io_buffer * a_src)44878 DIHM0(void* self,
44879 wuffs_base__io_buffer* a_dst,
44880 wuffs_base__more_information* a_minfo,
44881 wuffs_base__io_buffer* a_src) {
44882 return wuffs_base__image_decoder__tell_me_more(
44883 static_cast<wuffs_base__image_decoder*>(self), a_dst, a_minfo, a_src);
44884 }
44885
44886 std::string //
DIHM1(void * self,const wuffs_base__more_information * minfo,wuffs_base__slice_u8 raw)44887 DIHM1(void* self,
44888 const wuffs_base__more_information* minfo,
44889 wuffs_base__slice_u8 raw) {
44890 return static_cast<DecodeImageCallbacks*>(self)->HandleMetadata(*minfo, raw);
44891 }
44892
44893 std::string //
DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr & image_decoder,DecodeImageCallbacks & callbacks,sync_io::Input & input,wuffs_base__io_buffer & io_buf,sync_io::DynIOBuffer & raw_metadata_buf)44894 DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr& image_decoder,
44895 DecodeImageCallbacks& callbacks,
44896 sync_io::Input& input,
44897 wuffs_base__io_buffer& io_buf,
44898 sync_io::DynIOBuffer& raw_metadata_buf) {
44899 return private_impl::HandleMetadata(DecodeImageErrorMessages, input, io_buf,
44900 raw_metadata_buf, DIHM0,
44901 static_cast<void*>(image_decoder.get()),
44902 DIHM1, static_cast<void*>(&callbacks));
44903 }
44904
44905 DecodeImageResult //
DecodeImage0(wuffs_base__image_decoder::unique_ptr & image_decoder,DecodeImageCallbacks & callbacks,sync_io::Input & input,wuffs_base__io_buffer & io_buf,wuffs_base__slice_u32 quirks,uint64_t flags,wuffs_base__pixel_blend pixel_blend,wuffs_base__color_u32_argb_premul background_color,uint32_t max_incl_dimension,uint64_t max_incl_metadata_length)44906 DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,
44907 DecodeImageCallbacks& callbacks,
44908 sync_io::Input& input,
44909 wuffs_base__io_buffer& io_buf,
44910 wuffs_base__slice_u32 quirks,
44911 uint64_t flags,
44912 wuffs_base__pixel_blend pixel_blend,
44913 wuffs_base__color_u32_argb_premul background_color,
44914 uint32_t max_incl_dimension,
44915 uint64_t max_incl_metadata_length) {
44916 // Check args.
44917 switch (pixel_blend) {
44918 case WUFFS_BASE__PIXEL_BLEND__SRC:
44919 case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
44920 break;
44921 default:
44922 return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);
44923 }
44924
44925 wuffs_base__image_config image_config = wuffs_base__null_image_config();
44926 sync_io::DynIOBuffer raw_metadata_buf(max_incl_metadata_length);
44927 uint64_t start_pos = io_buf.reader_position();
44928 bool redirected = false;
44929 int32_t fourcc = 0;
44930 redirect:
44931 do {
44932 // Determine the image format.
44933 if (!redirected) {
44934 while (true) {
44935 fourcc = wuffs_base__magic_number_guess_fourcc(io_buf.reader_slice(),
44936 io_buf.meta.closed);
44937 if (fourcc > 0) {
44938 break;
44939 } else if ((fourcc == 0) && (io_buf.reader_length() >= 64)) {
44940 // Having (fourcc == 0) means that Wuffs' built in MIME sniffer
44941 // didn't recognize the image format. Nonetheless, custom callbacks
44942 // may still be able to do their own MIME sniffing, for exotic image
44943 // types. We try to give them at least 64 bytes of prefix data when
44944 // one-shot-calling callbacks.SelectDecoder. There is no mechanism
44945 // for the callbacks to request a longer prefix.
44946 break;
44947 } else if (io_buf.meta.closed || (io_buf.writer_length() == 0)) {
44948 fourcc = 0;
44949 break;
44950 }
44951 std::string error_message = input.CopyIn(&io_buf);
44952 if (!error_message.empty()) {
44953 return DecodeImageResult(std::move(error_message));
44954 }
44955 }
44956 } else {
44957 wuffs_base__io_buffer empty = wuffs_base__empty_io_buffer();
44958 wuffs_base__more_information minfo = wuffs_base__empty_more_information();
44959 wuffs_base__status tmm_status =
44960 image_decoder->tell_me_more(&empty, &minfo, &io_buf);
44961 if (tmm_status.repr != nullptr) {
44962 return DecodeImageResult(tmm_status.message());
44963 }
44964 if (minfo.flavor != WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {
44965 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44966 }
44967 uint64_t pos = minfo.io_redirect__range().min_incl;
44968 if (pos <= start_pos) {
44969 // Redirects must go forward.
44970 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44971 }
44972 std::string error_message =
44973 DecodeImageAdvanceIOBufferTo(input, io_buf, pos);
44974 if (!error_message.empty()) {
44975 return DecodeImageResult(std::move(error_message));
44976 }
44977 fourcc = (int32_t)(minfo.io_redirect__fourcc());
44978 if (fourcc == 0) {
44979 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44980 }
44981 image_decoder.reset();
44982 }
44983
44984 // Select the image decoder.
44985 image_decoder = callbacks.SelectDecoder(
44986 (uint32_t)fourcc, io_buf.reader_slice(), io_buf.meta.closed);
44987 if (!image_decoder) {
44988 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
44989 }
44990
44991 // Apply quirks.
44992 for (size_t i = 0; i < quirks.len; i++) {
44993 image_decoder->set_quirk_enabled(quirks.ptr[i], true);
44994 }
44995
44996 // Apply flags.
44997 if (flags != 0) {
44998 if (flags & DecodeImageArgFlags::REPORT_METADATA_CHRM) {
44999 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__CHRM, true);
45000 }
45001 if (flags & DecodeImageArgFlags::REPORT_METADATA_EXIF) {
45002 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__EXIF, true);
45003 }
45004 if (flags & DecodeImageArgFlags::REPORT_METADATA_GAMA) {
45005 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__GAMA, true);
45006 }
45007 if (flags & DecodeImageArgFlags::REPORT_METADATA_ICCP) {
45008 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__ICCP, true);
45009 }
45010 if (flags & DecodeImageArgFlags::REPORT_METADATA_KVP) {
45011 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__KVP, true);
45012 }
45013 if (flags & DecodeImageArgFlags::REPORT_METADATA_SRGB) {
45014 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__SRGB, true);
45015 }
45016 if (flags & DecodeImageArgFlags::REPORT_METADATA_XMP) {
45017 image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__XMP, true);
45018 }
45019 }
45020
45021 // Decode the image config.
45022 while (true) {
45023 wuffs_base__status id_dic_status =
45024 image_decoder->decode_image_config(&image_config, &io_buf);
45025 if (id_dic_status.repr == nullptr) {
45026 break;
45027 } else if (id_dic_status.repr == wuffs_base__note__i_o_redirect) {
45028 if (redirected) {
45029 return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
45030 }
45031 redirected = true;
45032 goto redirect;
45033 } else if (id_dic_status.repr == wuffs_base__note__metadata_reported) {
45034 std::string error_message = DecodeImageHandleMetadata(
45035 image_decoder, callbacks, input, io_buf, raw_metadata_buf);
45036 if (!error_message.empty()) {
45037 return DecodeImageResult(std::move(error_message));
45038 }
45039 } else if (id_dic_status.repr != wuffs_base__suspension__short_read) {
45040 return DecodeImageResult(id_dic_status.message());
45041 } else if (io_buf.meta.closed) {
45042 return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
45043 } else {
45044 std::string error_message = input.CopyIn(&io_buf);
45045 if (!error_message.empty()) {
45046 return DecodeImageResult(std::move(error_message));
45047 }
45048 }
45049 }
45050 } while (false);
45051 raw_metadata_buf.drop();
45052
45053 // Select the pixel format.
45054 uint32_t w = image_config.pixcfg.width();
45055 uint32_t h = image_config.pixcfg.height();
45056 if ((w > max_incl_dimension) || (h > max_incl_dimension)) {
45057 return DecodeImageResult(DecodeImage_MaxInclDimensionExceeded);
45058 }
45059 wuffs_base__pixel_format pixel_format = callbacks.SelectPixfmt(image_config);
45060 if (pixel_format.repr != image_config.pixcfg.pixel_format().repr) {
45061 switch (pixel_format.repr) {
45062 case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
45063 case WUFFS_BASE__PIXEL_FORMAT__BGR:
45064 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
45065 case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
45066 case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
45067 case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
45068 case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
45069 break;
45070 default:
45071 return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
45072 }
45073 image_config.pixcfg.set(pixel_format.repr,
45074 WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);
45075 }
45076
45077 // Allocate the pixel buffer.
45078 bool valid_background_color =
45079 wuffs_base__color_u32_argb_premul__is_valid(background_color);
45080 DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
45081 callbacks.AllocPixbuf(image_config, valid_background_color);
45082 if (!alloc_pixbuf_result.error_message.empty()) {
45083 return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
45084 }
45085 wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
45086 if (valid_background_color) {
45087 wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
45088 pixel_buffer.pixcfg.bounds(), background_color);
45089 if (pb_scufr_status.repr != nullptr) {
45090 return DecodeImageResult(pb_scufr_status.message());
45091 }
45092 }
45093
45094 // Allocate the work buffer. Wuffs' decoders conventionally assume that this
45095 // can be uninitialized memory.
45096 wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
45097 DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
45098 callbacks.AllocWorkbuf(workbuf_len, true);
45099 if (!alloc_workbuf_result.error_message.empty()) {
45100 return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
45101 } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
45102 return DecodeImageResult(DecodeImage_BufferIsTooShort);
45103 }
45104
45105 // Decode the frame config.
45106 wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();
45107 while (true) {
45108 wuffs_base__status id_dfc_status =
45109 image_decoder->decode_frame_config(&frame_config, &io_buf);
45110 if (id_dfc_status.repr == nullptr) {
45111 break;
45112 } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
45113 return DecodeImageResult(id_dfc_status.message());
45114 } else if (io_buf.meta.closed) {
45115 return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
45116 } else {
45117 std::string error_message = input.CopyIn(&io_buf);
45118 if (!error_message.empty()) {
45119 return DecodeImageResult(std::move(error_message));
45120 }
45121 }
45122 }
45123
45124 // Decode the frame (the pixels).
45125 //
45126 // From here on, always returns the pixel_buffer. If we get this far, we can
45127 // still display a partial image, even if we encounter an error.
45128 std::string message("");
45129 if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&
45130 frame_config.overwrite_instead_of_blend()) {
45131 pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;
45132 }
45133 while (true) {
45134 wuffs_base__status id_df_status =
45135 image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
45136 alloc_workbuf_result.workbuf, nullptr);
45137 if (id_df_status.repr == nullptr) {
45138 break;
45139 } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
45140 message = id_df_status.message();
45141 break;
45142 } else if (io_buf.meta.closed) {
45143 message = DecodeImage_UnexpectedEndOfFile;
45144 break;
45145 } else {
45146 std::string error_message = input.CopyIn(&io_buf);
45147 if (!error_message.empty()) {
45148 message = std::move(error_message);
45149 break;
45150 }
45151 }
45152 }
45153 return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
45154 pixel_buffer, std::move(message));
45155 }
45156
45157 } // namespace
45158
45159 DecodeImageResult //
DecodeImage(DecodeImageCallbacks & callbacks,sync_io::Input & input,DecodeImageArgQuirks quirks,DecodeImageArgFlags flags,DecodeImageArgPixelBlend pixel_blend,DecodeImageArgBackgroundColor background_color,DecodeImageArgMaxInclDimension max_incl_dimension,DecodeImageArgMaxInclMetadataLength max_incl_metadata_length)45160 DecodeImage(DecodeImageCallbacks& callbacks,
45161 sync_io::Input& input,
45162 DecodeImageArgQuirks quirks,
45163 DecodeImageArgFlags flags,
45164 DecodeImageArgPixelBlend pixel_blend,
45165 DecodeImageArgBackgroundColor background_color,
45166 DecodeImageArgMaxInclDimension max_incl_dimension,
45167 DecodeImageArgMaxInclMetadataLength max_incl_metadata_length) {
45168 wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
45169 wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
45170 std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
45171 if (!io_buf) {
45172 fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);
45173 fallback_io_buf =
45174 wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);
45175 io_buf = &fallback_io_buf;
45176 }
45177
45178 wuffs_base__image_decoder::unique_ptr image_decoder(nullptr, &free);
45179 DecodeImageResult result =
45180 DecodeImage0(image_decoder, callbacks, input, *io_buf, quirks.repr,
45181 flags.repr, pixel_blend.repr, background_color.repr,
45182 max_incl_dimension.repr, max_incl_metadata_length.repr);
45183 callbacks.Done(result, input, *io_buf, std::move(image_decoder));
45184 return result;
45185 }
45186
45187 } // namespace wuffs_aux
45188
45189 #endif // !defined(WUFFS_CONFIG__MODULES) ||
45190 // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
45191
45192 // ---------------- Auxiliary - JSON
45193
45194 #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)
45195
45196 #include <utility>
45197
45198 namespace wuffs_aux {
45199
DecodeJsonResult(std::string && error_message0,uint64_t cursor_position0)45200 DecodeJsonResult::DecodeJsonResult(std::string&& error_message0,
45201 uint64_t cursor_position0)
45202 : error_message(std::move(error_message0)),
45203 cursor_position(cursor_position0) {}
45204
~DecodeJsonCallbacks()45205 DecodeJsonCallbacks::~DecodeJsonCallbacks() {}
45206
45207 void //
Done(DecodeJsonResult & result,sync_io::Input & input,IOBuffer & buffer)45208 DecodeJsonCallbacks::Done(DecodeJsonResult& result,
45209 sync_io::Input& input,
45210 IOBuffer& buffer) {}
45211
45212 const char DecodeJson_BadJsonPointer[] = //
45213 "wuffs_aux::DecodeJson: bad JSON Pointer";
45214 const char DecodeJson_NoMatch[] = //
45215 "wuffs_aux::DecodeJson: no match";
45216
DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)45217 DecodeJsonArgQuirks::DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)
45218 : repr(repr0) {}
45219
DecodeJsonArgQuirks(uint32_t * ptr0,size_t len0)45220 DecodeJsonArgQuirks::DecodeJsonArgQuirks(uint32_t* ptr0, size_t len0)
45221 : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
45222
45223 DecodeJsonArgQuirks //
DefaultValue()45224 DecodeJsonArgQuirks::DefaultValue() {
45225 return DecodeJsonArgQuirks(wuffs_base__empty_slice_u32());
45226 }
45227
DecodeJsonArgJsonPointer(std::string repr0)45228 DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0)
45229 : repr(repr0) {}
45230
45231 DecodeJsonArgJsonPointer //
DefaultValue()45232 DecodeJsonArgJsonPointer::DefaultValue() {
45233 return DecodeJsonArgJsonPointer(std::string());
45234 }
45235
45236 // --------
45237
45238 #define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN \
45239 while (tok_buf.meta.ri >= tok_buf.meta.wi) { \
45240 if (tok_status.repr == nullptr) { \
45241 goto done; \
45242 } else if (tok_status.repr == wuffs_base__suspension__short_write) { \
45243 tok_buf.compact(); \
45244 } else if (tok_status.repr == wuffs_base__suspension__short_read) { \
45245 if (!io_error_message.empty()) { \
45246 ret_error_message = std::move(io_error_message); \
45247 goto done; \
45248 } else if (cursor_index != io_buf->meta.ri) { \
45249 ret_error_message = \
45250 "wuffs_aux::DecodeJson: internal error: bad cursor_index"; \
45251 goto done; \
45252 } else if (io_buf->meta.closed) { \
45253 ret_error_message = \
45254 "wuffs_aux::DecodeJson: internal error: io_buf is closed"; \
45255 goto done; \
45256 } \
45257 io_buf->compact(); \
45258 if (io_buf->meta.wi >= io_buf->data.len) { \
45259 ret_error_message = \
45260 "wuffs_aux::DecodeJson: internal error: io_buf is full"; \
45261 goto done; \
45262 } \
45263 cursor_index = io_buf->meta.ri; \
45264 io_error_message = input.CopyIn(io_buf); \
45265 } else { \
45266 ret_error_message = tok_status.message(); \
45267 goto done; \
45268 } \
45269 tok_status = \
45270 dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
45271 if ((tok_buf.meta.ri > tok_buf.meta.wi) || \
45272 (tok_buf.meta.wi > tok_buf.data.len) || \
45273 (io_buf->meta.ri > io_buf->meta.wi) || \
45274 (io_buf->meta.wi > io_buf->data.len)) { \
45275 ret_error_message = \
45276 "wuffs_aux::DecodeJson: internal error: bad buffer indexes"; \
45277 goto done; \
45278 } \
45279 } \
45280 wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \
45281 uint64_t token_len = token.length(); \
45282 if ((io_buf->meta.ri < cursor_index) || \
45283 ((io_buf->meta.ri - cursor_index) < token_len)) { \
45284 ret_error_message = \
45285 "wuffs_aux::DecodeJson: internal error: bad token indexes"; \
45286 goto done; \
45287 } \
45288 uint8_t* token_ptr = io_buf->data.ptr + cursor_index; \
45289 (void)(token_ptr); \
45290 cursor_index += static_cast<size_t>(token_len)
45291
45292 // --------
45293
45294 namespace {
45295
45296 // DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
45297 // etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
45298 // out of bounds.
45299 //
45300 // The string returned is unescaped. If calling it again, this time with i=8,
45301 // the "b~1z" substring would be returned as "b/z".
45302 std::pair<std::string, size_t> //
DecodeJson_SplitJsonPointer(std::string & s,size_t i,bool allow_tilde_n_tilde_r_tilde_t)45303 DecodeJson_SplitJsonPointer(std::string& s,
45304 size_t i,
45305 bool allow_tilde_n_tilde_r_tilde_t) {
45306 std::string fragment;
45307 if (i > s.size()) {
45308 return std::make_pair(std::string(), 0);
45309 }
45310 while (i < s.size()) {
45311 char c = s[i];
45312 if (c == '/') {
45313 break;
45314 } else if (c != '~') {
45315 fragment.push_back(c);
45316 i++;
45317 continue;
45318 }
45319 i++;
45320 if (i >= s.size()) {
45321 return std::make_pair(std::string(), 0);
45322 }
45323 c = s[i];
45324 if (c == '0') {
45325 fragment.push_back('~');
45326 i++;
45327 continue;
45328 } else if (c == '1') {
45329 fragment.push_back('/');
45330 i++;
45331 continue;
45332 } else if (allow_tilde_n_tilde_r_tilde_t) {
45333 if (c == 'n') {
45334 fragment.push_back('\n');
45335 i++;
45336 continue;
45337 } else if (c == 'r') {
45338 fragment.push_back('\r');
45339 i++;
45340 continue;
45341 } else if (c == 't') {
45342 fragment.push_back('\t');
45343 i++;
45344 continue;
45345 }
45346 }
45347 return std::make_pair(std::string(), 0);
45348 }
45349 return std::make_pair(std::move(fragment), i);
45350 }
45351
45352 // --------
45353
45354 std::string //
DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer & tok_buf,wuffs_base__status & tok_status,wuffs_json__decoder::unique_ptr & dec,wuffs_base__io_buffer * io_buf,std::string & io_error_message,size_t & cursor_index,sync_io::Input & input,std::string & json_pointer_fragment)45355 DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,
45356 wuffs_base__status& tok_status,
45357 wuffs_json__decoder::unique_ptr& dec,
45358 wuffs_base__io_buffer* io_buf,
45359 std::string& io_error_message,
45360 size_t& cursor_index,
45361 sync_io::Input& input,
45362 std::string& json_pointer_fragment) {
45363 std::string ret_error_message;
45364 while (true) {
45365 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45366
45367 int64_t vbc = token.value_base_category();
45368 uint64_t vbd = token.value_base_detail();
45369 if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
45370 continue;
45371 } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||
45372 !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {
45373 return DecodeJson_NoMatch;
45374 } else if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST) {
45375 goto do_list;
45376 }
45377 goto do_dict;
45378 }
45379
45380 do_dict:
45381 // Alternate between these two things:
45382 // 1. Decode the next dict key (a string). If it matches the fragment, we're
45383 // done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)
45384 // so that there was no next dict key, we're done (failure).
45385 // 2. Otherwise, skip the next dict value.
45386 while (true) {
45387 for (std::string str; true;) {
45388 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45389
45390 int64_t vbc = token.value_base_category();
45391 uint64_t vbd = token.value_base_detail();
45392 switch (vbc) {
45393 case WUFFS_BASE__TOKEN__VBC__FILLER:
45394 continue;
45395
45396 case WUFFS_BASE__TOKEN__VBC__STRUCTURE:
45397 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45398 goto fail;
45399 }
45400 return DecodeJson_NoMatch;
45401
45402 case WUFFS_BASE__TOKEN__VBC__STRING: {
45403 if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
45404 // No-op.
45405 } else if (vbd &
45406 WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
45407 const char* ptr = // Convert from (uint8_t*).
45408 static_cast<const char*>(static_cast<void*>(token_ptr));
45409 str.append(ptr, static_cast<size_t>(token_len));
45410 } else {
45411 goto fail;
45412 }
45413 break;
45414 }
45415
45416 case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
45417 uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
45418 size_t n = wuffs_base__utf_8__encode(
45419 wuffs_base__make_slice_u8(
45420 &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
45421 static_cast<uint32_t>(vbd));
45422 const char* ptr = // Convert from (uint8_t*).
45423 static_cast<const char*>(static_cast<void*>(&u[0]));
45424 str.append(ptr, n);
45425 break;
45426 }
45427
45428 default:
45429 goto fail;
45430 }
45431
45432 if (token.continued()) {
45433 continue;
45434 }
45435 if (str == json_pointer_fragment) {
45436 return "";
45437 }
45438 goto skip_the_next_dict_value;
45439 }
45440
45441 skip_the_next_dict_value:
45442 for (uint32_t skip_depth = 0; true;) {
45443 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45444
45445 int64_t vbc = token.value_base_category();
45446 uint64_t vbd = token.value_base_detail();
45447 if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
45448 continue;
45449 } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
45450 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45451 skip_depth++;
45452 continue;
45453 }
45454 skip_depth--;
45455 }
45456
45457 if (skip_depth == 0) {
45458 break;
45459 }
45460 } // skip_the_next_dict_value
45461 } // do_dict
45462
45463 do_list:
45464 do {
45465 wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(
45466 wuffs_base__make_slice_u8(
45467 static_cast<uint8_t*>(static_cast<void*>(
45468 const_cast<char*>(json_pointer_fragment.data()))),
45469 json_pointer_fragment.size()),
45470 WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
45471 if (!result_u64.status.is_ok()) {
45472 return DecodeJson_NoMatch;
45473 }
45474 uint64_t remaining = result_u64.value;
45475 if (remaining == 0) {
45476 goto check_that_a_value_follows;
45477 }
45478 for (uint32_t skip_depth = 0; true;) {
45479 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45480
45481 int64_t vbc = token.value_base_category();
45482 uint64_t vbd = token.value_base_detail();
45483 if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
45484 continue;
45485 } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
45486 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45487 skip_depth++;
45488 continue;
45489 }
45490 if (skip_depth == 0) {
45491 return DecodeJson_NoMatch;
45492 }
45493 skip_depth--;
45494 }
45495
45496 if (skip_depth > 0) {
45497 continue;
45498 }
45499 remaining--;
45500 if (remaining == 0) {
45501 goto check_that_a_value_follows;
45502 }
45503 }
45504 } while (false); // do_list
45505
45506 check_that_a_value_follows:
45507 while (true) {
45508 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45509
45510 int64_t vbc = token.value_base_category();
45511 uint64_t vbd = token.value_base_detail();
45512 if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
45513 continue;
45514 }
45515
45516 // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
45517 // that we're only peeking at the next token.
45518 tok_buf.meta.ri--;
45519 cursor_index -= static_cast<size_t>(token_len);
45520
45521 if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&
45522 (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {
45523 return DecodeJson_NoMatch;
45524 }
45525 return "";
45526 } // check_that_a_value_follows
45527
45528 fail:
45529 return "wuffs_aux::DecodeJson: internal error: unexpected token";
45530 done:
45531 return ret_error_message;
45532 }
45533
45534 } // namespace
45535
45536 // --------
45537
45538 DecodeJsonResult //
DecodeJson(DecodeJsonCallbacks & callbacks,sync_io::Input & input,DecodeJsonArgQuirks quirks,DecodeJsonArgJsonPointer json_pointer)45539 DecodeJson(DecodeJsonCallbacks& callbacks,
45540 sync_io::Input& input,
45541 DecodeJsonArgQuirks quirks,
45542 DecodeJsonArgJsonPointer json_pointer) {
45543 // Prepare the wuffs_base__io_buffer and the resultant error_message.
45544 wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
45545 wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
45546 std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
45547 if (!io_buf) {
45548 fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
45549 fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
45550 io_buf = &fallback_io_buf;
45551 }
45552 // cursor_index is discussed at
45553 // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
45554 size_t cursor_index = 0;
45555 std::string ret_error_message;
45556 std::string io_error_message;
45557
45558 do {
45559 // Prepare the low-level JSON decoder.
45560 wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();
45561 if (!dec) {
45562 ret_error_message = "wuffs_aux::DecodeJson: out of memory";
45563 goto done;
45564 } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
45565 ret_error_message =
45566 "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
45567 goto done;
45568 }
45569 bool allow_tilde_n_tilde_r_tilde_t = false;
45570 for (size_t i = 0; i < quirks.repr.len; i++) {
45571 dec->set_quirk_enabled(quirks.repr.ptr[i], true);
45572 if (quirks.repr.ptr[i] ==
45573 WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {
45574 allow_tilde_n_tilde_r_tilde_t = true;
45575 }
45576 }
45577
45578 // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
45579 wuffs_base__token tok_array[256];
45580 wuffs_base__token_buffer tok_buf =
45581 wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
45582 &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
45583 wuffs_base__status tok_status =
45584 dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
45585
45586 // Prepare other state.
45587 int32_t depth = 0;
45588 std::string str;
45589
45590 // Walk the (optional) JSON Pointer.
45591 for (size_t i = 0; i < json_pointer.repr.size();) {
45592 if (json_pointer.repr[i] != '/') {
45593 ret_error_message = DecodeJson_BadJsonPointer;
45594 goto done;
45595 }
45596 std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
45597 json_pointer.repr, i + 1, allow_tilde_n_tilde_r_tilde_t);
45598 i = split.second;
45599 if (i == 0) {
45600 ret_error_message = DecodeJson_BadJsonPointer;
45601 goto done;
45602 }
45603 ret_error_message = DecodeJson_WalkJsonPointerFragment(
45604 tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,
45605 input, split.first);
45606 if (!ret_error_message.empty()) {
45607 goto done;
45608 }
45609 }
45610
45611 // Loop, doing these two things:
45612 // 1. Get the next token.
45613 // 2. Process that token.
45614 while (true) {
45615 WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
45616
45617 int64_t vbc = token.value_base_category();
45618 uint64_t vbd = token.value_base_detail();
45619 switch (vbc) {
45620 case WUFFS_BASE__TOKEN__VBC__FILLER:
45621 continue;
45622
45623 case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
45624 if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
45625 ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
45626 if (!ret_error_message.empty()) {
45627 goto done;
45628 }
45629 depth++;
45630 if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
45631 ret_error_message =
45632 "wuffs_aux::DecodeJson: internal error: bad depth";
45633 goto done;
45634 }
45635 continue;
45636 }
45637 ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
45638 depth--;
45639 if (depth < 0) {
45640 ret_error_message =
45641 "wuffs_aux::DecodeJson: internal error: bad depth";
45642 goto done;
45643 }
45644 goto parsed_a_value;
45645 }
45646
45647 case WUFFS_BASE__TOKEN__VBC__STRING: {
45648 if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
45649 // No-op.
45650 } else if (vbd &
45651 WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
45652 const char* ptr = // Convert from (uint8_t*).
45653 static_cast<const char*>(static_cast<void*>(token_ptr));
45654 str.append(ptr, static_cast<size_t>(token_len));
45655 } else {
45656 goto fail;
45657 }
45658 if (token.continued()) {
45659 continue;
45660 }
45661 ret_error_message = callbacks.AppendTextString(std::move(str));
45662 str.clear();
45663 goto parsed_a_value;
45664 }
45665
45666 case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
45667 uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
45668 size_t n = wuffs_base__utf_8__encode(
45669 wuffs_base__make_slice_u8(
45670 &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
45671 static_cast<uint32_t>(vbd));
45672 const char* ptr = // Convert from (uint8_t*).
45673 static_cast<const char*>(static_cast<void*>(&u[0]));
45674 str.append(ptr, n);
45675 if (token.continued()) {
45676 continue;
45677 }
45678 goto fail;
45679 }
45680
45681 case WUFFS_BASE__TOKEN__VBC__LITERAL: {
45682 ret_error_message =
45683 (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)
45684 ? callbacks.AppendNull()
45685 : callbacks.AppendBool(vbd &
45686 WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
45687 goto parsed_a_value;
45688 }
45689
45690 case WUFFS_BASE__TOKEN__VBC__NUMBER: {
45691 if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {
45692 if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {
45693 wuffs_base__result_i64 r = wuffs_base__parse_number_i64(
45694 wuffs_base__make_slice_u8(token_ptr,
45695 static_cast<size_t>(token_len)),
45696 WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
45697 if (r.status.is_ok()) {
45698 ret_error_message = callbacks.AppendI64(r.value);
45699 goto parsed_a_value;
45700 }
45701 }
45702 if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {
45703 wuffs_base__result_f64 r = wuffs_base__parse_number_f64(
45704 wuffs_base__make_slice_u8(token_ptr,
45705 static_cast<size_t>(token_len)),
45706 WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
45707 if (r.status.is_ok()) {
45708 ret_error_message = callbacks.AppendF64(r.value);
45709 goto parsed_a_value;
45710 }
45711 }
45712 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {
45713 ret_error_message = callbacks.AppendF64(
45714 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45715 0xFFF0000000000000ul));
45716 goto parsed_a_value;
45717 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {
45718 ret_error_message = callbacks.AppendF64(
45719 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45720 0x7FF0000000000000ul));
45721 goto parsed_a_value;
45722 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {
45723 ret_error_message = callbacks.AppendF64(
45724 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45725 0xFFFFFFFFFFFFFFFFul));
45726 goto parsed_a_value;
45727 } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {
45728 ret_error_message = callbacks.AppendF64(
45729 wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
45730 0x7FFFFFFFFFFFFFFFul));
45731 goto parsed_a_value;
45732 }
45733 goto fail;
45734 }
45735 }
45736
45737 fail:
45738 ret_error_message =
45739 "wuffs_aux::DecodeJson: internal error: unexpected token";
45740 goto done;
45741
45742 parsed_a_value:
45743 // If an error was encountered, we are done. Otherwise, (depth == 0)
45744 // after parsing a value is equivalent to having decoded the entire JSON
45745 // value (for an empty json_pointer query) or having decoded the
45746 // pointed-to JSON value (for a non-empty json_pointer query). In the
45747 // latter case, we are also done.
45748 //
45749 // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
45750 // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
45751 // the entire JSON value should also consume any trailing filler, in case
45752 // the DecodeJson caller wants to subsequently check that the input is
45753 // completely exhausted (and otherwise raise "valid JSON followed by
45754 // further (unexpected) data"). We aren't done yet. Instead, keep the
45755 // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
45756 // decode_tokens returns an ok status.
45757 if (!ret_error_message.empty() ||
45758 ((depth == 0) && !json_pointer.repr.empty())) {
45759 goto done;
45760 }
45761 }
45762 } while (false);
45763
45764 done:
45765 DecodeJsonResult result(
45766 std::move(ret_error_message),
45767 wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
45768 callbacks.Done(result, input, *io_buf);
45769 return result;
45770 }
45771
45772 #undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN
45773
45774 } // namespace wuffs_aux
45775
45776 #endif // !defined(WUFFS_CONFIG__MODULES) ||
45777 // defined(WUFFS_CONFIG__MODULE__AUX__JSON)
45778
45779 #endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
45780
45781 #endif // WUFFS_IMPLEMENTATION
45782
45783 #if defined(__GNUC__)
45784 #pragma GCC diagnostic pop
45785 #elif defined(__clang__)
45786 #pragma clang diagnostic pop
45787 #endif
45788
45789 #endif // WUFFS_INCLUDE_GUARD
45790