From 870cfd18a7fe77a97a2258f564e9806d3474d56b Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Mon, 5 Aug 2024 00:14:21 +1000 Subject: [PATCH] release: wuffs gen -version=0.4.0-alpha.6 --- release/c/wuffs-v0.4.c | 1586 +++++++++++++++++++++------------------- 1 file changed, 826 insertions(+), 760 deletions(-) diff --git a/release/c/wuffs-v0.4.c b/release/c/wuffs-v0.4.c index 3fe55ee9..7aba0bc5 100644 --- a/release/c/wuffs-v0.4.c +++ b/release/c/wuffs-v0.4.c @@ -81,15 +81,15 @@ extern "C" { // each major.minor branch, the commit count should increase monotonically. // // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision -// 3be81643cc77e83e0125b150502ea273bf02839d committed on 2024-07-09. +// ffb64df0a0b127e20d5eb0e1aab40c29409c0c3e committed on 2024-08-04. #define WUFFS_VERSION 0x000040000 #define WUFFS_VERSION_MAJOR 0 #define WUFFS_VERSION_MINOR 4 #define WUFFS_VERSION_PATCH 0 -#define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.5" -#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3771 -#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20240709 -#define WUFFS_VERSION_STRING "0.4.0-alpha.5+3771.20240709" +#define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.6" +#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3789 +#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20240804 +#define WUFFS_VERSION_STRING "0.4.0-alpha.6+3789.20240804" // ---------------- Private Implementation Macros Re-definition Check @@ -176,12 +176,62 @@ extern "C" { #elif defined(_MSC_VER) // (#if-chain ref AVOID_CPU_ARCH_1) #if defined(_M_X64) -// We need for the __cpuid function. -#include + +// On X86_64, Microsoft Visual C/C++ (MSVC) only supports SSE2 by default. +// There are /arch:SSE2, /arch:AVX and /arch:AVX2 compiler flags (the AVX2 one +// is roughly equivalent to X86_64_V3), but there is no /arch:SSE42 compiler +// flag that's equivalent to X86_64_V2. +// +// For getting maximum performance with X86_64 MSVC and Wuffs, pass /arch:AVX2 +// (and then test on the oldest hardware you intend to support). +// +// Absent that compiler flag, either define one of the three macros listed +// below or else the X86_64 SIMD code will be disabled and you'll get a #pragma +// message stating this library "performs best with /arch:AVX2". This message +// is harmless and ignorable, in that the non-SIMD code is still correct and +// reasonably performant, but is a reminder that when combining Wuffs and MSVC, +// some compiler configuration is required for maximum performance. +// +// - WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY +// - WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V2 (enables SSE4.2 and below) +// - WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V3 (enables AVX2 and below) +// +// Defining the first one (WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY) +// or defining none of those three (the default state) are equivalent (in that +// both disable the SIMD code paths), other than that pragma message. +// +// When defining these WUFFS_CONFIG__ENABLE_ETC macros with MSVC, be aware that +// some users report it leading to ICEs (Internal Compiler Errors), but other +// users report no problems at all (and improved performance). It's unclear +// exactly what combination of SIMD code and MSVC configuration lead to ICEs. +// Do your own testing with your own MSVC version and configuration. +// +// https://github.com/google/wuffs/issues/148 +// https://github.com/google/wuffs/issues/151 +// https://developercommunity.visualstudio.com/t/fatal--error-C1001:-Internal-compiler-er/10703305 +// +// Clang (including clang-cl) and GCC don't need this WUFFS_CONFIG__ETC macro +// machinery, or having the Wuffs-the-library user to fiddle with compiler +// flags, because they support "__attribute__((target(arg)))". +#if defined(__AVX2__) || defined(__clang__) || \ + defined(WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V3) #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64 #define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2 -#if defined(__AVX2__) || defined(__clang__) +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3 +#elif defined(WUFFS_CONFIG__ENABLE_MSVC_CPU_ARCH__X86_64_V2) +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64 +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2 +#elif !defined(WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY) +#pragma message("Wuffs with MSVC+X64 performs best with /arch:AVX2") +#endif // defined(__AVX2__) || defined(__clang__) || etc + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) + +#if defined(WUFFS_CONFIG__DISABLE_MSVC_CPU_ARCH__X86_64_FAMILY) +#error "MSVC_CPU_ARCH simultaneously enabled and disabled" +#endif +#include // intrin.h isn't enough for X64 SIMD, with clang-cl, if we want to use // "__attribute__((target(arg)))" without e.g. "/arch:AVX". // @@ -191,23 +241,9 @@ extern "C" { #include // AVX, AVX2, FMA, POPCNT #include // SSE4.2 #include // AES, PCLMUL -#define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3 - -#else // defined(__AVX2__) || defined(__clang__) - -// clang-cl (which defines both __clang__ and _MSC_VER) supports -// "__attribute__((target(arg)))". -// -// For MSVC's cl.exe (unlike clang or gcc), SIMD capability is a compile-time -// property of the source file (e.g. a /arch:AVX2 or -mavx2 compiler flag), not -// of individual functions (that can be conditionally selected at runtime). -#if !defined(WUFFS_CONFIG__I_KNOW_THAT_WUFFS_MSVC_PERFORMS_BEST_WITH_ARCH_AVX2) -#pragma message("Wuffs with MSVC+IX86/X64 performs best with /arch:AVX2") -#endif -#endif // defined(__AVX2__) || defined(__clang__) +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) #endif // defined(_M_X64) - #endif // (#if-chain ref AVOID_CPU_ARCH_1) #endif // (#if-chain ref AVOID_CPU_ARCH_0) @@ -914,6 +950,8 @@ typedef struct wuffs_base__transform__output__struct { #define WUFFS_BASE__QUIRK_IGNORE_CHECKSUM 1 +#define WUFFS_BASE__QUIRK_QUALITY 2 + // -------- // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a @@ -1979,6 +2017,20 @@ WUFFS_BASE__MAYBE_STATIC int32_t // wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data, bool prefix_closed); +// ---------------- Quirk Values + +// These constants are the value half of a key-value pair, where the key is +// WUFFS_BASE__QUIRK_QUALITY. +// +// In the Wuffs API, set_quirk takes a u64 value. These macro definitions are +// likewise unsigned values (uint64_t) but for this particular key, they are +// best interpreted as signed values (int64_t). "Lower-than-default quality" +// and "higher-than-default quality", as signed values, are -1 and +1. +// +// See doc/note/quirks.md for some more discussion about trade-offs. +#define WUFFS_BASE__QUIRK_QUALITY__VALUE__LOWER_QUALITY UINT64_MAX +#define WUFFS_BASE__QUIRK_QUALITY__VALUE__HIGHER_QUALITY ((uint64_t)1) + // ---------------- Ranges and Rects // See https://github.com/google/wuffs/blob/main/doc/note/ranges-and-rects.md @@ -3351,49 +3403,53 @@ wuffs_base__make_token(uint64_t repr) { // -------- +// clang-format off + +// -------- + #define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF -#define WUFFS_BASE__TOKEN__VALUE__SHIFT 17 -#define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17 -#define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42 -#define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17 +#define WUFFS_BASE__TOKEN__VALUE__SHIFT 17 +#define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17 +#define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42 +#define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17 #define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38 -#define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17 -#define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16 -#define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0 +#define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17 +#define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16 +#define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0 -#define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46 +#define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46 // -------- -#define WUFFS_BASE__TOKEN__VBC__FILLER 0 -#define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1 -#define WUFFS_BASE__TOKEN__VBC__STRING 2 -#define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3 -#define WUFFS_BASE__TOKEN__VBC__LITERAL 4 -#define WUFFS_BASE__TOKEN__VBC__NUMBER 5 -#define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6 +#define WUFFS_BASE__TOKEN__VBC__FILLER 0 +#define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1 +#define WUFFS_BASE__TOKEN__VBC__STRING 2 +#define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3 +#define WUFFS_BASE__TOKEN__VBC__LITERAL 4 +#define WUFFS_BASE__TOKEN__VBC__NUMBER 5 +#define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6 #define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED 7 // -------- -#define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001 +#define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001 #define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002 -#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004 +#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004 // COMMENT_ANY is a bit-wise or of COMMENT_BLOCK AND COMMENT_LINE. -#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006 +#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006 // -------- -#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001 -#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002 +#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001 +#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020 #define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040 -#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000 -#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000 -#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000 +#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000 +#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000 +#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000 // -------- @@ -3413,11 +3469,11 @@ wuffs_base__make_token(uint64_t repr) { // // The lack of any particular bit is conservative: it is valid for all-ASCII // strings, in a single- or multi-token chain, to have none of these bits set. -#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001 -#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002 +#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001 +#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_UTF_8 0x00004 -#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010 -#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020 +#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010 +#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020 #define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_ASCII 0x00040 // CONVERT_D_DST_S_SRC means that multiples of S source bytes (possibly padded) @@ -3432,22 +3488,22 @@ wuffs_base__make_token(uint64_t repr) { // When src is the empty string, multiple conversion algorithms are applicable // (so these bits are not necessarily mutually exclusive), all producing the // same empty dst string. -#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100 -#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200 +#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100 +#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00400 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00800 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x01000 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x02000 -#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000 +#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_HEX 0x08000 #define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_STD 0x10000 // -------- #define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001 -#define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002 -#define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004 -#define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008 +#define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002 +#define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004 +#define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008 // -------- @@ -3460,8 +3516,8 @@ wuffs_base__make_token(uint64_t repr) { // For a source string of "+123" or "-0x9A", only the first two are valid. // // For a source string of "123.", only the first one is valid. -#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001 -#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002 +#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001 +#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004 #define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010 @@ -3473,11 +3529,15 @@ wuffs_base__make_token(uint64_t repr) { // "300", which are big-endian, little-endian or text. For binary formats, the // token length (after adjusting for FORMAT_IGNORE_ETC) discriminates // e.g. u16 little-endian vs u32 little-endian. -#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100 +#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100 #define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200 -#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400 +#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400 -#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000 +#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000 + +// -------- + +// clang-format on // -------- @@ -9602,6 +9662,7 @@ extern const char wuffs_jpeg__error__bad_sof_marker[]; extern const char wuffs_jpeg__error__bad_sos_marker[]; extern const char wuffs_jpeg__error__bad_header[]; extern const char wuffs_jpeg__error__bad_marker[]; +extern const char wuffs_jpeg__error__bad_scan_count[]; extern const char wuffs_jpeg__error__missing_huffman_table[]; extern const char wuffs_jpeg__error__missing_quantization_table[]; extern const char wuffs_jpeg__error__truncated_input[]; @@ -9846,6 +9907,12 @@ struct wuffs_jpeg__decoder__struct { uint32_t f_bitstream_ri; uint32_t f_bitstream_wi; bool f_bitstream_is_closed; + bool f_expect_multiple_scans; + bool f_use_lower_quality; + bool f_swizzle_immediately; + wuffs_base__status f_swizzle_immediately_status; + uint32_t f_swizzle_immediately_b_offsets[10]; + uint32_t f_swizzle_immediately_c_offsets[5]; uint32_t f_bitstream_padding; uint16_t f_quant_tables[4][64]; uint16_t f_saved_quant_tables[4][64]; @@ -9881,6 +9948,7 @@ struct wuffs_jpeg__decoder__struct { uint32_t p_skip_past_the_next_restart_marker; uint32_t (*choosy_decode_mcu)( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my); @@ -9889,6 +9957,7 @@ struct wuffs_jpeg__decoder__struct { struct { uint8_t f_bitstream_buffer[2048]; uint16_t f_mcu_blocks[10][64]; + uint8_t f_swizzle_immediately_buffer[640]; uint8_t f_swizzle_ycck_scratch_buffer_2k[2048]; uint8_t f_dht_temp_counts[16]; uint8_t f_dht_temp_bit_lengths[256]; @@ -14993,6 +15062,7 @@ struct wuffs_xz__decoder__struct { #include #include +#include namespace wuffs_aux { @@ -15005,6 +15075,8 @@ using IOBuffer = wuffs_base__io_buffer; // nullptr, since calling free(nullptr) is a no-op. using MemOwner = std::unique_ptr; +using QuirkKeyValuePair = std::pair; + namespace sync_io { // -------- @@ -15187,13 +15259,14 @@ class DecodeCborCallbacks { // DecodeCborArgQuirks wraps an optional argument to DecodeCbor. struct DecodeCborArgQuirks { - explicit DecodeCborArgQuirks(wuffs_base__slice_u32 repr0); - explicit DecodeCborArgQuirks(uint32_t* ptr, size_t len); + explicit DecodeCborArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0); // DefaultValue returns an empty slice. static DecodeCborArgQuirks DefaultValue(); - wuffs_base__slice_u32 repr; + const QuirkKeyValuePair* ptr; + const size_t len; }; // DecodeCbor calls callbacks based on the CBOR-formatted data in input. @@ -15401,13 +15474,14 @@ extern const char DecodeImage_UnsupportedPixelFormat[]; // DecodeImageArgQuirks wraps an optional argument to DecodeImage. struct DecodeImageArgQuirks { - explicit DecodeImageArgQuirks(wuffs_base__slice_u32 repr0); - explicit DecodeImageArgQuirks(uint32_t* ptr, size_t len); + explicit DecodeImageArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0); // DefaultValue returns an empty slice. static DecodeImageArgQuirks DefaultValue(); - wuffs_base__slice_u32 repr; + const QuirkKeyValuePair* ptr; + const size_t len; }; // DecodeImageArgFlags wraps an optional argument to DecodeImage. @@ -15619,13 +15693,14 @@ extern const char DecodeJson_NoMatch[]; // DecodeJsonArgQuirks wraps an optional argument to DecodeJson. struct DecodeJsonArgQuirks { - explicit DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0); - explicit DecodeJsonArgQuirks(uint32_t* ptr, size_t len); + explicit DecodeJsonArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0); // DefaultValue returns an empty slice. static DecodeJsonArgQuirks DefaultValue(); - wuffs_base__slice_u32 repr; + const QuirkKeyValuePair* ptr; + const size_t len; }; // DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson. @@ -15835,6 +15910,9 @@ wuffs_private_impl__u64__sat_sub_indirect(uint64_t* x, uint64_t y) { // ---------------- Numeric Types (Utility) +#define wuffs_base__utility__sign_extend_convert_u8_u32(a) \ + ((uint32_t)(int32_t)(int8_t)(a)) + #define wuffs_base__utility__sign_extend_convert_u16_u32(a) \ ((uint32_t)(int32_t)(int16_t)(a)) @@ -16544,8 +16622,10 @@ wuffs_base__pixel_swizzler__swizzle_ycck( const wuffs_base__pixel_swizzler* p, wuffs_base__pixel_buffer* dst, wuffs_base__slice_u8 dst_palette, - uint32_t width, - uint32_t height, + uint32_t x_min_incl, + uint32_t x_max_excl, + uint32_t y_min_incl, + uint32_t y_max_excl, wuffs_base__slice_u8 src0, wuffs_base__slice_u8 src1, wuffs_base__slice_u8 src2, @@ -28480,8 +28560,10 @@ wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row( static void // wuffs_private_impl__swizzle_ycck__general__triangle_filter( wuffs_base__pixel_buffer* dst, - uint32_t width, - uint32_t height, + uint32_t x_min_incl, + uint32_t x_max_excl, + uint32_t y_min_incl, + uint32_t y_max_excl, const uint8_t* src_ptr0, const uint8_t* src_ptr1, const uint8_t* src_ptr2, @@ -28503,6 +28585,10 @@ wuffs_private_impl__swizzle_ycck__general__triangle_filter( uint8_t* scratch_buffer_2k_ptr, wuffs_private_impl__swizzle_ycc__upsample_func (*upfuncs)[4][4], wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) { + if ((x_min_incl != 0) || (y_min_incl != 0)) { + return; + } + wuffs_private_impl__swizzle_ycc__upsample_func upfunc0 = (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u]; wuffs_private_impl__swizzle_ycc__upsample_func upfunc1 = @@ -28515,7 +28601,7 @@ wuffs_private_impl__swizzle_ycck__general__triangle_filter( // First row. uint32_t h1v2_bias = 1u; wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row( - dst, width, 0u, // + dst, x_max_excl, 0u, // src_ptr0, src_ptr1, src_ptr2, src_ptr3, // stride0, stride1, stride2, stride3, // inv_h0, inv_h1, inv_h2, inv_h3, // @@ -28527,10 +28613,10 @@ wuffs_private_impl__swizzle_ycck__general__triangle_filter( h1v2_bias = 2u; // Middle rows. - bool last_row = height == 2u * half_height_for_2to1; - uint32_t y_max_excl = last_row ? (height - 1u) : height; + bool last_row = y_max_excl == 2u * half_height_for_2to1; + uint32_t middle_y_max_excl = last_row ? (y_max_excl - 1u) : y_max_excl; uint32_t y; - for (y = 1u; y < y_max_excl; y++) { + for (y = 1u; y < middle_y_max_excl; y++) { const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0); const uint8_t* src0_minor = (inv_v0 != 2u) @@ -28557,11 +28643,11 @@ wuffs_private_impl__swizzle_ycck__general__triangle_filter( uint32_t total_src_len3 = 0u; uint32_t x = 0u; - while (x < width) { + while (x < x_max_excl) { bool first_column = x == 0u; uint32_t end = x + 480u; - if (end > width) { - end = width; + if (end > x_max_excl) { + end = x_max_excl; } uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0; @@ -28617,9 +28703,9 @@ wuffs_private_impl__swizzle_ycck__general__triangle_filter( } // Last row. - if (y_max_excl != height) { + if (middle_y_max_excl != y_max_excl) { wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row( - dst, width, height - 1u, // + dst, x_max_excl, middle_y_max_excl, // src_ptr0, src_ptr1, src_ptr2, src_ptr3, // stride0, stride1, stride2, stride3, // inv_h0, inv_h1, inv_h2, inv_h3, // @@ -28715,8 +28801,10 @@ wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row( static void // wuffs_private_impl__swizzle_ycc__general__triangle_filter( wuffs_base__pixel_buffer* dst, - uint32_t width, - uint32_t height, + uint32_t x_min_incl, + uint32_t x_max_excl, + uint32_t y_min_incl, + uint32_t y_max_excl, const uint8_t* src_ptr0, const uint8_t* src_ptr1, const uint8_t* src_ptr2, @@ -28734,6 +28822,10 @@ wuffs_private_impl__swizzle_ycc__general__triangle_filter( uint8_t* scratch_buffer_2k_ptr, wuffs_private_impl__swizzle_ycc__upsample_func (*upfuncs)[4][4], wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) { + if ((x_min_incl != 0) || (y_min_incl != 0)) { + return; + } + wuffs_private_impl__swizzle_ycc__upsample_func upfunc0 = (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u]; wuffs_private_impl__swizzle_ycc__upsample_func upfunc1 = @@ -28744,7 +28836,7 @@ wuffs_private_impl__swizzle_ycc__general__triangle_filter( // First row. uint32_t h1v2_bias = 1u; wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row( - dst, width, 0u, // + dst, x_max_excl, 0u, // src_ptr0, src_ptr1, src_ptr2, // stride0, stride1, stride2, // inv_h0, inv_h1, inv_h2, // @@ -28756,10 +28848,10 @@ wuffs_private_impl__swizzle_ycc__general__triangle_filter( h1v2_bias = 2u; // Middle rows. - bool last_row = height == 2u * half_height_for_2to1; - uint32_t y_max_excl = last_row ? (height - 1u) : height; + bool last_row = y_max_excl == 2u * half_height_for_2to1; + uint32_t middle_y_max_excl = last_row ? (y_max_excl - 1u) : y_max_excl; uint32_t y; - for (y = 1u; y < y_max_excl; y++) { + for (y = 1u; y < middle_y_max_excl; y++) { const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0); const uint8_t* src0_minor = (inv_v0 != 2u) @@ -28780,11 +28872,11 @@ wuffs_private_impl__swizzle_ycc__general__triangle_filter( uint32_t total_src_len2 = 0u; uint32_t x = 0u; - while (x < width) { + while (x < x_max_excl) { bool first_column = x == 0u; uint32_t end = x + 672u; - if (end > width) { - end = width; + if (end > x_max_excl) { + end = x_max_excl; } uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0; @@ -28829,16 +28921,16 @@ wuffs_private_impl__swizzle_ycc__general__triangle_filter( } // Last row. - if (y_max_excl != height) { + if (middle_y_max_excl != y_max_excl) { wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row( - dst, width, height - 1u, // - src_ptr0, src_ptr1, src_ptr2, // - stride0, stride1, stride2, // - inv_h0, inv_h1, inv_h2, // - inv_v0, inv_v1, inv_v2, // - half_width_for_2to1, // - h1v2_bias, // - scratch_buffer_2k_ptr, // + dst, x_max_excl, middle_y_max_excl, // + src_ptr0, src_ptr1, src_ptr2, // + stride0, stride1, stride2, // + inv_h0, inv_h1, inv_h2, // + inv_v0, inv_v1, inv_v2, // + half_width_for_2to1, // + h1v2_bias, // + scratch_buffer_2k_ptr, // upfunc0, upfunc1, upfunc2, conv3func); } } @@ -28846,8 +28938,10 @@ wuffs_private_impl__swizzle_ycc__general__triangle_filter( static void // wuffs_private_impl__swizzle_ycc__general__box_filter( wuffs_base__pixel_buffer* dst, - uint32_t width, - uint32_t height, + uint32_t x_min_incl, + uint32_t x_max_excl, + uint32_t y_min_incl, + uint32_t y_max_excl, const uint8_t* src_ptr0, const uint8_t* src_ptr1, const uint8_t* src_ptr2, @@ -28873,41 +28967,44 @@ wuffs_private_impl__swizzle_ycc__general__box_filter( (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u]; uint32_t y; - for (y = 0u; y < height; y++) { - const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0); - const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1); - const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2); - - uint32_t x = 0u; - while (x < width) { + for (y = y_min_incl; y < y_max_excl; y++) { + const uint8_t* src0_major = + src_ptr0 + (((y - y_min_incl) / inv_v0) * (size_t)stride0); + const uint8_t* src1_major = + src_ptr1 + (((y - y_min_incl) / inv_v1) * (size_t)stride1); + const uint8_t* src2_major = + src_ptr2 + (((y - y_min_incl) / inv_v2) * (size_t)stride2); + + uint32_t x = x_min_incl; + while (x < x_max_excl) { uint32_t end = x + 672u; - if (end > width) { - end = width; + if (end > x_max_excl) { + end = x_max_excl; } uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0; uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1; uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2; - const uint8_t* up0 = (*upfunc0)( // - scratch_buffer_2k_ptr + (0u * 672u), // - src0_major + (x / inv_h0), // - src0_major + (x / inv_h0), // - src_len0, // + const uint8_t* up0 = (*upfunc0)( // + scratch_buffer_2k_ptr + (0u * 672u), // + src0_major + ((x - x_min_incl) / inv_h0), // + src0_major + ((x - x_min_incl) / inv_h0), // + src_len0, // 0u, false, false); - const uint8_t* up1 = (*upfunc1)( // - scratch_buffer_2k_ptr + (1u * 672u), // - src1_major + (x / inv_h1), // - src1_major + (x / inv_h1), // - src_len1, // + const uint8_t* up1 = (*upfunc1)( // + scratch_buffer_2k_ptr + (1u * 672u), // + src1_major + ((x - x_min_incl) / inv_h1), // + src1_major + ((x - x_min_incl) / inv_h1), // + src_len1, // 0u, false, false); - const uint8_t* up2 = (*upfunc2)( // - scratch_buffer_2k_ptr + (2u * 672u), // - src2_major + (x / inv_h2), // - src2_major + (x / inv_h2), // - src_len2, // + const uint8_t* up2 = (*upfunc2)( // + scratch_buffer_2k_ptr + (2u * 672u), // + src2_major + ((x - x_min_incl) / inv_h2), // + src2_major + ((x - x_min_incl) / inv_h2), // + src_len2, // 0u, false, false); (*conv3func)(dst, x, end, y, up0, up1, up2); @@ -28916,6 +29013,100 @@ wuffs_private_impl__swizzle_ycc__general__box_filter( } } +static void // +wuffs_private_impl__swizzle_ycck__general__box_filter( + wuffs_base__pixel_buffer* dst, + uint32_t x_min_incl, + uint32_t x_max_excl, + uint32_t y_min_incl, + uint32_t y_max_excl, + const uint8_t* src_ptr0, + const uint8_t* src_ptr1, + const uint8_t* src_ptr2, + const uint8_t* src_ptr3, + uint32_t stride0, + uint32_t stride1, + uint32_t stride2, + uint32_t stride3, + uint32_t inv_h0, + uint32_t inv_h1, + uint32_t inv_h2, + uint32_t inv_h3, + uint32_t inv_v0, + uint32_t inv_v1, + uint32_t inv_v2, + uint32_t inv_v3, + uint32_t half_width_for_2to1, + uint32_t half_height_for_2to1, + uint8_t* scratch_buffer_2k_ptr, + wuffs_private_impl__swizzle_ycc__upsample_func (*upfuncs)[4][4], + wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) { + wuffs_private_impl__swizzle_ycc__upsample_func upfunc0 = + (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u]; + wuffs_private_impl__swizzle_ycc__upsample_func upfunc1 = + (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u]; + wuffs_private_impl__swizzle_ycc__upsample_func upfunc2 = + (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u]; + wuffs_private_impl__swizzle_ycc__upsample_func upfunc3 = + (*upfuncs)[(inv_h3 - 1u) & 3u][(inv_v3 - 1u) & 3u]; + + uint32_t y; + for (y = y_min_incl; y < y_max_excl; y++) { + const uint8_t* src0_major = + src_ptr0 + (((y - y_min_incl) / inv_v0) * (size_t)stride0); + const uint8_t* src1_major = + src_ptr1 + (((y - y_min_incl) / inv_v1) * (size_t)stride1); + const uint8_t* src2_major = + src_ptr2 + (((y - y_min_incl) / inv_v2) * (size_t)stride2); + const uint8_t* src3_major = + src_ptr3 + (((y - y_min_incl) / inv_v3) * (size_t)stride3); + + uint32_t x = x_min_incl; + while (x < x_max_excl) { + uint32_t end = x + 480u; + if (end > x_max_excl) { + end = x_max_excl; + } + + uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0; + uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1; + uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2; + uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3; + + const uint8_t* up0 = (*upfunc0)( // + scratch_buffer_2k_ptr + (0u * 480u), // + src0_major + ((x - x_min_incl) / inv_h0), // + src0_major + ((x - x_min_incl) / inv_h0), // + src_len0, // + 0u, false, false); + + const uint8_t* up1 = (*upfunc1)( // + scratch_buffer_2k_ptr + (1u * 480u), // + src1_major + ((x - x_min_incl) / inv_h1), // + src1_major + ((x - x_min_incl) / inv_h1), // + src_len1, // + 0u, false, false); + + const uint8_t* up2 = (*upfunc2)( // + scratch_buffer_2k_ptr + (2u * 480u), // + src2_major + ((x - x_min_incl) / inv_h2), // + src2_major + ((x - x_min_incl) / inv_h2), // + src_len2, // + 0u, false, false); + + const uint8_t* up3 = (*upfunc3)( // + scratch_buffer_2k_ptr + (3u * 480u), // + src3_major + ((x - x_min_incl) / inv_h3), // + src3_major + ((x - x_min_incl) / inv_h3), // + src_len3, // + 0u, false, false); + + (*conv4func)(dst, x, end, y, up0, up1, up2, up3); + x = end; + } + } +} + // -------- // wuffs_private_impl__swizzle_flattened_length is like @@ -28940,8 +29131,10 @@ wuffs_base__pixel_swizzler__swizzle_ycck( const wuffs_base__pixel_swizzler* p, wuffs_base__pixel_buffer* dst, wuffs_base__slice_u8 dst_palette, - uint32_t width, - uint32_t height, + uint32_t x_min_incl, + uint32_t x_max_excl, + uint32_t y_min_incl, + uint32_t y_max_excl, wuffs_base__slice_u8 src0, wuffs_base__slice_u8 src1, wuffs_base__slice_u8 src2, @@ -28971,13 +29164,18 @@ wuffs_base__pixel_swizzler__swizzle_ycck( wuffs_base__slice_u8 scratch_buffer_2k) { if (!p) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } else if (!dst || (width > 0xFFFFu) || (height > 0xFFFFu) || // - (4u <= ((unsigned int)h0 - 1u)) || // - (4u <= ((unsigned int)h1 - 1u)) || // - (4u <= ((unsigned int)h2 - 1u)) || // - (4u <= ((unsigned int)v0 - 1u)) || // - (4u <= ((unsigned int)v1 - 1u)) || // - (4u <= ((unsigned int)v2 - 1u)) || // + } else if (!dst || // + (x_min_incl > x_max_excl) || // + (x_max_excl > 0xFFFFu) || // + (y_min_incl > y_max_excl) || // + (y_max_excl > 0xFFFFu) || // + (4u <= ((unsigned int)h0 - 1u)) || // + (4u <= ((unsigned int)h1 - 1u)) || // + (4u <= ((unsigned int)h2 - 1u)) || // + (4u <= ((unsigned int)v0 - 1u)) || // + (4u <= ((unsigned int)v1 - 1u)) || // + (4u <= ((unsigned int)v2 - 1u)) || // + (triangle_filter_for_2to1 && ((x_min_incl | y_min_incl) > 0u)) || (scratch_buffer_2k.len < 2048u)) { return wuffs_base__make_status(wuffs_base__error__bad_argument); } @@ -29004,21 +29202,69 @@ wuffs_base__pixel_swizzler__swizzle_ycck( uint32_t inv_v2 = max_incl_v / v2; uint32_t inv_v3 = v3 ? (max_incl_v / v3) : 0u; - uint32_t half_width_for_2to1 = (width + 1u) / 2u; - uint32_t half_height_for_2to1 = (height + 1u) / 2u; - - width = wuffs_private_impl__u32__min_of_5( // - width, // - width0 * inv_h0, // - width1 * inv_h1, // - width2 * inv_h2, // - wuffs_base__pixel_config__width(&dst->pixcfg)); - height = wuffs_private_impl__u32__min_of_5( // - height, // - height0 * inv_v0, // - height1 * inv_v1, // - height2 * inv_v2, // - wuffs_base__pixel_config__height(&dst->pixcfg)); + if (x_min_incl != 0) { + if ((x_min_incl % inv_h0) || (x_min_incl % inv_h1) || + (x_min_incl % inv_h2) || (inv_h3 && (x_min_incl % inv_h3))) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + } + if (y_min_incl != 0) { + if ((y_min_incl % inv_v0) || (y_min_incl % inv_v1) || + (y_min_incl % inv_v2) || (inv_v3 && (y_min_incl % inv_v3))) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + } + + uint32_t half_width_for_2to1 = ((x_max_excl - x_min_incl) + 1u) / 2u; + if (inv_h0 == 2) { + half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width0); + } + if (inv_h1 == 2) { + half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width1); + } + if (inv_h2 == 2) { + half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width2); + } + if (inv_h3 == 2) { + half_width_for_2to1 = wuffs_base__u32__min(half_width_for_2to1, width3); + } + + uint32_t half_height_for_2to1 = ((y_max_excl - y_min_incl) + 1u) / 2u; + if (inv_v0 == 2) { + half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height0); + } + if (inv_v1 == 2) { + half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height1); + } + if (inv_v2 == 2) { + half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height2); + } + if (inv_v3 == 2) { + half_height_for_2to1 = wuffs_base__u32__min(half_height_for_2to1, height3); + } + + x_max_excl = wuffs_base__u32__min( // + wuffs_base__pixel_config__width(&dst->pixcfg), // + x_min_incl + wuffs_private_impl__u32__min_of_5( // + x_max_excl - x_min_incl, // + width0 * inv_h0, // + width1 * inv_h1, // + width2 * inv_h2, // + inv_h3 ? (width3 * inv_h3) : 0xFFFFFFFF)); + y_max_excl = wuffs_base__u32__min( // + wuffs_base__pixel_config__height(&dst->pixcfg), // + y_min_incl + wuffs_private_impl__u32__min_of_5( // + y_max_excl - y_min_incl, // + height0 * inv_v0, // + height1 * inv_v1, // + height2 * inv_v2, // + inv_v3 ? (height3 * inv_v3) : 0xFFFFFFFF)); + + if ((x_min_incl >= x_max_excl) || (y_min_incl >= y_max_excl)) { + return wuffs_base__make_status(NULL); + } + uint32_t width = x_max_excl - x_min_incl; + uint32_t height = y_max_excl - y_min_incl; if (((h0 * inv_h0) != max_incl_h) || // ((h1 * inv_h1) != max_incl_h) || // @@ -29119,10 +29365,6 @@ wuffs_base__pixel_swizzler__swizzle_ycck( // ---- - if ((width <= 0u) || (height <= 0u)) { - return wuffs_base__make_status(NULL); - } - wuffs_private_impl__swizzle_ycc__convert_3_func conv3func = NULL; if (is_rgb_or_cmyk) { @@ -29157,28 +29399,58 @@ wuffs_base__pixel_swizzler__swizzle_ycck( } } - void (*func)(wuffs_base__pixel_buffer * dst, // - uint32_t width, // - uint32_t height, // - const uint8_t* src_ptr0, // - const uint8_t* src_ptr1, // - const uint8_t* src_ptr2, // - uint32_t stride0, // - uint32_t stride1, // - uint32_t stride2, // - uint32_t inv_h0, // - uint32_t inv_h1, // - uint32_t inv_h2, // - uint32_t inv_v0, // - uint32_t inv_v1, // - uint32_t inv_v2, // - uint32_t half_width_for_2to1, // - uint32_t half_height_for_2to1, // - uint8_t* scratch_buffer_2k_ptr, // - wuffs_private_impl__swizzle_ycc__upsample_func(*upfuncs)[4][4], - wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) = + void (*func3)(wuffs_base__pixel_buffer * dst, // + uint32_t x_min_incl, // + uint32_t x_max_excl, // + uint32_t y_min_incl, // + uint32_t y_max_excl, // + const uint8_t* src_ptr0, // + const uint8_t* src_ptr1, // + const uint8_t* src_ptr2, // + uint32_t stride0, // + uint32_t stride1, // + uint32_t stride2, // + uint32_t inv_h0, // + uint32_t inv_h1, // + uint32_t inv_h2, // + uint32_t inv_v0, // + uint32_t inv_v1, // + uint32_t inv_v2, // + uint32_t half_width_for_2to1, // + uint32_t half_height_for_2to1, // + uint8_t* scratch_buffer_2k_ptr, // + wuffs_private_impl__swizzle_ycc__upsample_func(*upfuncs)[4][4], + wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) = &wuffs_private_impl__swizzle_ycc__general__box_filter; + void (*func4)(wuffs_base__pixel_buffer * dst, // + uint32_t x_min_incl, // + uint32_t x_max_excl, // + uint32_t y_min_incl, // + uint32_t y_max_excl, // + const uint8_t* src_ptr0, // + const uint8_t* src_ptr1, // + const uint8_t* src_ptr2, // + const uint8_t* src_ptr3, // + uint32_t stride0, // + uint32_t stride1, // + uint32_t stride2, // + uint32_t stride3, // + uint32_t inv_h0, // + uint32_t inv_h1, // + uint32_t inv_h2, // + uint32_t inv_h3, // + uint32_t inv_v0, // + uint32_t inv_v1, // + uint32_t inv_v2, // + uint32_t inv_v3, // + uint32_t half_width_for_2to1, // + uint32_t half_height_for_2to1, // + uint8_t* scratch_buffer_2k_ptr, // + wuffs_private_impl__swizzle_ycc__upsample_func(*upfuncs)[4][4], + wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) = + &wuffs_private_impl__swizzle_ycck__general__box_filter; + wuffs_private_impl__swizzle_ycc__upsample_func upfuncs[4][4]; memcpy(&upfuncs, &wuffs_private_impl__swizzle_ycc__upsample_funcs, sizeof upfuncs); @@ -29186,8 +29458,10 @@ wuffs_base__pixel_swizzler__swizzle_ycck( if (triangle_filter_for_2to1 && (wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h0, inv_v0) || wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h1, inv_v1) || - wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h2, inv_v2))) { - func = &wuffs_private_impl__swizzle_ycc__general__triangle_filter; + wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h2, inv_v2) || + wuffs_private_impl__swizzle_has_triangle_upsampler(inv_h3, inv_v3))) { + func3 = &wuffs_private_impl__swizzle_ycc__general__triangle_filter; + func4 = &wuffs_private_impl__swizzle_ycck__general__triangle_filter; upfuncs[0][1] = wuffs_private_impl__swizzle_ycc__upsample_inv_h1v2_triangle; upfuncs[1][0] = wuffs_private_impl__swizzle_ycc__upsample_inv_h2v1_triangle; @@ -29219,23 +29493,23 @@ wuffs_base__pixel_swizzler__swizzle_ycck( wuffs_private_impl__swizzle_ycc__convert_4_func conv4func = is_rgb_or_cmyk ? &wuffs_private_impl__swizzle_cmyk__convert_4_general : &wuffs_private_impl__swizzle_ycck__convert_4_general; - wuffs_private_impl__swizzle_ycck__general__triangle_filter( // - dst, width, height, // - src0.ptr, src1.ptr, src2.ptr, src3.ptr, // - stride0, stride1, stride2, stride3, // - inv_h0, inv_h1, inv_h2, inv_h3, // - inv_v0, inv_v1, inv_v2, inv_v3, // - half_width_for_2to1, half_height_for_2to1, // + (*func4)( // + dst, x_min_incl, x_max_excl, y_min_incl, y_max_excl, // + src0.ptr, src1.ptr, src2.ptr, src3.ptr, // + stride0, stride1, stride2, stride3, // + inv_h0, inv_h1, inv_h2, inv_h3, // + inv_v0, inv_v1, inv_v2, inv_v3, // + half_width_for_2to1, half_height_for_2to1, // scratch_buffer_2k.ptr, &upfuncs, conv4func); } else { - (*func)( // - dst, width, height, // - src0.ptr, src1.ptr, src2.ptr, // - stride0, stride1, stride2, // - inv_h0, inv_h1, inv_h2, // - inv_v0, inv_v1, inv_v2, // - half_width_for_2to1, half_height_for_2to1, // + (*func3)( // + dst, x_min_incl, x_max_excl, y_min_incl, y_max_excl, // + src0.ptr, src1.ptr, src2.ptr, // + stride0, stride1, stride2, // + inv_h0, inv_h1, inv_h2, // + inv_v0, inv_v1, inv_v2, // + half_width_for_2to1, half_height_for_2to1, // scratch_buffer_2k.ptr, &upfuncs, conv3func); } @@ -30954,6 +31228,7 @@ wuffs_bmp__decoder__do_decode_image_config( uint32_t v_width = 0; uint32_t v_height = 0; uint32_t v_planes = 0; + uint32_t v_n = 0; uint32_t v_dst_pixfmt = 0; uint32_t v_byte_width = 0; @@ -31711,7 +31986,8 @@ wuffs_bmp__decoder__do_decode_image_config( } } } else if (self->private_impl.f_bitmap_info_len >= 40u) { - self->private_data.s_do_decode_image_config.scratch = (self->private_impl.f_bitmap_info_len - 40u); + v_n = (self->private_impl.f_bitmap_info_len - 40u); + self->private_data.s_do_decode_image_config.scratch = v_n; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45); if (self->private_data.s_do_decode_image_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { self->private_data.s_do_decode_image_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); @@ -43656,6 +43932,7 @@ const char wuffs_jpeg__error__bad_sof_marker[] = "#jpeg: bad SOF marker"; const char wuffs_jpeg__error__bad_sos_marker[] = "#jpeg: bad SOS marker"; const char wuffs_jpeg__error__bad_header[] = "#jpeg: bad header"; const char wuffs_jpeg__error__bad_marker[] = "#jpeg: bad marker"; +const char wuffs_jpeg__error__bad_scan_count[] = "#jpeg: bad scan count"; const char wuffs_jpeg__error__missing_huffman_table[] = "#jpeg: missing Huffman table"; const char wuffs_jpeg__error__missing_quantization_table[] = "#jpeg: missing Quantization table"; const char wuffs_jpeg__error__truncated_input[] = "#jpeg: truncated input"; @@ -44000,6 +44277,7 @@ WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status wuffs_jpeg__decoder__decode_sos( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf); @@ -44082,14 +44360,23 @@ static wuffs_base__status wuffs_jpeg__decoder__swizzle_gray( wuffs_jpeg__decoder* self, wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf); + wuffs_base__slice_u8 a_workbuf, + uint32_t a_x0, + uint32_t a_x1, + uint32_t a_y0, + uint32_t a_y1, + uint64_t a_stride); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status wuffs_jpeg__decoder__swizzle_colorful( wuffs_jpeg__decoder* self, wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf); + wuffs_base__slice_u8 a_workbuf, + uint32_t a_x0, + uint32_t a_x1, + uint32_t a_y0, + uint32_t a_y1); WUFFS_BASE__GENERATED_C_CODE static bool @@ -44110,6 +44397,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my); @@ -44118,6 +44406,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu__choosy_default( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my); @@ -44126,6 +44415,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my); @@ -44134,6 +44424,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my); @@ -44142,6 +44433,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my); @@ -44150,6 +44442,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my); @@ -45793,6 +46086,11 @@ wuffs_jpeg__decoder__get_quirk( return 0; } + if (a_key == 2u) { + if (self->private_impl.f_use_lower_quality) { + return 18446744073709551615u; + } + } return 0u; } @@ -45814,6 +46112,10 @@ wuffs_jpeg__decoder__set_quirk( : wuffs_base__error__initialize_not_called); } + if (a_key == 2u) { + self->private_impl.f_use_lower_quality = (a_value >= 9223372036854775808u); + return wuffs_base__make_status(NULL); + } return wuffs_base__make_status(wuffs_base__error__unsupported_option); } @@ -47100,14 +47402,27 @@ wuffs_jpeg__decoder__decode_frame( if ((v_ddf_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { v_ddf_status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input); } - if (wuffs_base__status__is_error(&v_ddf_status) || (v_scan_count < self->private_impl.f_scan_count)) { + if ( ! self->private_impl.f_swizzle_immediately && (wuffs_base__status__is_error(&v_ddf_status) || (v_scan_count < self->private_impl.f_scan_count))) { if (self->private_impl.f_sof_marker >= 194u) { wuffs_jpeg__decoder__apply_progressive_idct(self, a_workbuf); } if (self->private_impl.f_num_components == 1u) { - v_swizzle_status = wuffs_jpeg__decoder__swizzle_gray(self, a_dst, a_workbuf); + v_swizzle_status = wuffs_jpeg__decoder__swizzle_gray(self, + a_dst, + a_workbuf, + 0u, + 4294967295u, + 0u, + 4294967295u, + ((uint64_t)(self->private_impl.f_components_workbuf_widths[0u]))); } else { - v_swizzle_status = wuffs_jpeg__decoder__swizzle_colorful(self, a_dst, a_workbuf); + v_swizzle_status = wuffs_jpeg__decoder__swizzle_colorful(self, + a_dst, + a_workbuf, + 0u, + 4294967295u, + 0u, + 4294967295u); } if (wuffs_base__status__is_error(&v_ddf_status)) { status = v_ddf_status; @@ -47212,9 +47527,14 @@ wuffs_jpeg__decoder__do_decode_frame( } goto ok; } + self->private_impl.f_swizzle_immediately = false; if (self->private_impl.f_components_workbuf_offsets[8u] > ((uint64_t)(a_workbuf.len))) { - status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); - goto exit; + if (self->private_impl.f_sof_marker >= 194u) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } + self->private_impl.f_swizzle_immediately = self->private_impl.f_use_lower_quality; + self->private_impl.f_swizzle_immediately_status = wuffs_base__make_status(NULL); } else if (self->private_impl.f_components_workbuf_offsets[4u] < self->private_impl.f_components_workbuf_offsets[8u]) { wuffs_private_impl__bulk_memset(a_workbuf.ptr + self->private_impl.f_components_workbuf_offsets[4u], (self->private_impl.f_components_workbuf_offsets[8u] - self->private_impl.f_components_workbuf_offsets[4u]), 0u); } @@ -47327,7 +47647,7 @@ wuffs_jpeg__decoder__do_decode_frame( a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - status = wuffs_jpeg__decoder__decode_sos(self, a_src, a_workbuf); + status = wuffs_jpeg__decoder__decode_sos(self, a_dst, a_src, a_workbuf); if (a_src) { iop_a_src = a_src->data.ptr + a_src->meta.ri; } @@ -47674,13 +47994,6 @@ wuffs_jpeg__decoder__calculate_huff_tables( #pragma GCC diagnostic ignored "-Wconversion" #endif v_k += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_j += 1u; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -47697,6 +48010,7 @@ WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status wuffs_jpeg__decoder__decode_sos( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); @@ -47714,9 +48028,12 @@ wuffs_jpeg__decoder__decode_sos( switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_scan_count >= 64u) { + if (self->private_impl.f_scan_count >= 32u) { status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_scan_count); goto exit; + } else if ((self->private_impl.f_scan_count > 0u) && ! self->private_impl.f_expect_multiple_scans) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_scan_count); + goto exit; } WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); status = wuffs_jpeg__decoder__prepare_scan(self, a_src); @@ -47746,12 +48063,26 @@ wuffs_jpeg__decoder__decode_sos( wuffs_jpeg__decoder__load_mcu_blocks(self, v_mx, v_my, a_workbuf); } while (true) { - v_decode_mcu_result = wuffs_jpeg__decoder__decode_mcu(self, a_workbuf, v_mx, v_my); + v_decode_mcu_result = wuffs_jpeg__decoder__decode_mcu(self, + a_dst, + a_workbuf, + v_mx, + v_my); if (v_decode_mcu_result == 0u) { break; - } else if (v_decode_mcu_result != 1u) { + } else if (v_decode_mcu_result == 1u) { + } else if (v_decode_mcu_result == 2u) { status = wuffs_base__make_status(wuffs_jpeg__error__internal_error_inconsistent_decoder_state); goto exit; + } else { + status = self->private_impl.f_swizzle_immediately_status; + if (wuffs_base__status__is_error(&status)) { + goto exit; + } else if (wuffs_base__status__is_suspension(&status)) { + status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension); + goto exit; + } + goto ok; } while (true) { v_bitstream_length = ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri)); @@ -47940,6 +48271,9 @@ wuffs_jpeg__decoder__prepare_scan( } v_i += 1u; } + if (self->private_impl.f_scan_count == 0u) { + self->private_impl.f_expect_multiple_scans = ((self->private_impl.f_sof_marker >= 194u) || (self->private_impl.f_scan_num_components < self->private_impl.f_num_components)); + } if (self->private_impl.f_sof_marker < 194u) { self->private_data.s_prepare_scan.scratch = 3u; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); @@ -48189,6 +48523,7 @@ wuffs_jpeg__decoder__calculate_multiple_component_scan_fields( uint32_t v_b = 0; uint32_t v_bx_offset = 0; uint32_t v_by_offset = 0; + uint32_t v_sibo = 0; uint8_t v_ssel = 0; uint8_t v_csel = 0; @@ -48201,6 +48536,7 @@ wuffs_jpeg__decoder__calculate_multiple_component_scan_fields( v_h = ((uint32_t)(self->private_impl.f_components_h[self->private_impl.f_scan_comps_cselector[v_i]])); v_v = ((uint32_t)(self->private_impl.f_components_v[self->private_impl.f_scan_comps_cselector[v_i]])); v_hv = (((uint32_t)(self->private_impl.f_components_h[self->private_impl.f_scan_comps_cselector[v_i]])) * ((uint32_t)(self->private_impl.f_components_v[self->private_impl.f_scan_comps_cselector[v_i]]))); + self->private_impl.f_swizzle_immediately_c_offsets[v_i] = ((uint32_t)(64u * v_total_hv)); v_total_hv += v_hv; while (v_hv > 0u) { self->private_impl.f_scan_comps_bx_offset[(v_b & 15u)] = ((uint8_t)((v_bx_offset & 3u))); @@ -48223,6 +48559,7 @@ wuffs_jpeg__decoder__calculate_multiple_component_scan_fields( return true; } self->private_impl.f_mcu_num_blocks = v_total_hv; + self->private_impl.f_swizzle_immediately_c_offsets[self->private_impl.f_scan_num_components] = ((uint32_t)(64u * v_total_hv)); v_b = 0u; while (v_b < self->private_impl.f_mcu_num_blocks) { v_ssel = self->private_impl.f_mcu_blocks_sselector[v_b]; @@ -48232,6 +48569,8 @@ wuffs_jpeg__decoder__calculate_multiple_component_scan_fields( self->private_impl.f_mcu_blocks_my_mul[v_b] = (8u * ((uint32_t)(self->private_impl.f_components_v[v_csel])) * self->private_impl.f_components_workbuf_widths[v_csel]); self->private_impl.f_mcu_blocks_dc_hselector[v_b] = ((uint8_t)(0u | self->private_impl.f_scan_comps_td[v_ssel])); self->private_impl.f_mcu_blocks_ac_hselector[v_b] = ((uint8_t)(4u | self->private_impl.f_scan_comps_ta[v_ssel])); + v_sibo = ((uint32_t)(self->private_impl.f_swizzle_immediately_c_offsets[v_csel] + ((8u * ((uint32_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) + (64u * ((uint32_t)(self->private_impl.f_scan_comps_by_offset[v_b])) * ((uint32_t)(self->private_impl.f_components_h[v_csel])))))); + self->private_impl.f_swizzle_immediately_b_offsets[v_b] = wuffs_base__u32__min(v_sibo, 576u); v_b += 1u; } self->private_impl.f_scan_width_in_mcus = self->private_impl.f_width_in_mcus; @@ -48567,15 +48906,21 @@ static wuffs_base__status wuffs_jpeg__decoder__swizzle_gray( wuffs_jpeg__decoder* self, wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf) { + wuffs_base__slice_u8 a_workbuf, + uint32_t a_x0, + uint32_t a_x1, + uint32_t a_y0, + uint32_t a_y1, + uint64_t a_stride) { wuffs_base__pixel_format v_dst_pixfmt = {0}; uint32_t v_dst_bits_per_pixel = 0; uint32_t v_dst_bytes_per_pixel = 0; - uint64_t v_dst_length = 0; + uint64_t v_x0 = 0; + uint64_t v_x1 = 0; wuffs_base__table_u8 v_tab = {0}; wuffs_base__slice_u8 v_dst = {0}; uint32_t v_y = 0; - uint64_t v_stride = 0; + uint32_t v_y1 = 0; v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst); v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt); @@ -48583,18 +48928,24 @@ wuffs_jpeg__decoder__swizzle_gray( return wuffs_base__make_status(wuffs_base__error__unsupported_option); } v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); - v_dst_length = ((uint64_t)((v_dst_bytes_per_pixel * self->private_impl.f_width))); + v_x0 = ((uint64_t)((v_dst_bytes_per_pixel * wuffs_base__u32__min(a_x0, self->private_impl.f_width)))); + v_x1 = ((uint64_t)((v_dst_bytes_per_pixel * wuffs_base__u32__min(a_x1, self->private_impl.f_width)))); v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - v_y = 0u; - while (v_y < self->private_impl.f_height) { + v_y = a_y0; + v_y1 = wuffs_base__u32__min(a_y1, self->private_impl.f_height); + while (v_y < v_y1) { v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y); - if (v_dst_length < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_length); + if (v_x1 < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_x1); + } + if (v_x0 < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_x0); + } else { + v_dst = wuffs_base__utility__empty_slice_u8(); } wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), a_workbuf); - v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[0u])); - if (v_stride <= ((uint64_t)(a_workbuf.len))) { - a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, v_stride); + if (a_stride <= ((uint64_t)(a_workbuf.len))) { + a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, a_stride); } else { a_workbuf = wuffs_base__utility__empty_slice_u8(); } @@ -48610,54 +48961,109 @@ static wuffs_base__status wuffs_jpeg__decoder__swizzle_colorful( wuffs_jpeg__decoder* self, wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf) { + wuffs_base__slice_u8 a_workbuf, + uint32_t a_x0, + uint32_t a_x1, + uint32_t a_y0, + uint32_t a_y1) { + uint64_t v_i = 0; + uint64_t v_j = 0; wuffs_base__slice_u8 v_src0 = {0}; wuffs_base__slice_u8 v_src1 = {0}; wuffs_base__slice_u8 v_src2 = {0}; wuffs_base__slice_u8 v_src3 = {0}; + uint32_t v_width0 = 0; + uint32_t v_width1 = 0; + uint32_t v_width2 = 0; + uint32_t v_width3 = 0; + uint32_t v_height0 = 0; + uint32_t v_height1 = 0; + uint32_t v_height2 = 0; + uint32_t v_height3 = 0; wuffs_base__status v_status = wuffs_base__make_status(NULL); - if ((self->private_impl.f_components_workbuf_offsets[0u] <= self->private_impl.f_components_workbuf_offsets[1u]) && (self->private_impl.f_components_workbuf_offsets[1u] <= ((uint64_t)(a_workbuf.len)))) { - v_src0 = wuffs_base__slice_u8__subslice_ij(a_workbuf, - self->private_impl.f_components_workbuf_offsets[0u], - self->private_impl.f_components_workbuf_offsets[1u]); - } - if ((self->private_impl.f_components_workbuf_offsets[1u] <= self->private_impl.f_components_workbuf_offsets[2u]) && (self->private_impl.f_components_workbuf_offsets[2u] <= ((uint64_t)(a_workbuf.len)))) { - v_src1 = wuffs_base__slice_u8__subslice_ij(a_workbuf, - self->private_impl.f_components_workbuf_offsets[1u], - self->private_impl.f_components_workbuf_offsets[2u]); - } - if ((self->private_impl.f_components_workbuf_offsets[2u] <= self->private_impl.f_components_workbuf_offsets[3u]) && (self->private_impl.f_components_workbuf_offsets[3u] <= ((uint64_t)(a_workbuf.len)))) { - v_src2 = wuffs_base__slice_u8__subslice_ij(a_workbuf, - self->private_impl.f_components_workbuf_offsets[2u], - self->private_impl.f_components_workbuf_offsets[3u]); - } - if ((self->private_impl.f_components_workbuf_offsets[3u] <= self->private_impl.f_components_workbuf_offsets[4u]) && (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len)))) { - v_src3 = wuffs_base__slice_u8__subslice_ij(a_workbuf, - self->private_impl.f_components_workbuf_offsets[3u], - self->private_impl.f_components_workbuf_offsets[4u]); + if (self->private_impl.f_swizzle_immediately) { + v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[0u])); + v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[1u])); + if ((v_i <= v_j) && (v_j <= 640u)) { + v_src0 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j); + v_width0 = (8u * ((uint32_t)(self->private_impl.f_components_h[0u]))); + v_height0 = (8u * ((uint32_t)(self->private_impl.f_components_v[0u]))); + } + v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[1u])); + v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[2u])); + if ((v_i <= v_j) && (v_j <= 640u)) { + v_src1 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j); + v_width1 = (8u * ((uint32_t)(self->private_impl.f_components_h[1u]))); + v_height1 = (8u * ((uint32_t)(self->private_impl.f_components_v[1u]))); + } + v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[2u])); + v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[3u])); + if ((v_i <= v_j) && (v_j <= 640u)) { + v_src2 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j); + v_width2 = (8u * ((uint32_t)(self->private_impl.f_components_h[2u]))); + v_height2 = (8u * ((uint32_t)(self->private_impl.f_components_v[2u]))); + } + v_i = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[3u])); + v_j = ((uint64_t)(self->private_impl.f_swizzle_immediately_c_offsets[4u])); + if ((v_i <= v_j) && (v_j <= 640u)) { + v_src3 = wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, v_i, v_j); + v_width3 = (8u * ((uint32_t)(self->private_impl.f_components_h[3u]))); + v_height3 = (8u * ((uint32_t)(self->private_impl.f_components_v[3u]))); + } + } else { + if ((self->private_impl.f_components_workbuf_offsets[0u] <= self->private_impl.f_components_workbuf_offsets[1u]) && (self->private_impl.f_components_workbuf_offsets[1u] <= ((uint64_t)(a_workbuf.len)))) { + v_src0 = wuffs_base__slice_u8__subslice_ij(a_workbuf, + self->private_impl.f_components_workbuf_offsets[0u], + self->private_impl.f_components_workbuf_offsets[1u]); + v_width0 = self->private_impl.f_components_workbuf_widths[0u]; + v_height0 = self->private_impl.f_components_workbuf_heights[0u]; + } + if ((self->private_impl.f_components_workbuf_offsets[1u] <= self->private_impl.f_components_workbuf_offsets[2u]) && (self->private_impl.f_components_workbuf_offsets[2u] <= ((uint64_t)(a_workbuf.len)))) { + v_src1 = wuffs_base__slice_u8__subslice_ij(a_workbuf, + self->private_impl.f_components_workbuf_offsets[1u], + self->private_impl.f_components_workbuf_offsets[2u]); + v_width1 = self->private_impl.f_components_workbuf_widths[1u]; + v_height1 = self->private_impl.f_components_workbuf_heights[1u]; + } + if ((self->private_impl.f_components_workbuf_offsets[2u] <= self->private_impl.f_components_workbuf_offsets[3u]) && (self->private_impl.f_components_workbuf_offsets[3u] <= ((uint64_t)(a_workbuf.len)))) { + v_src2 = wuffs_base__slice_u8__subslice_ij(a_workbuf, + self->private_impl.f_components_workbuf_offsets[2u], + self->private_impl.f_components_workbuf_offsets[3u]); + v_width2 = self->private_impl.f_components_workbuf_widths[2u]; + v_height2 = self->private_impl.f_components_workbuf_heights[2u]; + } + if ((self->private_impl.f_components_workbuf_offsets[3u] <= self->private_impl.f_components_workbuf_offsets[4u]) && (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len)))) { + v_src3 = wuffs_base__slice_u8__subslice_ij(a_workbuf, + self->private_impl.f_components_workbuf_offsets[3u], + self->private_impl.f_components_workbuf_offsets[4u]); + v_width3 = self->private_impl.f_components_workbuf_widths[3u]; + v_height3 = self->private_impl.f_components_workbuf_heights[3u]; + } } v_status = wuffs_base__pixel_swizzler__swizzle_ycck(&self->private_impl.f_swizzler, a_dst, wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), - self->private_impl.f_width, - self->private_impl.f_height, + (a_x0 & 65535u), + wuffs_base__u32__min(a_x1, self->private_impl.f_width), + (a_y0 & 65535u), + wuffs_base__u32__min(a_y1, self->private_impl.f_height), v_src0, v_src1, v_src2, v_src3, - self->private_impl.f_components_workbuf_widths[0u], - self->private_impl.f_components_workbuf_widths[1u], - self->private_impl.f_components_workbuf_widths[2u], - self->private_impl.f_components_workbuf_widths[3u], - self->private_impl.f_components_workbuf_heights[0u], - self->private_impl.f_components_workbuf_heights[1u], - self->private_impl.f_components_workbuf_heights[2u], - self->private_impl.f_components_workbuf_heights[3u], - self->private_impl.f_components_workbuf_widths[0u], - self->private_impl.f_components_workbuf_widths[1u], - self->private_impl.f_components_workbuf_widths[2u], - self->private_impl.f_components_workbuf_widths[3u], + v_width0, + v_width1, + v_width2, + v_width3, + v_height0, + v_height1, + v_height2, + v_height3, + v_width0, + v_width1, + v_width2, + v_width3, self->private_impl.f_components_h[0u], self->private_impl.f_components_h[1u], self->private_impl.f_components_h[2u], @@ -48667,7 +49073,7 @@ wuffs_jpeg__decoder__swizzle_colorful( self->private_impl.f_components_v[2u], self->private_impl.f_components_v[3u], self->private_impl.f_is_rgb_or_cmyk, - true, + ! self->private_impl.f_use_lower_quality, wuffs_base__make_slice_u8(self->private_data.f_swizzle_ycck_scratch_buffer_2k, 2048)); return wuffs_private_impl__status__ensure_not_a_suspension(v_status); } @@ -48779,6 +49185,7 @@ wuffs_jpeg__decoder__restart_frame( } self->private_impl.f_call_sequence = 40u; self->private_impl.f_bitstream_is_closed = false; + self->private_impl.f_expect_multiple_scans = false; self->private_impl.f_frame_config_io_position = a_io_position; self->private_impl.f_scan_count = 0u; self->private_impl.f_restart_interval = self->private_impl.f_saved_restart_interval; @@ -48877,6 +49284,9 @@ wuffs_jpeg__decoder__workbuf_len( return wuffs_base__utility__empty_range_ii_u64(); } + if (self->private_impl.f_use_lower_quality && (self->private_impl.f_sof_marker < 194u)) { + return wuffs_base__utility__make_range_ii_u64(0u, self->private_impl.f_components_workbuf_offsets[8u]); + } return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_components_workbuf_offsets[8u], self->private_impl.f_components_workbuf_offsets[8u]); } @@ -49513,16 +49923,18 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my) { - return (*self->private_impl.choosy_decode_mcu)(self, a_workbuf, a_mx, a_my); + return (*self->private_impl.choosy_decode_mcu)(self, a_dst, a_workbuf, a_mx, a_my); } WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu__choosy_default( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my) { @@ -49722,11 +50134,47 @@ wuffs_jpeg__decoder__decode_mcu__choosy_default( if (self->private_impl.f_test_only_interrupt_decode_mcu) { goto label__goto_done__break; } - v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_mcb]]; - v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel])); - v_offset = (self->private_impl.f_mcu_blocks_offset[v_mcb] + (((uint64_t)(self->private_impl.f_mcu_blocks_mx_mul[v_mcb])) * ((uint64_t)(a_mx))) + (((uint64_t)(self->private_impl.f_mcu_blocks_my_mul[v_mcb])) * ((uint64_t)(a_my)))); - if (v_offset <= ((uint64_t)(a_workbuf.len))) { - wuffs_jpeg__decoder__decode_idct(self, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset), v_stride, ((uint32_t)(self->private_impl.f_components_tq[v_csel]))); + if ( ! self->private_impl.f_swizzle_immediately) { + v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_mcb]]; + v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel])); + v_offset = (self->private_impl.f_mcu_blocks_offset[v_mcb] + (((uint64_t)(self->private_impl.f_mcu_blocks_mx_mul[v_mcb])) * ((uint64_t)(a_mx))) + (((uint64_t)(self->private_impl.f_mcu_blocks_my_mul[v_mcb])) * ((uint64_t)(a_my)))); + if (v_offset <= ((uint64_t)(a_workbuf.len))) { + wuffs_jpeg__decoder__decode_idct(self, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset), v_stride, ((uint32_t)(self->private_impl.f_components_tq[v_csel]))); + } + } else if (self->private_impl.f_num_components == 1u) { + wuffs_jpeg__decoder__decode_idct(self, wuffs_base__make_slice_u8(self->private_data.f_swizzle_immediately_buffer, 64), 8u, ((uint32_t)(self->private_impl.f_components_tq[v_csel]))); + self->private_impl.f_swizzle_immediately_status = wuffs_jpeg__decoder__swizzle_gray(self, + a_dst, + wuffs_base__make_slice_u8(self->private_data.f_swizzle_immediately_buffer, 64), + ((a_mx + 0u) * 8u), + ((a_mx + 1u) * 8u), + ((a_my + 0u) * 8u), + ((a_my + 1u) * 8u), + 8u); + if ( ! wuffs_base__status__is_ok(&self->private_impl.f_swizzle_immediately_status)) { + v_ret = 3u; + goto label__goto_done__break; + } + break; + } else { + v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_mcb]]; + v_stride = (8u * ((uint64_t)(self->private_impl.f_components_h[v_csel]))); + wuffs_jpeg__decoder__decode_idct(self, wuffs_base__make_slice_u8_ij(self->private_data.f_swizzle_immediately_buffer, self->private_impl.f_swizzle_immediately_b_offsets[v_mcb], 640), v_stride, ((uint32_t)(self->private_impl.f_components_tq[v_csel]))); + if (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) { + continue; + } + self->private_impl.f_swizzle_immediately_status = wuffs_jpeg__decoder__swizzle_colorful(self, + a_dst, + wuffs_base__utility__empty_slice_u8(), + ((a_mx + 0u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_h))), + ((a_mx + 1u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_h))), + ((a_my + 0u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_v))), + ((a_my + 1u) * 8u * ((uint32_t)(self->private_impl.f_max_incl_components_v)))); + if ( ! wuffs_base__status__is_ok(&self->private_impl.f_swizzle_immediately_status)) { + v_ret = 3u; + goto label__goto_done__break; + } + break; } } self->private_impl.f_mcu_current_block = 0u; @@ -49755,6 +50203,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my) { @@ -49922,6 +50371,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my) { @@ -50183,6 +50633,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my) { @@ -50323,6 +50774,7 @@ WUFFS_BASE__GENERATED_C_CODE static uint32_t wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit( wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__slice_u8 a_workbuf, uint32_t a_mx, uint32_t a_my) { @@ -69437,42 +69889,6 @@ WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[5] WUFFS_BASE__POTENTIALLY_UNUSED = { 1612u, 0u, 511u, 1022u, 1533u, }; -static const uint32_t -WUFFS_WEBP__SIGN_EXTEND_I8_I32[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, - 8u, 9u, 10u, 11u, 12u, 13u, 14u, 15u, - 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, - 24u, 25u, 26u, 27u, 28u, 29u, 30u, 31u, - 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, - 40u, 41u, 42u, 43u, 44u, 45u, 46u, 47u, - 48u, 49u, 50u, 51u, 52u, 53u, 54u, 55u, - 56u, 57u, 58u, 59u, 60u, 61u, 62u, 63u, - 64u, 65u, 66u, 67u, 68u, 69u, 70u, 71u, - 72u, 73u, 74u, 75u, 76u, 77u, 78u, 79u, - 80u, 81u, 82u, 83u, 84u, 85u, 86u, 87u, - 88u, 89u, 90u, 91u, 92u, 93u, 94u, 95u, - 96u, 97u, 98u, 99u, 100u, 101u, 102u, 103u, - 104u, 105u, 106u, 107u, 108u, 109u, 110u, 111u, - 112u, 113u, 114u, 115u, 116u, 117u, 118u, 119u, - 120u, 121u, 122u, 123u, 124u, 125u, 126u, 127u, - 4294967168u, 4294967169u, 4294967170u, 4294967171u, 4294967172u, 4294967173u, 4294967174u, 4294967175u, - 4294967176u, 4294967177u, 4294967178u, 4294967179u, 4294967180u, 4294967181u, 4294967182u, 4294967183u, - 4294967184u, 4294967185u, 4294967186u, 4294967187u, 4294967188u, 4294967189u, 4294967190u, 4294967191u, - 4294967192u, 4294967193u, 4294967194u, 4294967195u, 4294967196u, 4294967197u, 4294967198u, 4294967199u, - 4294967200u, 4294967201u, 4294967202u, 4294967203u, 4294967204u, 4294967205u, 4294967206u, 4294967207u, - 4294967208u, 4294967209u, 4294967210u, 4294967211u, 4294967212u, 4294967213u, 4294967214u, 4294967215u, - 4294967216u, 4294967217u, 4294967218u, 4294967219u, 4294967220u, 4294967221u, 4294967222u, 4294967223u, - 4294967224u, 4294967225u, 4294967226u, 4294967227u, 4294967228u, 4294967229u, 4294967230u, 4294967231u, - 4294967232u, 4294967233u, 4294967234u, 4294967235u, 4294967236u, 4294967237u, 4294967238u, 4294967239u, - 4294967240u, 4294967241u, 4294967242u, 4294967243u, 4294967244u, 4294967245u, 4294967246u, 4294967247u, - 4294967248u, 4294967249u, 4294967250u, 4294967251u, 4294967252u, 4294967253u, 4294967254u, 4294967255u, - 4294967256u, 4294967257u, 4294967258u, 4294967259u, 4294967260u, 4294967261u, 4294967262u, 4294967263u, - 4294967264u, 4294967265u, 4294967266u, 4294967267u, 4294967268u, 4294967269u, 4294967270u, 4294967271u, - 4294967272u, 4294967273u, 4294967274u, 4294967275u, 4294967276u, 4294967277u, 4294967278u, 4294967279u, - 4294967280u, 4294967281u, 4294967282u, 4294967283u, 4294967284u, 4294967285u, 4294967286u, 4294967287u, - 4294967288u, 4294967289u, 4294967290u, 4294967291u, 4294967292u, 4294967293u, 4294967294u, 4294967295u, -}; - static const uint8_t WUFFS_WEBP__DISTANCE_MAP[120] WUFFS_BASE__POTENTIALLY_UNUSED = { 24u, 7u, 23u, 25u, 40u, 6u, 39u, 41u, @@ -71023,29 +71439,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += v_curr_row.ptr[0u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += v_curr_row.ptr[1u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += v_curr_row.ptr[2u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += v_curr_row.ptr[3u]; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71077,29 +71472,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[0u] += v_prev_row.ptr[0u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[1u] += v_prev_row.ptr[1u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[2u] += v_prev_row.ptr[2u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[3u] += v_prev_row.ptr[3u]; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71129,29 +71503,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += v_curr_row.ptr[0u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += v_curr_row.ptr[1u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += v_curr_row.ptr[2u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += v_curr_row.ptr[3u]; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71162,29 +71515,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += v_prev_row.ptr[4u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += v_prev_row.ptr[5u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += v_prev_row.ptr[6u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += v_prev_row.ptr[7u]; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71195,29 +71527,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += v_prev_row.ptr[8u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += v_prev_row.ptr[9u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += v_prev_row.ptr[10u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += v_prev_row.ptr[11u]; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71228,29 +71539,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += v_prev_row.ptr[0u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += v_prev_row.ptr[1u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += v_prev_row.ptr[2u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += v_prev_row.ptr[3u]; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71265,29 +71555,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(((v_l0 + ((uint32_t)(v_prev_row.ptr[4u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(((v_l1 + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(((v_l2 + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(((v_l3 + ((uint32_t)(v_prev_row.ptr[7u]))) / 2u))); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71298,29 +71567,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[0u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[1u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[2u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[3u]))) / 2u))); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71331,29 +71579,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[4u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[7u]))) / 2u))); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71364,29 +71591,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[4u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[7u]))) / 2u))); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71397,29 +71603,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[4u])) + ((uint32_t)(v_prev_row.ptr[8u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[5u])) + ((uint32_t)(v_prev_row.ptr[9u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[6u])) + ((uint32_t)(v_prev_row.ptr[10u]))) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[7u])) + ((uint32_t)(v_prev_row.ptr[11u]))) / 2u))); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71438,29 +71623,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(((v_l0 + v_t0) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(((v_l1 + v_t1) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(((v_l2 + v_t2) / 2u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(((v_l3 + v_t3) / 2u))); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71492,29 +71656,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(v_l0)); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(v_l1)); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(v_l2)); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(v_l3)); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71525,29 +71668,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += ((uint8_t)(v_t0)); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += ((uint8_t)(v_t1)); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += ((uint8_t)(v_t2)); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += ((uint8_t)(v_t3)); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71559,29 +71681,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[0u], v_prev_row.ptr[4u], v_prev_row.ptr[0u]); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[1u], v_prev_row.ptr[5u], v_prev_row.ptr[1u]); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[2u], v_prev_row.ptr[6u], v_prev_row.ptr[2u]); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += wuffs_webp__decoder__mode12(self, v_curr_row.ptr[3u], v_prev_row.ptr[7u], v_prev_row.ptr[3u]); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71592,29 +71693,8 @@ wuffs_webp__decoder__apply_transform_predictor( #pragma GCC diagnostic ignored "-Wconversion" #endif v_curr_row.ptr[4u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[0u], v_prev_row.ptr[4u], v_prev_row.ptr[0u]); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[5u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[1u], v_prev_row.ptr[5u], v_prev_row.ptr[1u]); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[6u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[2u], v_prev_row.ptr[6u], v_prev_row.ptr[2u]); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_curr_row.ptr[7u] += wuffs_webp__decoder__mode13(self, v_curr_row.ptr[3u], v_prev_row.ptr[7u], v_prev_row.ptr[3u]); #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71724,9 +71804,9 @@ wuffs_webp__decoder__apply_transform_cross_color( v_x = 0u; while (v_x < self->private_impl.f_width) { if (((v_x & v_mask) == 0u) && (((uint64_t)(v_tile_data.len)) >= 4u)) { - v_g2r = WUFFS_WEBP__SIGN_EXTEND_I8_I32[v_tile_data.ptr[0u]]; - v_g2b = WUFFS_WEBP__SIGN_EXTEND_I8_I32[v_tile_data.ptr[1u]]; - v_r2b = WUFFS_WEBP__SIGN_EXTEND_I8_I32[v_tile_data.ptr[2u]]; + v_g2r = wuffs_base__utility__sign_extend_convert_u8_u32(v_tile_data.ptr[0u]); + v_g2b = wuffs_base__utility__sign_extend_convert_u8_u32(v_tile_data.ptr[1u]); + v_r2b = wuffs_base__utility__sign_extend_convert_u8_u32(v_tile_data.ptr[2u]); v_tile_data = wuffs_base__slice_u8__subslice_i(v_tile_data, 4u); } if (((uint64_t)(a_pix.len)) >= 4u) { @@ -71737,23 +71817,9 @@ wuffs_webp__decoder__apply_transform_cross_color( #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif - v_r += ((uint8_t)((((uint32_t)(WUFFS_WEBP__SIGN_EXTEND_I8_I32[v_g] * v_g2r)) >> 5u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_b += ((uint8_t)((((uint32_t)(WUFFS_WEBP__SIGN_EXTEND_I8_I32[v_g] * v_g2b)) >> 5u))); -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_b += ((uint8_t)((((uint32_t)(WUFFS_WEBP__SIGN_EXTEND_I8_I32[v_r] * v_r2b)) >> 5u))); + v_r += ((uint8_t)((((uint32_t)(wuffs_base__utility__sign_extend_convert_u8_u32(v_g) * v_g2r)) >> 5u))); + v_b += ((uint8_t)((((uint32_t)(wuffs_base__utility__sign_extend_convert_u8_u32(v_g) * v_g2b)) >> 5u))); + v_b += ((uint8_t)((((uint32_t)(wuffs_base__utility__sign_extend_convert_u8_u32(v_r) * v_r2b)) >> 5u))); #if defined(__GNUC__) #pragma GCC diagnostic pop #endif @@ -71790,13 +71856,6 @@ wuffs_webp__decoder__apply_transform_subtract_green( #pragma GCC diagnostic ignored "-Wconversion" #endif v_p.ptr[0u] += v_g; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_p.ptr[2u] += v_g; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -71834,6 +71893,26 @@ wuffs_webp__decoder__apply_transform_color_indexing( v_tile_size_log2 = ((uint32_t)(self->private_impl.f_transform_tile_size_log2[3u])); if (v_tile_size_log2 == 0u) { + { + wuffs_base__slice_u8 i_slice_dst = a_pix; + v_dst.ptr = i_slice_dst.ptr; + v_dst.len = 4; + const uint8_t* i_end0_dst = wuffs_private_impl__ptr_u8_plus_len(v_dst.ptr, (((i_slice_dst.len - (size_t)(v_dst.ptr - i_slice_dst.ptr)) / 4) * 4)); + while (v_dst.ptr < i_end0_dst) { + v_p = (((uint32_t)(v_dst.ptr[1u])) * 4u); + v_p0 = self->private_data.f_palette[(v_p + 0u)]; + v_p1 = self->private_data.f_palette[(v_p + 1u)]; + v_p2 = self->private_data.f_palette[(v_p + 2u)]; + v_p3 = self->private_data.f_palette[(v_p + 3u)]; + v_dst.ptr[0u] = v_p0; + v_dst.ptr[1u] = v_p1; + v_dst.ptr[2u] = v_p2; + v_dst.ptr[3u] = v_p3; + v_dst.ptr += 4; + } + v_dst.len = 0; + } + return wuffs_base__make_empty_struct(); } v_bits_per_pixel = (((uint32_t)(8u)) >> v_tile_size_log2); v_x_mask = ((((uint32_t)(1u)) << v_tile_size_log2) - 1u); @@ -72930,6 +73009,7 @@ wuffs_webp__decoder__decode_transform( wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); + wuffs_base__status v_status = wuffs_base__make_status(NULL); uint8_t v_c8 = 0; uint32_t v_transform_type = 0; uint32_t v_tile_size_log2 = 0; @@ -73028,28 +73108,34 @@ wuffs_webp__decoder__decode_transform( if (status.repr) { goto suspend; } - if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)])) > ((uint64_t)(a_workbuf.len)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - status = wuffs_webp__decoder__decode_pixels(self, - wuffs_base__slice_u8__subslice_ij(a_workbuf, - ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)])), - ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)]))), - a_src, - ((self->private_impl.f_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), - ((self->private_impl.f_height + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), - wuffs_base__utility__empty_slice_u8(), - 0u); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; + while (true) { + if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)])) > ((uint64_t)(a_workbuf.len)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_webp__decoder__decode_pixels(self, + wuffs_base__slice_u8__subslice_ij(a_workbuf, + ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)])), + ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)]))), + a_src, + ((self->private_impl.f_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), + ((self->private_impl.f_height + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), + wuffs_base__utility__empty_slice_u8(), + 0u); + v_status = t_2; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); } } else if (v_transform_type == 2u) { } else { @@ -73060,8 +73146,8 @@ wuffs_webp__decoder__decode_transform( status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_2 = *iop_a_src++; - v_c8 = t_2; + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; } if (self->private_impl.f_n_bits >= 8u) { status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); @@ -73136,29 +73222,8 @@ wuffs_webp__decoder__decode_transform( #pragma GCC diagnostic ignored "-Wconversion" #endif v_p.ptr[4u] += v_p.ptr[0u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_p.ptr[5u] += v_p.ptr[1u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_p.ptr[6u] += v_p.ptr[2u]; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif v_p.ptr[7u] += v_p.ptr[3u]; #if defined(__GNUC__) #pragma GCC diagnostic pop @@ -73167,7 +73232,6 @@ wuffs_webp__decoder__decode_transform( } } - goto ok; ok: self->private_impl.p_decode_transform = 0; goto exit; @@ -73291,6 +73355,7 @@ wuffs_webp__decoder__decode_hg_table( wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); + wuffs_base__status v_status = wuffs_base__make_status(NULL); uint8_t v_c8 = 0; uint32_t v_use_hg_table = 0; uint32_t v_tile_size_log2 = 0; @@ -73395,28 +73460,34 @@ wuffs_webp__decoder__decode_hg_table( if (status.repr) { goto suspend; } - if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])) > ((uint64_t)(a_workbuf.len)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - status = wuffs_webp__decoder__decode_pixels(self, - wuffs_base__slice_u8__subslice_ij(a_workbuf, - ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])), - ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))), - a_src, - ((a_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), - ((self->private_impl.f_height + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), - wuffs_base__utility__empty_slice_u8(), - 0u); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; + while (true) { + if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])) > ((uint64_t)(a_workbuf.len)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_webp__decoder__decode_pixels(self, + wuffs_base__slice_u8__subslice_ij(a_workbuf, + ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])), + ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))), + a_src, + ((a_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), + ((self->private_impl.f_height + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2), + wuffs_base__utility__empty_slice_u8(), + 0u); + v_status = t_2; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); } self->private_impl.f_overall_n_huffman_groups = 1u; if ((((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u]))) || (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[1u])) > ((uint64_t)(a_workbuf.len)))) { @@ -77458,15 +77529,13 @@ DecodeCborCallbacks::Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer) {} -DecodeCborArgQuirks::DecodeCborArgQuirks(wuffs_base__slice_u32 repr0) - : repr(repr0) {} - -DecodeCborArgQuirks::DecodeCborArgQuirks(uint32_t* ptr0, size_t len0) - : repr(wuffs_base__make_slice_u32(ptr0, len0)) {} +DecodeCborArgQuirks::DecodeCborArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0) + : ptr(ptr0), len(len0) {} DecodeCborArgQuirks // DecodeCborArgQuirks::DefaultValue() { - return DecodeCborArgQuirks(wuffs_base__empty_slice_u32()); + return DecodeCborArgQuirks(nullptr, 0); } DecodeCborResult // @@ -77495,8 +77564,8 @@ DecodeCbor(DecodeCborCallbacks& callbacks, ret_error_message = "wuffs_aux::DecodeCbor: out of memory"; goto done; } - for (size_t i = 0; i < quirks.repr.len; i++) { - dec->set_quirk(quirks.repr.ptr[i], 1); + for (size_t i = 0; i < quirks.len; i++) { + dec->set_quirk(quirks.ptr[i].first, quirks.ptr[i].second); } // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB. @@ -77989,15 +78058,13 @@ const char DecodeImage_UnsupportedPixelConfiguration[] = // const char DecodeImage_UnsupportedPixelFormat[] = // "wuffs_aux::DecodeImage: unsupported pixel format"; -DecodeImageArgQuirks::DecodeImageArgQuirks(wuffs_base__slice_u32 repr0) - : repr(repr0) {} - -DecodeImageArgQuirks::DecodeImageArgQuirks(uint32_t* ptr0, size_t len0) - : repr(wuffs_base__make_slice_u32(ptr0, len0)) {} +DecodeImageArgQuirks::DecodeImageArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0) + : ptr(ptr0), len(len0) {} DecodeImageArgQuirks // DecodeImageArgQuirks::DefaultValue() { - return DecodeImageArgQuirks(wuffs_base__empty_slice_u32()); + return DecodeImageArgQuirks(nullptr, 0); } DecodeImageArgFlags::DecodeImageArgFlags(uint64_t repr0) : repr(repr0) {} @@ -78095,7 +78162,8 @@ 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, + const QuirkKeyValuePair* quirks_ptr, + const size_t quirks_len, uint64_t flags, wuffs_base__pixel_blend pixel_blend, wuffs_base__color_u32_argb_premul background_color, @@ -78178,8 +78246,8 @@ DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder, } // Apply quirks. - for (size_t i = 0; i < quirks.len; i++) { - image_decoder->set_quirk(quirks.ptr[i], 1); + for (size_t i = 0; i < quirks_len; i++) { + image_decoder->set_quirk(quirks_ptr[i].first, quirks_ptr[i].second); } // Apply flags. @@ -78406,10 +78474,10 @@ DecodeImage(DecodeImageCallbacks& callbacks, } wuffs_base__image_decoder::unique_ptr image_decoder(nullptr); - DecodeImageResult result = - DecodeImage0(image_decoder, callbacks, input, *io_buf, quirks.repr, - flags.repr, pixel_blend.repr, background_color.repr, - max_incl_dimension.repr, max_incl_metadata_length.repr); + DecodeImageResult result = DecodeImage0( + image_decoder, callbacks, input, *io_buf, quirks.ptr, quirks.len, + flags.repr, pixel_blend.repr, background_color.repr, + max_incl_dimension.repr, max_incl_metadata_length.repr); callbacks.Done(result, input, *io_buf, std::move(image_decoder)); return result; } @@ -78444,15 +78512,13 @@ const char DecodeJson_BadJsonPointer[] = // const char DecodeJson_NoMatch[] = // "wuffs_aux::DecodeJson: no match"; -DecodeJsonArgQuirks::DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0) - : repr(repr0) {} - -DecodeJsonArgQuirks::DecodeJsonArgQuirks(uint32_t* ptr0, size_t len0) - : repr(wuffs_base__make_slice_u32(ptr0, len0)) {} +DecodeJsonArgQuirks::DecodeJsonArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0) + : ptr(ptr0), len(len0) {} DecodeJsonArgQuirks // DecodeJsonArgQuirks::DefaultValue() { - return DecodeJsonArgQuirks(wuffs_base__empty_slice_u32()); + return DecodeJsonArgQuirks(nullptr, 0); } DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0) @@ -78797,11 +78863,11 @@ DecodeJson(DecodeJsonCallbacks& callbacks, goto done; } bool allow_tilde_n_tilde_r_tilde_t = false; - for (size_t i = 0; i < quirks.repr.len; i++) { - dec->set_quirk(quirks.repr.ptr[i], 1); - if (quirks.repr.ptr[i] == + for (size_t i = 0; i < quirks.len; i++) { + dec->set_quirk(quirks.ptr[i].first, quirks.ptr[i].second); + if (quirks.ptr[i].first == WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) { - allow_tilde_n_tilde_r_tilde_t = true; + allow_tilde_n_tilde_r_tilde_t = (quirks.ptr[i].second != 0); } }